Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4a9f0b0

Browse files
committed
perf: dual-child read + traversal tweaks
1 parentff83ea4 commit4a9f0b0

File tree

2 files changed

+67
-11
lines changed

2 files changed

+67
-11
lines changed

‎reader.go‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,67 @@ func readNodeBySize(buffer []byte, offset, bit, recordSize uint) (uint, error) {
515515
}
516516
}
517517

518+
// readNodePairBySize reads both left (bit=0) and right (bit=1) child pointers
519+
// for a node at the given base offset according to the record size. This reduces
520+
// duplicate bound checks and byte fetches when both children are needed.
521+
funcreadNodePairBySize(buffer []byte,baseOffset,recordSizeuint) (left,rightuint,errerror) {
522+
bufferLen:=uint(len(buffer))
523+
switchrecordSize {
524+
case24:
525+
// Each child is 3 bytes; total 6 bytes starting at baseOffset
526+
ifbaseOffset>bufferLen-6 {
527+
return0,0,mmdberrors.NewInvalidDatabaseError(
528+
"bounds check failed: insufficient buffer for 24-bit node pair read",
529+
)
530+
}
531+
o:=baseOffset
532+
left= (uint(buffer[o])<<16)| (uint(buffer[o+1])<<8)|uint(buffer[o+2])
533+
o+=3
534+
right= (uint(buffer[o])<<16)| (uint(buffer[o+1])<<8)|uint(buffer[o+2])
535+
returnleft,right,nil
536+
case28:
537+
// Left uses high nibble of shared byte, right uses low nibble.
538+
// Layout: [A B C S][D E F] where S provides 4 shared bits for each child
539+
ifbaseOffset>bufferLen-7 {
540+
return0,0,mmdberrors.NewInvalidDatabaseError(
541+
"bounds check failed: insufficient buffer for 28-bit node pair read",
542+
)
543+
}
544+
// Left child (bit=0): uses high nibble of shared byte
545+
shared:=uint(buffer[baseOffset+3])
546+
left= ((shared&0xF0)<<20)|
547+
(uint(buffer[baseOffset])<<16)|
548+
(uint(buffer[baseOffset+1])<<8)|
549+
uint(buffer[baseOffset+2])
550+
// Right child (bit=1): uses low nibble of shared byte, next 3 bytes
551+
right= ((shared&0x0F)<<24)|
552+
(uint(buffer[baseOffset+4])<<16)|
553+
(uint(buffer[baseOffset+5])<<8)|
554+
uint(buffer[baseOffset+6])
555+
returnleft,right,nil
556+
case32:
557+
// Each child is 4 bytes; total 8 bytes
558+
ifbaseOffset>bufferLen-8 {
559+
return0,0,mmdberrors.NewInvalidDatabaseError(
560+
"bounds check failed: insufficient buffer for 32-bit node pair read",
561+
)
562+
}
563+
o:=baseOffset
564+
left= (uint(buffer[o])<<24)|
565+
(uint(buffer[o+1])<<16)|
566+
(uint(buffer[o+2])<<8)|
567+
uint(buffer[o+3])
568+
o+=4
569+
right= (uint(buffer[o])<<24)|
570+
(uint(buffer[o+1])<<16)|
571+
(uint(buffer[o+2])<<8)|
572+
uint(buffer[o+3])
573+
returnleft,right,nil
574+
default:
575+
return0,0,mmdberrors.NewInvalidDatabaseError("unsupported record size")
576+
}
577+
}
578+
518579
func (r*Reader)traverseTree(ip netip.Addr,nodeuint,stopBitint) (uint,int,error) {
519580
switchr.Metadata.RecordSize {
520581
case24:

‎traverse.go‎

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,12 @@ func (r *Reader) NetworksWithin(prefix netip.Prefix, options ...NetworksOption)
223223
}
224224
ipRight[node.bit>>3]|=1<< (7- (node.bit%8))
225225

226-
offset:=node.pointer*r.nodeOffsetMult
227-
rightPointer,err:=readNodeBySize(r.buffer,offset,1,r.Metadata.RecordSize)
226+
baseOffset:=node.pointer*r.nodeOffsetMult
227+
leftPointer,rightPointer,err:=readNodePairBySize(
228+
r.buffer,
229+
baseOffset,
230+
r.Metadata.RecordSize,
231+
)
228232
iferr!=nil {
229233
yield(Result{
230234
ip:mappedIP(node.ip),
@@ -241,15 +245,6 @@ func (r *Reader) NetworksWithin(prefix netip.Prefix, options ...NetworksOption)
241245
bit:node.bit,
242246
})
243247

244-
leftPointer,err:=readNodeBySize(r.buffer,offset,0,r.Metadata.RecordSize)
245-
iferr!=nil {
246-
yield(Result{
247-
ip:mappedIP(node.ip),
248-
prefixLen:uint8(node.bit),
249-
err:err,
250-
})
251-
return
252-
}
253248
node.pointer=leftPointer
254249
}
255250
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp