@@ -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+ func readNodePairBySize (buffer []byte ,baseOffset ,recordSize uint ) (left ,right uint ,err error ) {
522+ bufferLen := uint (len (buffer ))
523+ switch recordSize {
524+ case 24 :
525+ // Each child is 3 bytes; total 6 bytes starting at baseOffset
526+ if baseOffset > bufferLen - 6 {
527+ return 0 ,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+ return left ,right ,nil
536+ case 28 :
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+ if baseOffset > bufferLen - 7 {
540+ return 0 ,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+ return left ,right ,nil
556+ case 32 :
557+ // Each child is 4 bytes; total 8 bytes
558+ if baseOffset > bufferLen - 8 {
559+ return 0 ,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+ return left ,right ,nil
574+ default :
575+ return 0 ,0 ,mmdberrors .NewInvalidDatabaseError ("unsupported record size" )
576+ }
577+ }
578+
518579func (r * Reader )traverseTree (ip netip.Addr ,node uint ,stopBit int ) (uint ,int ,error ) {
519580switch r .Metadata .RecordSize {
520581case 24 :