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 ") {
|
} else if strings.HasPrefix(cmd, "put ") {
|
||||||
seg := strings.TrimSpace(cmd[len("put "):])
|
seg := strings.TrimSpace(cmd[len("put "):])
|
||||||
o, n, err := editor.Put(seg)
|
o, n, err := editor.Put(seg, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to Put(%s): %s\n", seg, err)
|
fmt.Printf("failed to Put(%s): %s\n", seg, err)
|
||||||
continue
|
continue
|
||||||
|
|
@ -155,7 +155,7 @@ func Edit(sCmd string) {
|
||||||
fmt.Printf("Put(%s): Ok, with %d deletes and %d additions\n", seg, o, n)
|
fmt.Printf("Put(%s): Ok, with %d deletes and %d additions\n", seg, o, n)
|
||||||
} else if strings.HasPrefix(cmd, "put_file ") {
|
} else if strings.HasPrefix(cmd, "put_file ") {
|
||||||
file := strings.TrimSpace(cmd[len("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 {
|
if err != nil {
|
||||||
fmt.Printf("failed to PutFile(%s): %s\n", file, err)
|
fmt.Printf("failed to PutFile(%s): %s\n", file, err)
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -181,13 +181,13 @@ func (e *Editor) Slice(offset int, size int) []*Segment {
|
||||||
return out
|
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)
|
seg, err := SegmentFrom(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.PutSegment(seg)
|
return e.PutSegment(seg, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutSegment put the specified segment into the current segment list with
|
// 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------|
|
// StartIP------seg.StartIP------EndIP------|
|
||||||
//
|
//
|
||||||
// |---------------------seg.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 next *list.Element
|
||||||
var eList []*list.Element
|
var eList []*list.Element
|
||||||
var found, counter = false, 0
|
var found, counter = false, 0
|
||||||
|
|
@ -252,8 +252,18 @@ func (e *Editor) PutSegment(seg *Segment) (int, int, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// append the new segment
|
// check the callback and append the new segment
|
||||||
|
if cb == nil {
|
||||||
sList = append(sList, seg)
|
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
|
// check and do the tailing segment append
|
||||||
var tail = eList[len(eList)-1].Value.(*Segment)
|
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
|
// print for debug
|
||||||
// for i, s := range sList {
|
// for i, s := range sList {
|
||||||
// fmt.Printf("%d: %s\n", i, s)
|
// fmt.Printf("%d: %s\n", i, s)
|
||||||
|
|
@ -295,7 +309,7 @@ func (e *Editor) PutSegment(seg *Segment) (int, int, error) {
|
||||||
return oldRows, newRows, nil
|
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)
|
handle, err := os.OpenFile(src, os.O_RDONLY, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, err
|
||||||
|
|
@ -305,7 +319,7 @@ func (e *Editor) PutFile(src string) (int, int, error) {
|
||||||
_, _, iErr := IterateSegments(handle, true, func(l string) {
|
_, _, iErr := IterateSegments(handle, true, func(l string) {
|
||||||
// do nothing here
|
// do nothing here
|
||||||
}, nil, func(seg *Segment) error {
|
}, nil, func(seg *Segment) error {
|
||||||
o, n, err := e.PutSegment(seg)
|
o, n, err := e.PutSegment(seg, cb)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
oldRows += o
|
oldRows += o
|
||||||
newRows += n
|
newRows += n
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,40 @@ func CheckSegments(segList []*Segment) error {
|
||||||
return nil
|
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) {
|
func RegionFiltering(region string, fields []int) (string, error) {
|
||||||
if len(fields) == 0 {
|
if len(fields) == 0 {
|
||||||
return region, nil
|
return region, nil
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue