Merge pull request #475 from lionsoul2014/opt_golang_editor
editor with put callback and auto segments merge
This commit is contained in:
commit
a603a75ab7
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue