From f857eb98e250f326bc8ba39bed5955c96eaa56c5 Mon Sep 17 00:00:00 2001 From: proost Date: Sat, 1 Aug 2026 16:52:31 +0900 Subject: [PATCH] test: count min sketch serialization test --- count/count_min_sketch.go | 4 + count/count_min_sketch_serialization_test.go | 117 ++++++++++++++++++ .../count_min_empty_cpp.sk | Bin 0 -> 16 bytes .../count_min_non_empty_cpp.sk | Bin 0 -> 24600 bytes .../go_generated_files/count_min_empty_go.sk | Bin 0 -> 16 bytes .../count_min_non_empty_go.sk | Bin 0 -> 24600 bytes 6 files changed, 121 insertions(+) create mode 100644 count/count_min_sketch_serialization_test.go create mode 100644 serialization_test_data/cpp_generated_files/count_min_empty_cpp.sk create mode 100644 serialization_test_data/cpp_generated_files/count_min_non_empty_cpp.sk create mode 100644 serialization_test_data/go_generated_files/count_min_empty_go.sk create mode 100644 serialization_test_data/go_generated_files/count_min_non_empty_go.sk diff --git a/count/count_min_sketch.go b/count/count_min_sketch.go index 30dd99d..ca79d5b 100644 --- a/count/count_min_sketch.go +++ b/count/count_min_sketch.go @@ -28,6 +28,10 @@ import ( "github.com/apache/datasketches-go/internal" ) +const ( + DefaultSeed = 9001 +) + // Implementation of the CountMin sketch data structure of Cormode and Muthukrishnan. // [1] - http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf type CountMinSketch struct { diff --git a/count/count_min_sketch_serialization_test.go b/count/count_min_sketch_serialization_test.go new file mode 100644 index 0000000..646a251 --- /dev/null +++ b/count/count_min_sketch_serialization_test.go @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package count + +import ( + "bytes" + "fmt" + "os" + "testing" + + "github.com/apache/datasketches-go/internal" + "github.com/stretchr/testify/assert" +) + +func TestGenerateGoSnapshots(t *testing.T) { + if len(os.Getenv(internal.DSketchTestGenerateGo)) == 0 { + t.Skipf("%s not set", internal.DSketchTestGenerateGo) + } + + t.Run("empty", func(t *testing.T) { + sketch, err := NewCountMinSketch(1, 5, DefaultSeed) + assert.NoError(t, err) + + var buf bytes.Buffer + err = sketch.Serialize(&buf) + assert.NoError(t, err) + + err = os.MkdirAll(internal.GoPath, os.ModePerm) + assert.NoError(t, err) + err = os.WriteFile(fmt.Sprintf("%s/count_min_empty_go.sk", internal.GoPath), buf.Bytes(), 0644) + assert.NoError(t, err) + }) + + t.Run("non empty", func(t *testing.T) { + sketch, err := NewCountMinSketch(3, 1024, DefaultSeed) + assert.NoError(t, err) + for i := 0; i < 10; i++ { + err := sketch.UpdateUint64(uint64(i), int64(10*i*i)) + assert.NoError(t, err) + } + + var buf bytes.Buffer + err = sketch.Serialize(&buf) + assert.NoError(t, err) + + err = os.MkdirAll(internal.GoPath, os.ModePerm) + assert.NoError(t, err) + err = os.WriteFile(fmt.Sprintf("%s/count_min_non_empty_go.sk", internal.GoPath), buf.Bytes(), 0644) + assert.NoError(t, err) + }) +} + +func TestCPPCompact(t *testing.T) { + t.Run("empty", func(t *testing.T) { + filename := fmt.Sprintf("%s/count_min_empty_cpp.sk", internal.CppPath) + if _, err := os.Stat(filename); os.IsNotExist(err) { + assert.FailNowf(t, "file %s does not exist", filename) + return + } + + b, err := os.ReadFile(filename) + assert.NoError(t, err) + + sketch, err := NewCountMinSketch(1, 5, DefaultSeed) + assert.NoError(t, err) + + result, err := sketch.Deserialize(b, DefaultSeed) + assert.NoError(t, err) + + assert.Equal(t, sketch.GetNumHashes(), result.GetNumHashes()) + assert.Equal(t, sketch.GetNumBuckets(), result.GetNumBuckets()) + assert.Equal(t, sketch.GetSeed(), result.GetSeed()) + assert.Equal(t, sketch.GetEstimateUint64(0), result.GetEstimateUint64(0)) + assert.Equal(t, sketch.GetTotalWeight(), result.GetTotalWeight()) + }) + + t.Run("non empty", func(t *testing.T) { + filename := fmt.Sprintf("%s/count_min_non_empty_cpp.sk", internal.CppPath) + if _, err := os.Stat(filename); os.IsNotExist(err) { + assert.FailNowf(t, "file %s does not exist", filename) + return + } + + b, err := os.ReadFile(filename) + assert.NoError(t, err) + + sketch, err := NewCountMinSketch(3, 1024, DefaultSeed) + assert.NoError(t, err) + for i := 0; i < 10; i++ { + err := sketch.UpdateUint64(uint64(i), int64(10*i*i)) + assert.NoError(t, err) + } + + result, err := sketch.Deserialize(b, DefaultSeed) + assert.NoError(t, err) + + assert.Equal(t, sketch.GetNumHashes(), result.GetNumHashes()) + assert.Equal(t, sketch.GetNumBuckets(), result.GetNumBuckets()) + assert.Equal(t, sketch.GetSeed(), result.GetSeed()) + assert.Equal(t, sketch.GetTotalWeight(), result.GetTotalWeight()) + }) +} diff --git a/serialization_test_data/cpp_generated_files/count_min_empty_cpp.sk b/serialization_test_data/cpp_generated_files/count_min_empty_cpp.sk new file mode 100644 index 0000000000000000000000000000000000000000..3e75137d75f27b0f89f2c5975d4b0258f6de9a51 GIT binary patch literal 16 UcmZQ#6k=om0#+bqJTsXA00jO4d;kCd literal 0 HcmV?d00001 diff --git a/serialization_test_data/cpp_generated_files/count_min_non_empty_cpp.sk b/serialization_test_data/cpp_generated_files/count_min_non_empty_cpp.sk new file mode 100644 index 0000000000000000000000000000000000000000..9631a654d2f1146a544d8595f75213e13f6e9b89 GIT binary patch literal 24600 zcmeI(yA8rH5CG78sGws6D#S=kz!>bn0vU)&7=a22nv_W-W1syf5Rqd0?p+#u&d?vb z?`PL_<2pkje{#kol>y}&j75>_BUfB=D+z-63W_?b*VzcU%Fi3t!OK!5-N z0t5&UAP`zWKPzI@3!GuA8 z009C72!s`w!bTn=@K*juq^gE}vsAL?jVPc$6R~PyCa_GPwf(K7`+m#xw%^rCKW4j- ikp%J!=qKi{fd~i?AV7dXZUOH%=B|MC2@oLgUx5#RiVh?I literal 0 HcmV?d00001 diff --git a/serialization_test_data/go_generated_files/count_min_empty_go.sk b/serialization_test_data/go_generated_files/count_min_empty_go.sk new file mode 100644 index 0000000000000000000000000000000000000000..3e75137d75f27b0f89f2c5975d4b0258f6de9a51 GIT binary patch literal 16 UcmZQ#6k=om0#+bqJTsXA00jO4d;kCd literal 0 HcmV?d00001 diff --git a/serialization_test_data/go_generated_files/count_min_non_empty_go.sk b/serialization_test_data/go_generated_files/count_min_non_empty_go.sk new file mode 100644 index 0000000000000000000000000000000000000000..279ac9bc19d18875918654df6d1739e279599cfb GIT binary patch literal 24600 zcmeI(yA8rH5CG7GP(jBCREUw7fHByC1u_tmFai}4NU38vA3OIbP$JnE-@6Ej__AwH z&F`~sn(p;%&d2|0l