@@ -352,9 +352,36 @@ func (d *Decoder) PeekKind() (Kind, error) {
352352}
353353
354354// Offset returns the current offset position in the database.
355- // This can be used by custom unmarshalers for caching purposes.
355+ // If the current position points to a pointer, this method resolves the
356+ // pointer chain and returns the offset of the actual data. This ensures
357+ // that multiple pointers to the same data return the same offset, which
358+ // is important for caching purposes.
356359func (d * Decoder )Offset ()uint {
357- return d .offset
360+ // Follow pointer chain to get resolved data location
361+ dataOffset := d .offset
362+ for {
363+ kindNum ,size ,ctrlEndOffset ,err := d .d .decodeCtrlData (dataOffset )
364+ if err != nil {
365+ // Return original offset to avoid breaking the public API.
366+ // Offset() returns uint (not (uint, error)), so we can't propagate errors.
367+ // In practice, errors here are rare and the original offset is still valid.
368+ return d .offset
369+ }
370+ if kindNum != KindPointer {
371+ // dataOffset is now pointing at the actual data (not a pointer)
372+ // Return this offset, which is where the data's control bytes start
373+ break
374+ }
375+ // Follow the pointer to get the target offset
376+ dataOffset ,_ ,err = d .d .decodePointer (size ,ctrlEndOffset )
377+ if err != nil {
378+ // Return original offset to avoid breaking the public API.
379+ // The caller will encounter the same error when they try to read.
380+ return d .offset
381+ }
382+ // dataOffset is now the pointer target; loop to check if it's also a pointer
383+ }
384+ return dataOffset
358385}
359386
360387func (d * Decoder )reset (offset uint ) {