From 7ff7772e14237171269feb51af9832f0a860c640 Mon Sep 17 00:00:00 2001 From: Lion Date: Mon, 5 Dec 2022 14:19:49 +0800 Subject: [PATCH] impl save and put_file --- data/ip.merge.txt | 3 +- maker/golang/main.go | 13 +++-- maker/golang/xdb/editor.go | 99 ++++++++++++++++++++++++------------- maker/golang/xdb/segment.go | 2 +- 4 files changed, 72 insertions(+), 45 deletions(-) diff --git a/data/ip.merge.txt b/data/ip.merge.txt index f92ed62..5df6abd 100644 --- a/data/ip.merge.txt +++ b/data/ip.merge.txt @@ -1,6 +1,5 @@ 0.0.0.0|0.255.255.255|0|0|0|内网IP|内网IP -1.0.0.0|1.0.0.155|澳大利亚|0|0|0|0 -1.0.0.156|1.0.0.255|澳大利亚|0|0|0|0 +1.0.0.0|1.0.0.255|澳大利亚|0|0|0|0 1.0.1.0|1.0.3.255|中国|0|福建省|福州市|电信 1.0.4.0|1.0.7.255|澳大利亚|0|维多利亚|墨尔本|0 1.0.8.0|1.0.15.255|中国|0|广东省|广州市|电信 diff --git a/maker/golang/main.go b/maker/golang/main.go index c4f2651..7ef7cbc 100644 --- a/maker/golang/main.go +++ b/maker/golang/main.go @@ -281,13 +281,11 @@ func testBench() { func edit() { var err error - var srcFile, dstFile = "", "" + var srcFile = "" var fErr = iterateFlags(func(key string, val string) error { switch key { case "src": srcFile = val - case "dst": - dstFile = val default: return fmt.Errorf("undefined option '%s=%s'\n", key, val) } @@ -298,21 +296,22 @@ func edit() { return } - if dstFile == "" || srcFile == "" { + if srcFile == "" { fmt.Printf("%s edit [command options]\n", os.Args[0]) fmt.Printf("options:\n") fmt.Printf(" --src string source ip text file path\n") - fmt.Printf(" --dst string destination source file path\n") return } fmt.Printf("init the editor from source @ `%s` ... \n", srcFile) - editor, err := xdb.NewEditor(srcFile, dstFile) + var tStart = time.Now() + editor, err := xdb.NewEditor(srcFile) if err != nil { fmt.Printf("failed to init editor: %s", err) return } + fmt.Printf("all segments loaded, length: %d, elapsed: %s\n", editor.SegLen(), time.Since(tStart)) var help = func() { fmt.Printf("command list: \n") fmt.Printf(" put [segment] : put the specifield segment\n") @@ -343,7 +342,7 @@ func edit() { fmt.Printf("failed to save the changes: %s", err) continue } - fmt.Printf("Changes saved\n") + fmt.Printf("all segments saved to %s\n", srcFile) } else if strings.HasPrefix(cmd, "put ") { seg := cmd[len("put "):] err = editor.Put(seg) diff --git a/maker/golang/xdb/editor.go b/maker/golang/xdb/editor.go index 84f2d93..5892471 100644 --- a/maker/golang/xdb/editor.go +++ b/maker/golang/xdb/editor.go @@ -11,61 +11,38 @@ import ( "fmt" "os" "path/filepath" - "time" ) type Editor struct { // source ip file + srcPath string srcHandle *os.File - dstHandle *os.File - - // region info - // @Note: 2^32 items at most - region map[uint32]string - rIndex uint32 // segments list segments *list.List } -func NewEditor(srcFile string, dstFile string) (*Editor, error) { +func NewEditor(srcFile string) (*Editor, error) { // check the src and dst file srcPath, err := filepath.Abs(srcFile) if err != nil { return nil, err } - dstPath, err := filepath.Abs(dstFile) - if err != nil { - return nil, err - } - - if srcPath == dstPath { - return nil, fmt.Errorf("src_path(%s) = dst_path(%s)", srcFile, dstFile) - } - srcHandle, err := os.OpenFile(srcPath, os.O_RDONLY, 0600) if err != nil { return nil, err } - dstHandle, err := os.OpenFile(dstPath, os.O_CREATE|os.O_RDWR, 0644) - if err != nil { - return nil, err - } - e := &Editor{ + srcPath: srcPath, srcHandle: srcHandle, - dstHandle: dstHandle, - - region: map[uint32]string{}, - rIndex: uint32(0), - segments: list.New(), + segments: list.New(), } // load the segments if err = e.loadSegments(); err != nil { - return nil, fmt.Errorf("failed load segments: %s", err) + return nil, fmt.Errorf("failed to load segments: %s", err) } return e, nil @@ -74,9 +51,8 @@ func NewEditor(srcFile string, dstFile string) (*Editor, error) { // Load all the segments from the source file func (e *Editor) loadSegments() error { var last *Segment = nil - var tStart = time.Now() - var err = IterateSegments(e.srcHandle, func(l string) { + var iErr = IterateSegments(e.srcHandle, func(l string) { // do nothing here }, func(seg *Segment) error { // check the continuity of the data segment @@ -84,29 +60,82 @@ func (e *Editor) loadSegments() error { return err } + e.segments.PushBack(seg) last = seg return nil }) - if err != nil { - return fmt.Errorf("failed to load segments: %s", err) + if iErr != nil { + return iErr } - fmt.Printf("all segments loaded, length: %d, elapsed: %s\n", e.segments.Len(), time.Since(tStart)) return nil } +func (e *Editor) SegLen() int { + return e.segments.Len() +} + func (e *Editor) Put(ip string) error { + seg, err := SegmentFrom(ip) + if err != nil { + return err + } + + return e.PutSegment(seg) +} + +func (e *Editor) PutSegment(seg *Segment) error { return nil } func (e *Editor) PutFile(src string) error { + handle, err := os.OpenFile(src, os.O_RDONLY, 0600) + if err != nil { + return err + } + + iErr := IterateSegments(handle, func(l string) { + // do nothing here + }, func(seg *Segment) error { + return e.PutSegment(seg) + }) + if iErr != nil { + return iErr + } + + _ = handle.Close() return nil } func (e *Editor) Save() error { + dstHandle, err := os.OpenFile(e.srcPath, os.O_WRONLY|os.O_TRUNC, 0644) + if err != nil { + return err + } + + // loop and flush all the segments to the dstHandle + var next *list.Element + for e := e.segments.Front(); e != nil; e = next { + next = e.Next() + s, ok := e.Value.(*Segment) + if !ok { + // could this even a case ? + continue + } + + var l = s.String() + _, err = dstHandle.WriteString(fmt.Sprintf("%s\n", l)) + if err != nil { + return err + } + } + + // close the handle + _ = dstHandle.Close() + return nil } -func (e *Editor) Close() error { - return nil +func (e *Editor) Close() { + _ = e.srcHandle.Close() } diff --git a/maker/golang/xdb/segment.go b/maker/golang/xdb/segment.go index 0ad95f4..fba39f8 100644 --- a/maker/golang/xdb/segment.go +++ b/maker/golang/xdb/segment.go @@ -107,5 +107,5 @@ func (s *Segment) Split() []*Segment { } func (s *Segment) String() string { - return Long2IP(s.StartIP) + "|" + Long2IP(s.EndIP) + "|" + s.Region + return fmt.Sprintf("%s|%s|%s", Long2IP(s.StartIP), Long2IP(s.EndIP), s.Region) }