diff --git a/go/cmd/dolt/commands/admin/archive_inspect.go b/go/cmd/dolt/commands/admin/archive_inspect.go index 3c08a57c36..77f2796348 100644 --- a/go/cmd/dolt/commands/admin/archive_inspect.go +++ b/go/cmd/dolt/commands/admin/archive_inspect.go @@ -255,6 +255,28 @@ func (cmd ArchiveInspectCmd) Exec(ctx context.Context, commandStr string, args [ cli.Printf("Raw suffix bytes: %x\n", rawBytes) } } + + // Show mmap specific details if available + if mmapIndexSize, ok := details["mmapIndexSize"]; ok { + cli.Println() + cli.Println("Memory-mapped reader details:") + cli.Printf("Mmap index size: %d\n", mmapIndexSize) + cli.Printf("Mmap byte span count: %d\n", details["mmapByteSpanCount"]) + cli.Printf("Mmap chunk count: %d\n", details["mmapChunkCount"]) + cli.Printf("Span index offset: %d\n", details["spanIndexOffset"]) + cli.Printf("Prefixes offset: %d\n", details["prefixesOffset"]) + cli.Printf("Chunk refs offset: %d\n", details["chunkRefsOffset"]) + cli.Printf("Suffixes offset: %d\n", details["suffixesOffset"]) + cli.Printf("Expected suffix start: %d\n", details["expectedSuffixStart"]) + cli.Printf("Expected suffix end: %d\n", details["expectedSuffixEnd"]) + cli.Printf("Actual suffix offset: %d\n", details["actualSuffixOffset"]) + if rawBytes, ok := details["rawSuffixBytes"]; ok { + cli.Printf("Raw suffix bytes: %x\n", rawBytes) + } + if err, ok := details["rawSuffixBytesError"]; ok { + cli.Printf("Raw suffix bytes error: %s\n", err) + } + } } return 0 diff --git a/go/store/nbs/archive_inspect.go b/go/store/nbs/archive_inspect.go index 71021974d1..ac0c30ab33 100644 --- a/go/store/nbs/archive_inspect.go +++ b/go/store/nbs/archive_inspect.go @@ -213,6 +213,43 @@ func (ai *ArchiveInspector) GetIndexReaderDetails(idx uint32) map[string]interfa } } + // For mmap reader, expose similar details using reflection-like approach + if mmap, ok := ai.reader.indexReader.(interface { + getNumChunks() uint32 + // Add methods to access internal fields for debugging + }); ok { + // Try to access internal fields by type assertion to the concrete type + if mmapReader, isMmap := ai.reader.indexReader.(*mmapIndexReader); isMmap { + details["mmapIndexSize"] = mmapReader.indexSize + details["mmapByteSpanCount"] = mmapReader.byteSpanCount + details["mmapChunkCount"] = mmapReader.chunkCount + details["spanIndexOffset"] = mmapReader.spanIndexOffset + details["prefixesOffset"] = mmapReader.prefixesOffset + details["chunkRefsOffset"] = mmapReader.chunkRefsOffset + details["suffixesOffset"] = mmapReader.suffixesOffset + + // Calculate expected suffix position in mmap + expectedSuffixStart := int64(idx) * hash.SuffixLen + actualSuffixOffset := mmapReader.suffixesOffset + expectedSuffixStart + details["expectedSuffixStart"] = expectedSuffixStart + details["expectedSuffixEnd"] = expectedSuffixStart + hash.SuffixLen + details["actualSuffixOffset"] = actualSuffixOffset + + // Try to read raw bytes around the suffix position + if mmapReader.data != nil { + rawBytes := make([]byte, hash.SuffixLen) + _, err := mmapReader.data.ReadAt(rawBytes, actualSuffixOffset) + if err == nil { + details["rawSuffixBytes"] = rawBytes + } else { + details["rawSuffixBytesError"] = err.Error() + } + } + } else { + details["chunkCount"] = mmap.getNumChunks() + } + } + return details }