為達到高速的全規則匹配(一條資料要和當前所有規則進行匹配,而不是匹配即跳出),需要乙個二叉判斷樹,二叉判斷樹的輸入要求乙個有序的、互斥的判斷閾值序列。但是,顯示中的業務規則絕大多數都是交叉的,比如企業業務規則,同乙個/組ip可能會和多個/組ip有互動,因此要對其建立多條規則,而且組與組之間的範圍還非常可能是疊加的。因此,需要程式自動的差分判斷範圍,以供判斷樹的生成。
#!/usr/bin/env python
#coding = utf-8
'''author: yang xu
e-mail: [email protected]
'''class _segment(object):
__slots__ = ('value', 'ishead', 'istail')
def __init__(self, value, ishead=false, istail=false):
self.value = value
self.ishead = ishead
self.istail = istail
def __str__(self):
h = 'h' if self.ishead else ''
t = 't' if self.istail else ''
return '<%s%s%s>'%(h, self.value, t)
__repr__ = __str__
class span(object):
__slots__ = ('start', 'end', 'srcs')
def __init__(self, start, end, srcs):
self.start = start
self.end = end
self.srcs = srcs
def __str__(self):
return ''%(self.start, self.end, str(self.srcs))
__repr__ = __str__
def _seglist(sequence):
tmp_set = set()
for span in sequence:
start = span[0]
end = span[1]
tmp_set.add(start)
tmp_set.add(end)
tmp_set = sorted(list(tmp_set))
header = set([span[0] for span in sequence])
tailer = set([span[1] for span in sequence])
seg_list =
for item in tmp_set:
ishead = item in header
istail = item in tailer
segment = _segment(item, ishead, istail)
return seg_list
def _spanlist(seg_list):
span_list =
for seg in seg_list:
# add value-1 before header
if seg.ishead:
if span_list:
# add value
# add value if ishead & istail
if seg.ishead and seg.istail:
# add value+1 after tailer
if seg.istail:
return span_list
def _filter(span_list, sequence,
getstart=lambda item: item[0],
getend=lambda item: item[1],
gettag = lambda item: item
):def belongs(span, sequence):
s = span[0]
t = span[1]
tag_list =
for item in sequence:
_s = getstart(item)
_t = getend(item)
tag = gettag(item)
if _s<=s<=_t and _s<=t<=_t:
return tag_list
taglists = map(lambda span: belongs(span, sequence), span_list)
return_list =
for index in xrange(len(taglists)):
tags = taglists[index]
span = span_list[index]
if tags:
return return_list
def split(sequence,
getstart=lambda item: item[0],
getend=lambda item: item[1],
gettag = lambda item: item
):sequence_list = [(getstart(obj), getend(obj)) for obj in sequence]
seg_list = _seglist(sequence_list)
span_list = _spanlist(seg_list)
starts = span_list[0::2]
ends = span_list[1::2]
return_list =
for index in xrange(len(ends)):
start = starts[index]
end = ends[index]
if start > end: continue
return_list = _filter(
return_list, sequence,
getstart = getstart,
getend = getend,
gettag=gettag
)return return_list
if __name__ == '__main__':
ls = [
[-1, 10],
[3, 7],
[10, 15],
[12, 20],
[22, 22],
[24, 30]
]s = split(ls)
print
for i in s:
print i
class o(object):
def __init__(self, id, s, e):
self.tag = id
self.start = s
self.end = e
def __str__(self):
return '<%s-%s>'%(self.start, self.end)
__repr__ = __str__
seq =
count = 1
for span in ls:
count += 1
seq.sort(cmp = lambda x, y: cmp(x.start, y.start))
s = split(seq,
getstart=lambda item: item.start,
getend=lambda item: item.end,
gettag = lambda item: item#.tag
)print
for i in s:
print i
# result:
# # # # # # # # # #
# ]>
# , <3-7>]>
# ]>
# , <10-15>]>
# ]>
# , <12-20>]>
# ]>
# ]>
# ]>
給定乙個 部分重疊、完全重疊、連續、間斷的序列,上述**會將其拆分為更細的span,然後返回拆分好後的span及其所屬的原始序列。載體為span物件。
同時,輸入序列可以是簡單的二元組,分為表示start和end,也可以是乙個複雜物件,此時需要定義獲取物件屬性對應到start和end的方法getstart和getend。
gettag引數用來決定返回所屬原始序列時的值,預設是輸入時物件本身。
python函式範圍 Python函式範圍
我有乙個關於 python函式範圍的問題.我已經包含了乙個示例,說明了我遇到的問題.fun0重新定義了varible c列表中的第乙個條目.這個變化反映在fun0之外,即使我沒有從fun0返回任何值.fun1完全重新定義變數c,但更改不會在fun1之外反映出來.同樣,fun2重新定義了c,並且更改不...
TCP資料報重組實現分析
參照tcp ip詳解第二卷24 29章,詳細論述了tcp協議的實現,大概總結一下tcp如何向應用層保證資料報的正確性 可靠性,即tcp如何實現對資料報文的重組。首先要設計兩個報文佇列,乙個存放正常來到的報文,乙個存放失序到來的報文。比如正常報文佇列最後乙個報文資料如下 報文資料段第一位元組的序號 資...
TCP資料報重組實現分析
tcp重組資料報分析 參照tcp ip詳解第二卷24 29章,詳細論述了tcp協議的實現,大概總結一下tcp如何向應用層保證資料報的正確性 可靠性,即tcp如何實現對資料報文的重組。首先要設計兩個報文佇列,乙個存放正常來到的報文,乙個存放失序到來的報文。比如正常報文佇列最後乙個報文資料如下 報文資料...