diff --git a/maker/golang/cmd/edit.go b/maker/golang/cmd/edit.go index 44c9e2a..a242a69 100644 --- a/maker/golang/cmd/edit.go +++ b/maker/golang/cmd/edit.go @@ -147,7 +147,7 @@ func Edit(sCmd string) { } } else if strings.HasPrefix(cmd, "put ") { seg := strings.TrimSpace(cmd[len("put "):]) - o, n, err := editor.Put(seg) + o, n, err := editor.Put(seg, nil) if err != nil { fmt.Printf("failed to Put(%s): %s\n", seg, err) continue @@ -155,7 +155,7 @@ func Edit(sCmd string) { fmt.Printf("Put(%s): Ok, with %d deletes and %d additions\n", seg, o, n) } else if strings.HasPrefix(cmd, "put_file ") { file := strings.TrimSpace(cmd[len("put_file "):]) - o, n, err := editor.PutFile(file) + o, n, err := editor.PutFile(file, nil) if err != nil { fmt.Printf("failed to PutFile(%s): %s\n", file, err) continue diff --git a/maker/golang/xdb/editor.go b/maker/golang/xdb/editor.go index 2c4f259..ac005c6 100644 --- a/maker/golang/xdb/editor.go +++ b/maker/golang/xdb/editor.go @@ -181,13 +181,13 @@ func (e *Editor) Slice(offset int, size int) []*Segment { return out } -func (e *Editor) Put(ip string) (int, int, error) { +func (e *Editor) Put(ip string, cb func(newSeg *Segment, oldList []*Segment) []*Segment) (int, int, error) { seg, err := SegmentFrom(ip) if err != nil { return 0, 0, err } - return e.PutSegment(seg) + return e.PutSegment(seg, cb) } // PutSegment put the specified segment into the current segment list with @@ -201,7 +201,7 @@ func (e *Editor) Put(ip string) (int, int, error) { // StartIP------seg.StartIP------EndIP------| // // |---------------------seg.EndIP -func (e *Editor) PutSegment(seg *Segment) (int, int, error) { +func (e *Editor) PutSegment(seg *Segment, cb func(newSeg *Segment, oldList []*Segment) []*Segment) (int, int, error) { var next *list.Element var eList []*list.Element var found, counter = false, 0 @@ -252,8 +252,18 @@ func (e *Editor) PutSegment(seg *Segment) (int, int, error) { }) } - // append the new segment - sList = append(sList, seg) + // check the callback and append the new segment + if cb == nil { + sList = append(sList, seg) + } else { + var tsList []*Segment + for _, ele := range eList { + tsList = append(tsList, ele.Value.(*Segment)) + } + + // call the callback and append the segments + sList = append(sList, cb(seg, tsList)...) + } // check and do the tailing segment append var tail = eList[len(eList)-1].Value.(*Segment) @@ -265,6 +275,10 @@ func (e *Editor) PutSegment(seg *Segment) (int, int, error) { }) } + // check and merge the sList + // for all the continuous segments with the same region + sList = MergeSegments(sList) + // print for debug // for i, s := range sList { // fmt.Printf("%d: %s\n", i, s) @@ -295,7 +309,7 @@ func (e *Editor) PutSegment(seg *Segment) (int, int, error) { return oldRows, newRows, nil } -func (e *Editor) PutFile(src string) (int, int, error) { +func (e *Editor) PutFile(src string, cb func(newSeg *Segment, oldList []*Segment) []*Segment) (int, int, error) { handle, err := os.OpenFile(src, os.O_RDONLY, 0600) if err != nil { return 0, 0, err @@ -305,7 +319,7 @@ func (e *Editor) PutFile(src string) (int, int, error) { _, _, iErr := IterateSegments(handle, true, func(l string) { // do nothing here }, nil, func(seg *Segment) error { - o, n, err := e.PutSegment(seg) + o, n, err := e.PutSegment(seg, cb) if err == nil { oldRows += o newRows += n diff --git a/maker/golang/xdb/util.go b/maker/golang/xdb/util.go index 1235ebd..c28359a 100644 --- a/maker/golang/xdb/util.go +++ b/maker/golang/xdb/util.go @@ -254,6 +254,40 @@ func CheckSegments(segList []*Segment) error { return nil } +// check and merge the continuous segments with the same region +func MergeSegments(segList []*Segment) []*Segment { + var err error + var last *Segment = nil + var mergedList []*Segment + for _, seg := range segList { + // check and automatic merging the Consecutive Segments, which means: + // 1, region info is the same + // 2, last.eip+1 = cur.sip + if last == nil { + last = seg + continue + } else if last.Region == seg.Region { + if err = seg.RightBehind(last); err == nil { + last.EndIP = seg.EndIP + continue + } + } + + // append the segment + mergedList = append(mergedList, last) + + // track the last value + last = seg + } + + // process the last segment + if last != nil { + mergedList = append(mergedList, last) + } + + return mergedList +} + func RegionFiltering(region string, fields []int) (string, error) { if len(fields) == 0 { return region, nil