aboutsummaryrefslogtreecommitdiff
path: root/format/commitgraph/layer_lookup.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-06 10:57:15 +0800
committerGravatar Runxi Yu2026-03-06 10:57:15 +0800
commitbd9ca0ee6f4645d31335d63d35d3b495afa32cc5 (patch)
tree5462b7dc5f218e373b47091f4aba488b697a38e9 /format/commitgraph/layer_lookup.go
parentconfig: Split files (diff)
signatureNo signature
format/commitgraph: Split layer files
Diffstat (limited to 'format/commitgraph/layer_lookup.go')
-rw-r--r--format/commitgraph/layer_lookup.go53
1 files changed, 53 insertions, 0 deletions
diff --git a/format/commitgraph/layer_lookup.go b/format/commitgraph/layer_lookup.go
new file mode 100644
index 00000000..3ae4ff53
--- /dev/null
+++ b/format/commitgraph/layer_lookup.go
@@ -0,0 +1,53 @@
+package commitgraph
+
+import (
+ "bytes"
+ "encoding/binary"
+
+ "codeberg.org/lindenii/furgit/internal/intconv"
+ "codeberg.org/lindenii/furgit/objectid"
+)
+
+func layerLookup(layer *layer, oid objectid.ObjectID) (uint32, bool) {
+ hashSize := oid.Size()
+ first := int(oid.RawBytes()[0])
+
+ var lo uint32
+ if first > 0 {
+ lo = binary.BigEndian.Uint32(layer.chunkOIDFanout[(first-1)*4 : first*4])
+ }
+
+ hi := binary.BigEndian.Uint32(layer.chunkOIDFanout[first*4 : (first+1)*4])
+ if hi == 0 || lo >= hi {
+ return 0, false
+ }
+
+ target := oid.RawBytes()
+ left := int(lo)
+
+ right := int(hi) - 1
+ for left <= right {
+ mid := left + (right-left)/2
+ start := mid * hashSize
+ end := start + hashSize
+
+ current := layer.chunkOIDLookup[start:end]
+
+ cmp := bytes.Compare(current, target)
+ switch {
+ case cmp == 0:
+ pos, err := intconv.IntToUint32(mid)
+ if err != nil {
+ return 0, false
+ }
+
+ return pos, true
+ case cmp < 0:
+ left = mid + 1
+ default:
+ right = mid - 1
+ }
+ }
+
+ return 0, false
+}