ref: ac400226b0b622aae21b09cb6c83f07924647d0d
parent: 5ee77b00a0c00d2ef5c796260a34bbd6e8ac39a8
author: Runxi Yu <me@runxiyu.org>
date: Thu Jan 29 16:01:40 EST 2026
delta, packed: Use xxhash instead of murmurhash2
--- a/delta_write_deltify.go
+++ b/delta_write_deltify.go
@@ -3,7 +3,7 @@
import (
"bytes"
- "codeberg.org/lindenii/furgit/internal/murmurhash2"
+ "github.com/cespare/xxhash/v2"
)
const (
@@ -62,7 +62,7 @@
type deltaBlock struct {length int
offset int
- hash uint32
+ hash uint64
}
type deltaTable struct {@@ -82,7 +82,7 @@
data []byte
}
-func deltify(base, target []byte, seed uint32) ([]deltaInstruction, error) {+func deltify(base, target []byte, seed uint64) ([]deltaInstruction, error) { if base == nil { base = []byte{}}
@@ -96,7 +96,7 @@
return deltifyMemMem(target, 0, len(target), seed, dt, base, 0, len(base))
}
-func deltifyMemMem(target []byte, fileoffset, filesize int, seed uint32, dt *deltaTable, base []byte, baseOffset0, baseSize int) ([]deltaInstruction, error) {+func deltifyMemMem(target []byte, fileoffset, filesize int, seed uint64, dt *deltaTable, base []byte, baseOffset0, baseSize int) ([]deltaInstruction, error) {const allocChunkSize = 64
instr := make([]deltaInstruction, 0, allocChunkSize)
offset0 := fileoffset
@@ -141,7 +141,7 @@
return instr, nil
}
-func deltaTableInitMem(data []byte, fileoffset, filesize int, seed uint32) (*deltaTable, error) {+func deltaTableInitMem(data []byte, fileoffset, filesize int, seed uint64) (*deltaTable, error) { dt := &deltaTable{nalloc: 128,
size: 128,
@@ -164,8 +164,13 @@
return dt, nil
}
-func deltaHashBlock(p []byte, seed uint32) uint32 {- return murmurhash2.Sum32(p, seed)
+func deltaHashBlock(p []byte, seed uint64) uint64 {+ if seed == 0 {+ return xxhash.Sum64(p)
+ }
+ d := xxhash.NewWithSeed(seed)
+ _, _ = d.Write(p)
+ return d.Sum64()
}
func deltaNextBlockLen(data []byte, fileoffset, filesize int) int {@@ -188,7 +193,7 @@
return p - fileoffset
}
-func (dt *deltaTable) addBlock(data []byte, offset0, length, offset int, h uint32) error {+func (dt *deltaTable) addBlock(data []byte, offset0, length, offset int, h uint64) error { if length == 0 {return nil
}
@@ -200,22 +205,22 @@
return nil
}
dt.offs[idx] = uint32(dt.nblocks + 1)
- dt.blocks[dt.nblocks] = deltaBlock{- length: length,
- offset: offset,
- hash: h,
- }
+ dt.blocks[dt.nblocks] = deltaBlock{+ length: length,
+ offset: offset,
+ hash: h,
+ }
dt.nblocks++
dt.len++
return nil
}
-func (dt *deltaTable) lookupBlock(chunk []byte, length int, seed uint32, base []byte, baseOffset0 int) *deltaBlock {+func (dt *deltaTable) lookupBlock(chunk []byte, length int, seed uint64, base []byte, baseOffset0 int) *deltaBlock { if dt == nil || dt.size == 0 {return nil
}
h := deltaHashBlock(chunk, seed)
- for i := int(h % uint32(dt.size)); dt.offs[i] != 0; i = (i + 1) % dt.size {+ for i := int(h % uint64(dt.size)); dt.offs[i] != 0; i = (i + 1) % dt.size {block := &dt.blocks[dt.offs[i]-1]
if block.hash != h || block.length != length {continue
@@ -231,11 +236,11 @@
return nil
}
-func (dt *deltaTable) lookupSlot(data []byte, offset0, offset, length int, h uint32) (int, bool) {+func (dt *deltaTable) lookupSlot(data []byte, offset0, offset, length int, h uint64) (int, bool) { if dt == nil || dt.size == 0 {return 0, false
}
- for i := int(h % uint32(dt.size)); ; i = (i + 1) % dt.size {+ for i := int(h % uint64(dt.size)); ; i = (i + 1) % dt.size { if dt.offs[i] == 0 {return i, false
}
@@ -273,7 +278,7 @@
dt.offs = make([]uint32, dt.size)
for i := 0; i < dt.nblocks; i++ {block := &dt.blocks[i]
- idx := int(block.hash % uint32(dt.size))
+ idx := int(block.hash % uint64(dt.size))
for dt.offs[idx] != 0 {idx = (idx + 1) % dt.size
}
--- a/delta_write_encode.go
+++ b/delta_write_encode.go
@@ -89,7 +89,7 @@
return out, nil
}
-func deltaTry(base, target []byte, seed uint32, minSavings int) ([]byte, bool) {+func deltaTry(base, target []byte, seed uint64, minSavings int) ([]byte, bool) { if minSavings < 0 {minSavings = 0
}
--- a/delta_write_select.go
+++ b/delta_write_select.go
@@ -26,7 +26,7 @@
}
}
-func pickDeltaBase(ctx *deltaContext, obj *objectToPack, seed uint32, minSavings, maxDepth int) (*objectToPack, []byte) {+func pickDeltaBase(ctx *deltaContext, obj *objectToPack, seed uint64, minSavings, maxDepth int) (*objectToPack, []byte) { if ctx == nil || len(ctx.candidates) == 0 {return nil, nil
}
--- a/packed_write_pack.go
+++ b/packed_write_pack.go
@@ -319,14 +319,14 @@
}
var dctx deltaContext
- var deltaSeed uint32
+ var deltaSeed uint64
if opts.EnableDeltas {dctx.window = defaultDeltaWindow
- var seedBytes [4]byte
+ var seedBytes [8]byte
if _, err := rand.Read(seedBytes[:]); err != nil { return Hash{}, err}
- deltaSeed = binary.LittleEndian.Uint32(seedBytes[:])
+ deltaSeed = binary.LittleEndian.Uint64(seedBytes[:])
}
for _, id := range objects {--
⑨