Merge pull request #475 from lionsoul2014/opt_golang_editor

editor with put callback and auto segments merge
This commit is contained in:
Leon / 狮子的魂 2026-04-22 16:29:55 +08:00 committed by GitHub
commit a603a75ab7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 57 additions and 9 deletions

View File

@ -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

View File

@ -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

View File

@ -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