shithub: furgit

Download patch

ref: 7cb1995e2b431a900e23958e23565da7922e976a
parent: 7ee37c0fb0530e89a11d97a65d6440b66d4b8e6f
author: Runxi Yu <me@runxiyu.org>
date: Fri Feb 20 07:49:27 EST 2026

Revert "delta, packed: Use xxhash instead of murmurhash2"

This reverts commit ac400226b0b622aae21b09cb6c83f07924647d0d.

--- a/delta_write_deltify.go
+++ b/delta_write_deltify.go
@@ -3,7 +3,7 @@
 import (
 	"bytes"
 
-	"github.com/cespare/xxhash/v2"
+	"codeberg.org/lindenii/furgit/internal/murmurhash2"
 )
 
 const (
@@ -62,7 +62,7 @@
 type deltaBlock struct {
 	length int
 	offset int
-	hash   uint64
+	hash   uint32
 }
 
 type deltaTable struct {
@@ -82,7 +82,7 @@
 	data   []byte
 }
 
-func deltify(base, target []byte, seed uint64) ([]deltaInstruction, error) {
+func deltify(base, target []byte, seed uint32) ([]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 uint64, dt *deltaTable, base []byte, baseOffset0, baseSize int) ([]deltaInstruction, error) {
+func deltifyMemMem(target []byte, fileoffset, filesize int, seed uint32, 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 uint64) (*deltaTable, error) {
+func deltaTableInitMem(data []byte, fileoffset, filesize int, seed uint32) (*deltaTable, error) {
 	dt := &deltaTable{
 		nalloc: 128,
 		size:   128,
@@ -164,13 +164,8 @@
 	return dt, nil
 }
 
-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 deltaHashBlock(p []byte, seed uint32) uint32 {
+	return murmurhash2.Sum32(p, seed)
 }
 
 func deltaNextBlockLen(data []byte, fileoffset, filesize int) int {
@@ -193,7 +188,7 @@
 	return p - fileoffset
 }
 
-func (dt *deltaTable) addBlock(data []byte, offset0, length, offset int, h uint64) error {
+func (dt *deltaTable) addBlock(data []byte, offset0, length, offset int, h uint32) error {
 	if length == 0 {
 		return nil
 	}
@@ -205,22 +200,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 uint64, base []byte, baseOffset0 int) *deltaBlock {
+func (dt *deltaTable) lookupBlock(chunk []byte, length int, seed uint32, base []byte, baseOffset0 int) *deltaBlock {
 	if dt == nil || dt.size == 0 {
 		return nil
 	}
 	h := deltaHashBlock(chunk, seed)
-	for i := int(h % uint64(dt.size)); dt.offs[i] != 0; i = (i + 1) % dt.size {
+	for i := int(h % uint32(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
@@ -236,11 +231,11 @@
 	return nil
 }
 
-func (dt *deltaTable) lookupSlot(data []byte, offset0, offset, length int, h uint64) (int, bool) {
+func (dt *deltaTable) lookupSlot(data []byte, offset0, offset, length int, h uint32) (int, bool) {
 	if dt == nil || dt.size == 0 {
 		return 0, false
 	}
-	for i := int(h % uint64(dt.size)); ; i = (i + 1) % dt.size {
+	for i := int(h % uint32(dt.size)); ; i = (i + 1) % dt.size {
 		if dt.offs[i] == 0 {
 			return i, false
 		}
@@ -278,7 +273,7 @@
 		dt.offs = make([]uint32, dt.size)
 		for i := 0; i < dt.nblocks; i++ {
 			block := &dt.blocks[i]
-			idx := int(block.hash % uint64(dt.size))
+			idx := int(block.hash % uint32(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 uint64, minSavings int) ([]byte, bool) {
+func deltaTry(base, target []byte, seed uint32, 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 uint64, minSavings, maxDepth int) (*objectToPack, []byte) {
+func pickDeltaBase(ctx *deltaContext, obj *objectToPack, seed uint32, 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
@@ -306,14 +306,14 @@
 	}
 
 	var dctx deltaContext
-	var deltaSeed uint64
+	var deltaSeed uint32
 	if opts.EnableDeltas {
 		dctx.window = defaultDeltaWindow
-		var seedBytes [8]byte
+		var seedBytes [4]byte
 		if _, err := rand.Read(seedBytes[:]); err != nil {
 			return Hash{}, err
 		}
-		deltaSeed = binary.LittleEndian.Uint64(seedBytes[:])
+		deltaSeed = binary.LittleEndian.Uint32(seedBytes[:])
 	}
 
 	for _, id := range objects {
--