nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: puzpuzpuz/xsync
Pull request #66 (2022-10-29 06:42:47)

Fix the second `valueFn` call in `(*MapOf) LoadOrCompute`.


Patch:
diff --git a/mapof.go b/mapof.go
index 048e186..32d1cc9 100644
--- a/mapof.go
+++ b/mapof.go
@@ -229,7 +229,7 @@ func (m *MapOf[K, V]) doStore(key K, valueFn func() V, loadIfExists bool) (V, bo
 					topHashes = atomic.LoadUint64(&emptyb.topHashMutex)
 					atomic.StoreUint64(&emptyb.topHashMutex, storeTopHash(hash, topHashes, emptyidx))
 					value := valueFn()
-					var wv interface{} = valueFn()
+					var wv interface{} = value
 					atomic.StorePointer(&emptyb.values[emptyidx], unsafe.Pointer(&wv))
 					atomic.StorePointer(&emptyb.keys[emptyidx], unsafe.Pointer(&key))
 					unlockBucket(&rootb.topHashMutex)


Test patch:
diff --git a/mapof_test.go b/mapof_test.go
index fb8a26d..36b3b65 100644
--- a/mapof_test.go
+++ b/mapof_test.go
@@ -395,6 +395,20 @@ func TestMapOfSerialLoadOrCompute(t *testing.T) {
 			t.Errorf("values do not match for %d: %v", i, v)
 		}
 	}
+
+	t.Run("valueFn func should be called only once", func(t *testing.T) {
+		m := NewIntegerMapOf[int, int]()
+		for i := 0; i < 100; {
+			m.LoadOrCompute(i, func() (v int) { v, i = i, i+1; return v })
+		}
+
+		m.Range(func(k, v int) bool {
+			if k != v {
+				t.Fatalf("%dth key is not equal to value %d", k, v)
+			}
+			return true
+		})
+	})
 }
 
 func TestMapOfSerialStoreThenDelete(t *testing.T) {
Repository: puzpuzpuz/xsync
Pull request #98 (2023-06-04 12:26:34)

Fix nextPowOf2 on zero input
### change

1. if input `0` in nextPowOf2, the v is max(uint32) - 1 after v--.
2. add more unit test for util.


Patch:
diff --git a/util.go b/util.go
index 12d83e6..81a596a 100644
--- a/util.go
+++ b/util.go
@@ -20,6 +20,9 @@ const (
 // nextPowOf2 computes the next highest power of 2 of 32-bit v.
 // Source: https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
 func nextPowOf2(v uint32) uint32 {
+	if v == 0 {
+		return 1
+	}
 	v--
 	v |= v >> 1
 	v |= v >> 2


Test patch:
diff --git a/util_test.go b/util_test.go
new file mode 100644
index 0000000..cef9bee
--- /dev/null
+++ b/util_test.go
@@ -0,0 +1,49 @@
+package xsync
+
+import (
+	"math/rand"
+	"testing"
+)
+
+func TestNextPowOf2(t *testing.T) {
+	if nextPowOf2(0) != 1 {
+		t.Error("nextPowOf2 failed")
+	}
+	if nextPowOf2(1) != 1 {
+		t.Error("nextPowOf2 failed")
+	}
+	if nextPowOf2(2) != 2 {
+		t.Error("nextPowOf2 failed")
+	}
+	if nextPowOf2(3) != 4 {
+		t.Error("nextPowOf2 failed")
+	}
+}
+
+func TestFastrand(t *testing.T) {
+	count := 10000
+	set := make(map[uint32]struct{}, count)
+
+	for i := 0; i < count; i++ {
+		num := fastrand()
+		set[num] = struct{}{}
+	}
+
+	if len(set) != count {
+		t.Error("duplicated rand num")
+	}
+}
+
+func BenchmarkFastrand(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_ = fastrand()
+	}
+	// about 1.5 ns/op
+}
+
+func BenchmarkRand(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_ = rand.Uint32()
+	}
+	// about 12 ns/op
+}