From 7fa2d0f2923a351ce7b59b71eaf0220013821da2 Mon Sep 17 00:00:00 2001 From: dima <1.e4.kc6@gmail.com> Date: Sat, 1 Nov 2025 16:16:20 +0000 Subject: [PATCH] added CountVarUint64, CountVarUint32, CountVarSize --- little/little.go | 76 ++++++++++++++++++++++++++++++++++--------- little/little_test.go | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 15 deletions(-) diff --git a/little/little.go b/little/little.go index 3fd80da..f68c9e2 100644 --- a/little/little.go +++ b/little/little.go @@ -996,6 +996,24 @@ func ReadVarUint64(src io.Reader) (num uint64, err error) { return } +func WriteBool(w io.Writer, flag bool) (err error) { + var b byte + if flag { + b = 1 + } + _, err = w.Write([]byte{b}) + return +} + +func ReadBool(src io.Reader) (bool, error) { + b, err := ReadByte(src) + if err != nil { + return false, err + } + return b == 1, nil +} + +// uint64 func WriteVarSize(w io.Writer, n int) (int, error) { num := uint64(n) a := make([]byte, 9) @@ -1013,15 +1031,6 @@ func WriteVarSize(w io.Writer, n int) (int, error) { return w.Write(a) } -func WriteBool(w io.Writer, flag bool) (err error) { - var b byte - if flag { - b = 1 - } - _, err = w.Write([]byte{b}) - return -} - func ReadVarSize(src io.Reader) (_ int, err error) { var ( b byte @@ -1047,10 +1056,47 @@ func ReadVarSize(src io.Reader) (_ int, err error) { return int(num), nil } -func ReadBool(src io.Reader) (bool, error) { - b, err := ReadByte(src) - if err != nil { - return false, err - } - return b == 1, nil +var varUint32Cutoffs = []uint32{ + 1 << 7, + 1 << 14, + 1 << 21, + 1 << 28, +} + +func CountVarUint32(n uint32) int { + for i, cutoff := range varUint32Cutoffs { + if n < cutoff { + return i + 1 + } + } + return 5 +} + +var varUint64Cutoffs = []uint64{ + 1 << 7, + 1 << 14, + 1 << 21, + 1 << 28, + 1 << 35, + 1 << 42, + 1 << 49, + 1 << 56, +} + +func CountVarUint64(n uint64) int { + for i, cutoff := range varUint64Cutoffs { + if n < cutoff { + return i + 1 + } + } + return 9 +} +func CountVarSize(n int) int { + u64 := uint64(n) + for i, cutoff := range varUint64Cutoffs { + if u64 < cutoff { + return i + 1 + } + } + return 9 } diff --git a/little/little_test.go b/little/little_test.go index 0f29cea..c087270 100644 --- a/little/little_test.go +++ b/little/little_test.go @@ -703,6 +703,96 @@ func TestWriteReadBool(t *testing.T) { } } +// VAR SIZE COUNT + +func TestCountVarUint32(t *testing.T) { + var testCases = []struct { + Num uint32 + Count int + }{ + {Num: (1 << 7) - 1, Count: 1}, + {Num: (1 << 7), Count: 2}, + {Num: (1 << 14) - 1, Count: 2}, + {Num: (1 << 14), Count: 3}, + {Num: (1 << 21) - 1, Count: 3}, + {Num: (1 << 21), Count: 4}, + {Num: (1 << 28) - 1, Count: 4}, + {Num: (1 << 28), Count: 5}, + {Num: (1 << 32) - 1, Count: 5}, + } + for _, testCase := range testCases { + count := CountVarUint32(testCase.Num) + if count != testCase.Count { + t.Fatalf("calculated count %d is not equal %d for num %d\n", + count, testCase.Count, testCase.Num) + } + } +} + +func TestCountVarUint64(t *testing.T) { + var testCases = []struct { + Num uint64 + Count int + }{ + {Num: (1 << 7) - 1, Count: 1}, + {Num: (1 << 7), Count: 2}, + {Num: (1 << 14) - 1, Count: 2}, + {Num: (1 << 14), Count: 3}, + {Num: (1 << 21) - 1, Count: 3}, + {Num: (1 << 21), Count: 4}, + {Num: (1 << 28) - 1, Count: 4}, + {Num: (1 << 28), Count: 5}, + {Num: (1 << 35) - 1, Count: 5}, + {Num: (1 << 35), Count: 6}, + {Num: (1 << 42) - 1, Count: 6}, + {Num: (1 << 42), Count: 7}, + {Num: (1 << 49) - 1, Count: 7}, + {Num: (1 << 49), Count: 8}, + {Num: (1 << 56) - 1, Count: 8}, + {Num: (1 << 56), Count: 9}, + {Num: (1 << 64) - 1, Count: 9}, + } + for _, testCase := range testCases { + count := CountVarUint64(testCase.Num) + if count != testCase.Count { + t.Fatalf("calculated count %d is not equal %d for num %d\n", + count, testCase.Count, testCase.Num) + } + } +} + +func TestCountVarSize(t *testing.T) { + var testCases = []struct { + Num int + Count int + }{ + {Num: (1 << 7) - 1, Count: 1}, + {Num: (1 << 7), Count: 2}, + {Num: (1 << 14) - 1, Count: 2}, + {Num: (1 << 14), Count: 3}, + {Num: (1 << 21) - 1, Count: 3}, + {Num: (1 << 21), Count: 4}, + {Num: (1 << 28) - 1, Count: 4}, + {Num: (1 << 28), Count: 5}, + {Num: (1 << 35) - 1, Count: 5}, + {Num: (1 << 35), Count: 6}, + {Num: (1 << 42) - 1, Count: 6}, + {Num: (1 << 42), Count: 7}, + {Num: (1 << 49) - 1, Count: 7}, + {Num: (1 << 49), Count: 8}, + {Num: (1 << 56) - 1, Count: 8}, + {Num: (1 << 56), Count: 9}, + {Num: (1 << 63) - 1, Count: 9}, + } + for _, testCase := range testCases { + count := CountVarSize(testCase.Num) + if count != testCase.Count { + t.Fatalf("calculated count %d is not equal %d for num %d\n", + count, testCase.Count, testCase.Num) + } + } +} + // HELPERS const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"