aboutsummaryrefslogtreecommitdiff
path: root/delta_write_select.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-01-29 17:41:23 +0100
committerGravatar Runxi Yu2026-01-29 17:43:52 +0100
commit17c9aee0e781026353ead4ac749a3ae89c83d007 (patch)
treefc681ebc99fdcd21339265a7e0fcfd4fe7a17d67 /delta_write_select.go
parentREADME: Various updates (diff)
signatureNo signature
packed: Write packs with deltas
Diffstat (limited to 'delta_write_select.go')
-rw-r--r--delta_write_select.go56
1 files changed, 56 insertions, 0 deletions
diff --git a/delta_write_select.go b/delta_write_select.go
new file mode 100644
index 00000000..ad8e0d0e
--- /dev/null
+++ b/delta_write_select.go
@@ -0,0 +1,56 @@
+package furgit
+
+const defaultDeltaWindow = 64
+
+type objectToPack struct {
+ id Hash
+ ty ObjectType
+ body []byte
+ offset uint64
+ deltaDepth int
+}
+
+type deltaContext struct {
+ window int
+ candidates []*objectToPack
+}
+
+func (ctx *deltaContext) addCandidate(obj *objectToPack) {
+ if ctx.window <= 0 {
+ return
+ }
+ ctx.candidates = append(ctx.candidates, obj)
+ if len(ctx.candidates) > ctx.window {
+ over := len(ctx.candidates) - ctx.window
+ ctx.candidates = ctx.candidates[over:]
+ }
+}
+
+func pickDeltaBase(ctx *deltaContext, obj *objectToPack, seed uint32, minSavings, maxDepth int) (*objectToPack, []byte) {
+ if ctx == nil || len(ctx.candidates) == 0 {
+ return nil, nil
+ }
+ if maxDepth <= 0 {
+ maxDepth = 1
+ }
+ var bestBase *objectToPack
+ var bestDelta []byte
+ for i := len(ctx.candidates) - 1; i >= 0; i-- {
+ base := ctx.candidates[i]
+ if base.ty != ObjectTypeBlob {
+ continue
+ }
+ if base.deltaDepth >= maxDepth {
+ continue
+ }
+ delta, ok := deltaTry(base.body, obj.body, seed, minSavings)
+ if !ok {
+ continue
+ }
+ if bestDelta == nil || len(delta) < len(bestDelta) {
+ bestDelta = delta
+ bestBase = base
+ }
+ }
+ return bestBase, bestDelta
+}