impl save and put_file

This commit is contained in:
Lion 2022-12-05 14:19:49 +08:00
parent 0dcea0f995
commit 7ff7772e14
4 changed files with 72 additions and 45 deletions

View File

@ -1,6 +1,5 @@
0.0.0.0|0.255.255.255|0|0|0|内网IP|内网IP 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.0|1.0.0.255|澳大利亚|0|0|0|0
1.0.0.156|1.0.0.255|澳大利亚|0|0|0|0
1.0.1.0|1.0.3.255|中国|0|福建省|福州市|电信 1.0.1.0|1.0.3.255|中国|0|福建省|福州市|电信
1.0.4.0|1.0.7.255|澳大利亚|0|维多利亚|墨尔本|0 1.0.4.0|1.0.7.255|澳大利亚|0|维多利亚|墨尔本|0
1.0.8.0|1.0.15.255|中国|0|广东省|广州市|电信 1.0.8.0|1.0.15.255|中国|0|广东省|广州市|电信

View File

@ -281,13 +281,11 @@ func testBench() {
func edit() { func edit() {
var err error var err error
var srcFile, dstFile = "", "" var srcFile = ""
var fErr = iterateFlags(func(key string, val string) error { var fErr = iterateFlags(func(key string, val string) error {
switch key { switch key {
case "src": case "src":
srcFile = val srcFile = val
case "dst":
dstFile = val
default: default:
return fmt.Errorf("undefined option '%s=%s'\n", key, val) return fmt.Errorf("undefined option '%s=%s'\n", key, val)
} }
@ -298,21 +296,22 @@ func edit() {
return return
} }
if dstFile == "" || srcFile == "" { if srcFile == "" {
fmt.Printf("%s edit [command options]\n", os.Args[0]) fmt.Printf("%s edit [command options]\n", os.Args[0])
fmt.Printf("options:\n") fmt.Printf("options:\n")
fmt.Printf(" --src string source ip text file path\n") fmt.Printf(" --src string source ip text file path\n")
fmt.Printf(" --dst string destination source file path\n")
return return
} }
fmt.Printf("init the editor from source @ `%s` ... \n", srcFile) 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 { if err != nil {
fmt.Printf("failed to init editor: %s", err) fmt.Printf("failed to init editor: %s", err)
return return
} }
fmt.Printf("all segments loaded, length: %d, elapsed: %s\n", editor.SegLen(), time.Since(tStart))
var help = func() { var help = func() {
fmt.Printf("command list: \n") fmt.Printf("command list: \n")
fmt.Printf(" put [segment] : put the specifield segment\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) fmt.Printf("failed to save the changes: %s", err)
continue continue
} }
fmt.Printf("Changes saved\n") fmt.Printf("all segments saved to %s\n", srcFile)
} else if strings.HasPrefix(cmd, "put ") { } else if strings.HasPrefix(cmd, "put ") {
seg := cmd[len("put "):] seg := cmd[len("put "):]
err = editor.Put(seg) err = editor.Put(seg)

View File

@ -11,61 +11,38 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"time"
) )
type Editor struct { type Editor struct {
// source ip file // source ip file
srcPath string
srcHandle *os.File srcHandle *os.File
dstHandle *os.File
// region info
// @Note: 2^32 items at most
region map[uint32]string
rIndex uint32
// segments list // segments list
segments *list.List segments *list.List
} }
func NewEditor(srcFile string, dstFile string) (*Editor, error) { func NewEditor(srcFile string) (*Editor, error) {
// check the src and dst file // check the src and dst file
srcPath, err := filepath.Abs(srcFile) srcPath, err := filepath.Abs(srcFile)
if err != nil { if err != nil {
return nil, err 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) srcHandle, err := os.OpenFile(srcPath, os.O_RDONLY, 0600)
if err != nil { if err != nil {
return nil, err return nil, err
} }
dstHandle, err := os.OpenFile(dstPath, os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
return nil, err
}
e := &Editor{ e := &Editor{
srcPath: srcPath,
srcHandle: srcHandle, srcHandle: srcHandle,
dstHandle: dstHandle,
region: map[uint32]string{},
rIndex: uint32(0),
segments: list.New(), segments: list.New(),
} }
// load the segments // load the segments
if err = e.loadSegments(); err != nil { 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 return e, nil
@ -74,9 +51,8 @@ func NewEditor(srcFile string, dstFile string) (*Editor, error) {
// Load all the segments from the source file // Load all the segments from the source file
func (e *Editor) loadSegments() error { func (e *Editor) loadSegments() error {
var last *Segment = nil 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 // do nothing here
}, func(seg *Segment) error { }, func(seg *Segment) error {
// check the continuity of the data segment // check the continuity of the data segment
@ -84,29 +60,82 @@ func (e *Editor) loadSegments() error {
return err return err
} }
e.segments.PushBack(seg)
last = seg last = seg
return nil return nil
}) })
if err != nil { if iErr != nil {
return fmt.Errorf("failed to load segments: %s", err) return iErr
} }
fmt.Printf("all segments loaded, length: %d, elapsed: %s\n", e.segments.Len(), time.Since(tStart))
return nil return nil
} }
func (e *Editor) SegLen() int {
return e.segments.Len()
}
func (e *Editor) Put(ip string) error { 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 return nil
} }
func (e *Editor) PutFile(src string) error { 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 return nil
} }
func (e *Editor) Save() error { 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 return nil
} }
func (e *Editor) Close() error { func (e *Editor) Close() {
return nil _ = e.srcHandle.Close()
} }

View File

@ -107,5 +107,5 @@ func (s *Segment) Split() []*Segment {
} }
func (s *Segment) String() string { 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)
} }