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
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|广东省|广州市|电信

View File

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

View File

@ -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(),
}
// 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()
}

View File

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