Thread-safe impl for CacheRegion

This commit is contained in:
lionsoul2014 2026-04-29 13:44:14 +08:00
parent 90e827633a
commit 5b10989ac2
4 changed files with 27 additions and 18 deletions

View File

@ -108,7 +108,7 @@ func (e *Editor) loadSegments() error {
e.segments.PushBack(&Segment{ e.segments.PushBack(&Segment{
StartIP: e.verison.Min, StartIP: e.verison.Min,
EndIP: IPSubOne(seg.StartIP), EndIP: IPSubOne(seg.StartIP),
Region: REmpty(), Region: EmptyRegion,
}) })
} }
} else if err := seg.RightBehind(last); err == nil { } else if err := seg.RightBehind(last); err == nil {
@ -121,7 +121,7 @@ func (e *Editor) loadSegments() error {
e.segments.PushBack(&Segment{ e.segments.PushBack(&Segment{
StartIP: IPAddOne(last.EndIP), StartIP: IPAddOne(last.EndIP),
EndIP: IPSubOne(seg.StartIP), EndIP: IPSubOne(seg.StartIP),
Region: REmpty(), Region: EmptyRegion,
}) })
} }
@ -138,7 +138,7 @@ func (e *Editor) loadSegments() error {
e.segments.PushBack(&Segment{ e.segments.PushBack(&Segment{
StartIP: IPAddOne(back.Value.(*Segment).EndIP), StartIP: IPAddOne(back.Value.(*Segment).EndIP),
EndIP: e.verison.Max, EndIP: e.verison.Max,
Region: REmpty(), Region: EmptyRegion,
}) })
} }
} }

View File

@ -3,31 +3,32 @@ package xdb
import ( import (
"fmt" "fmt"
"strings" "strings"
"sync"
) )
// region manager with: // region manager with:
// 1, content cache. // 1, content cache.
// 2, util functions // 2, util functions
// global cache map
var rcLock sync.Mutex
var regionCache = map[string]*Region{}
type Region struct { type Region struct {
Str string // region string Str string // region string
fields []string // region fields fields []string // region fields
} }
// global cache map var EmptyRegion = CacheRegion("")
var regionCache = map[string]*Region{}
func RNew(str string) *Region { // Create or get the region from the global cache.
return NewRegion(str) // And it is a thread-safe implementation.
} func CacheRegion(str string) *Region {
func REmpty() *Region {
return NewRegion("")
}
func NewRegion(str string) *Region {
// check the cache and return it directly // check the cache and return it directly
// if there is a cache available // if there is a cache available
rcLock.Lock()
defer rcLock.Unlock()
region, ok := regionCache[str] region, ok := regionCache[str]
if ok { if ok {
return region return region
@ -43,6 +44,14 @@ func NewRegion(str string) *Region {
return region return region
} }
// Create a new region without checking cache info
func NewRegion(str string) *Region {
return &Region{
Str: str,
fields: nil,
}
}
func (r *Region) Fields() []string { func (r *Region) Fields() []string {
if r.fields == nil { if r.fields == nil {
r.fields = strings.Split(r.Str, "|") r.fields = strings.Split(r.Str, "|")
@ -51,7 +60,7 @@ func (r *Region) Fields() []string {
return r.fields return r.fields
} }
func (r *Region) JoinBy(sep string) string { func (r *Region) Join(sep string) string {
if sep == "|" { if sep == "|" {
return r.Str return r.Str
} }
@ -78,7 +87,7 @@ func (r *Region) Filtering(fields []int) (*Region, error) {
sb = append(sb, fs[idx]) sb = append(sb, fs[idx])
} }
new := RNew(strings.Join(sb, "|")) new := CacheRegion(strings.Join(sb, "|"))
if new.fields == nil { if new.fields == nil {
new.fields = sb new.fields = sb
} }

View File

@ -38,7 +38,7 @@ func SegmentFrom(seg string) (*Segment, error) {
return &Segment{ return &Segment{
StartIP: sip, StartIP: sip,
EndIP: eip, EndIP: eip,
Region: RNew(ps[2]), Region: CacheRegion(ps[2]),
}, nil }, nil
} }

View File

@ -200,7 +200,7 @@ func IterateSegments(handle *os.File, autoMerge bool, before func(l string), fil
var seg = &Segment{ var seg = &Segment{
StartIP: sip, StartIP: sip,
EndIP: eip, EndIP: eip,
Region: RNew(region), Region: CacheRegion(region),
} }
// check and automatic merging the Consecutive Segments, which means: // check and automatic merging the Consecutive Segments, which means: