120 lines
2.3 KiB
Go
120 lines
2.3 KiB
Go
// Copyright 2022 The Ip2Region Authors. All rights reserved.
|
|
// Use of this source code is governed by a Apache2.0-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// original source ip editor
|
|
|
|
package xdb
|
|
|
|
import (
|
|
"container/list"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
)
|
|
|
|
type Editor struct {
|
|
// source ip 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.List
|
|
}
|
|
|
|
func NewEditor(srcFile string, dstFile 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{
|
|
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 e, nil
|
|
}
|
|
|
|
// 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, nil, func(sip uint32, eip uint32, region *string) error {
|
|
var str = *region
|
|
var seg = &Segment{
|
|
StartIP: sip,
|
|
EndIP: eip,
|
|
Region: str,
|
|
}
|
|
|
|
// check the continuity of the data segment
|
|
if last != nil {
|
|
if last.EndIP+1 != seg.StartIP {
|
|
return fmt.Errorf("discontinuous data segment: last.eip+1(%d) != seg.sip(%d, %s)", sip, eip, str)
|
|
}
|
|
}
|
|
|
|
last = seg
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to load segments: %s", err)
|
|
}
|
|
|
|
fmt.Printf("all segments loaded, length: %d, elapsed: %s\n", e.segments.Len(), time.Since(tStart))
|
|
return nil
|
|
}
|
|
|
|
func (e *Editor) Put(ip string) error {
|
|
return nil
|
|
}
|
|
|
|
func (e *Editor) PutFile(src string) error {
|
|
return nil
|
|
}
|
|
|
|
func (e *Editor) Save() error {
|
|
return nil
|
|
}
|
|
|
|
func (e *Editor) Close() error {
|
|
return nil
|
|
}
|