aboutsummaryrefslogtreecommitdiff
path: root/format/commitgraph/read/layer_lookup.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-06 11:54:21 +0800
committerGravatar Runxi Yu2026-03-06 11:55:56 +0800
commitc62c5544fa23378843a3383a9dcd4494e5ea33bc (patch)
tree8b825a36767fe0ba3fb44f27cb634047c4c0318f /format/commitgraph/read/layer_lookup.go
parentformat/pack/ingest: Fix delta apply import (diff)
signatureNo signature
format/commitgraph: Split into ./read and ./ v0.1.60
Diffstat (limited to 'format/commitgraph/read/layer_lookup.go')
-rw-r--r--format/commitgraph/read/layer_lookup.go53
1 files changed, 53 insertions, 0 deletions
diff --git a/format/commitgraph/read/layer_lookup.go b/format/commitgraph/read/layer_lookup.go
new file mode 100644
index 00000000..9a03505a
--- /dev/null
+++ b/format/commitgraph/read/layer_lookup.go
@@ -0,0 +1,53 @@
+package read
+
+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
+}