From 59b8a806e4348d7a3d59ae04606f241c15dd42a2 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 15 May 2024 16:54:49 +0700 Subject: [PATCH 1/9] logic and test cases --- examples/gno.land/p/demo/bitmap/bitmap.gno | 40 ++++++++++++ .../gno.land/p/demo/bitmap/bitmap_test.gno | 62 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 examples/gno.land/p/demo/bitmap/bitmap.gno create mode 100644 examples/gno.land/p/demo/bitmap/bitmap_test.gno diff --git a/examples/gno.land/p/demo/bitmap/bitmap.gno b/examples/gno.land/p/demo/bitmap/bitmap.gno new file mode 100644 index 00000000000..312039b4425 --- /dev/null +++ b/examples/gno.land/p/demo/bitmap/bitmap.gno @@ -0,0 +1,40 @@ +package bitmap + +// A simple implementation of Bitmap + +// Bitmap represents a bitmap using a slice of bytes +type Bitmap struct { + data []byte +} + +// NewBitmap creates a new Bitmap with a specific size (in bits) +func New(size uint64) *Bitmap { + byteSize := (size + 7) / 8 // Calculate the number of bytes needed + return &Bitmap{ + data: make([]byte, byteSize), + } +} + +// Set sets the bit at the given index (0-based) +func (b *Bitmap) Set(index uint64) { + if index >= uint64(len(b.data))*8 { + panic("Index out of bounds") + } + + byteIndex := index / 8 + bitIndex := index % 8 + + b.data[byteIndex] |= 1 << uint(bitIndex) // Set the corresponding bit using bitwise OR +} + +// Get checks if the bit at the given index is set +func (b *Bitmap) Get(index uint64) bool { + if index >= uint64(len(b.data))*8 { + panic("Index out of bounds") + } + + byteIndex := index / 8 + bitIndex := index % 8 + + return b.data[byteIndex]&(1< 0 // Check if the corresponding bit is set using bitwise AND +} diff --git a/examples/gno.land/p/demo/bitmap/bitmap_test.gno b/examples/gno.land/p/demo/bitmap/bitmap_test.gno new file mode 100644 index 00000000000..0bfcc47bf3f --- /dev/null +++ b/examples/gno.land/p/demo/bitmap/bitmap_test.gno @@ -0,0 +1,62 @@ +package bitmap + +import ( + "testing" +) + +func TestNewBitmap(t *testing.T) { + // Test creating a bitmap with zero size + bm := New(0) + if len(bm.data) != 0 { + t.Errorf("Expected empty data slice for size 0, got %d bytes", len(bm.data)) + } + + // Test creating a bitmap with a small size + bm = New(8) + if len(bm.data) != 1 { + t.Errorf("Expected 1 byte for size 8, got %d bytes", len(bm.data)) + } + + // Test creating a bitmap with a size not divisible by 8 + bm = New(10) + if len(bm.data) != 2 { + t.Errorf("Expected 2 bytes for size 10, got %d bytes", len(bm.data)) + } +} + +func TestSetGet(t *testing.T) { + bm := New(16) + + // Test setting and getting a bit + bm.Set(5) + if !bm.Get(5) { + t.Errorf("Expected bit 5 to be set after setting") + } + if bm.Get(10) { + t.Errorf("Expected bit 10 to be unset") + } + + // Test setting and getting out of bounds + defer func() { + if recover() == nil { + t.Errorf("Expected panic for out of bounds index") + } + }() + bm.Set(20) // Should panic + + defer func() { + if recover() == nil { + t.Errorf("Expected panic for out of bounds index") + } + }() + bm.Get(20) // Should panic +} + +func TestLargeBitmap(t *testing.T) { + // Test creating and setting a bit in a larger bitmap + bm := New(1024) + bm.Set(512) + if !bm.Get(512) { + t.Errorf("Expected bit 512 to be set in a large bitmap") + } +} From cf42789137c791a9c9c42f1c6bf4891f7eb38909 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 15 May 2024 17:09:29 +0700 Subject: [PATCH 2/9] add gno.mod --- examples/gno.land/p/demo/bitmap/gno.mod | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/gno.land/p/demo/bitmap/gno.mod diff --git a/examples/gno.land/p/demo/bitmap/gno.mod b/examples/gno.land/p/demo/bitmap/gno.mod new file mode 100644 index 00000000000..f02ad3b1ce4 --- /dev/null +++ b/examples/gno.land/p/demo/bitmap/gno.mod @@ -0,0 +1 @@ +module gno.land/p/demo/avl \ No newline at end of file From 2e876e6ee3dea746f27683b8df436eeb41ec852a Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 15 May 2024 17:10:18 +0700 Subject: [PATCH 3/9] pull latest --- examples/gno.land/p/demo/bitmap/gno.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gno.land/p/demo/bitmap/gno.mod b/examples/gno.land/p/demo/bitmap/gno.mod index f02ad3b1ce4..192aa4108e8 100644 --- a/examples/gno.land/p/demo/bitmap/gno.mod +++ b/examples/gno.land/p/demo/bitmap/gno.mod @@ -1 +1 @@ -module gno.land/p/demo/avl \ No newline at end of file +module gno.land/p/demo/bitmap \ No newline at end of file From 0e13a8af25884c198ec184efed399c54cea8aa43 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Thu, 16 May 2024 14:46:11 +0700 Subject: [PATCH 4/9] add new line --- examples/gno.land/p/demo/bitmap/gno.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gno.land/p/demo/bitmap/gno.mod b/examples/gno.land/p/demo/bitmap/gno.mod index 192aa4108e8..02adc6bce14 100644 --- a/examples/gno.land/p/demo/bitmap/gno.mod +++ b/examples/gno.land/p/demo/bitmap/gno.mod @@ -1 +1 @@ -module gno.land/p/demo/bitmap \ No newline at end of file +module gno.land/p/demo/bitmap From daf272165dcecb99d47d4ca68f0c58287b6a9426 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Thu, 23 May 2024 10:18:16 +0700 Subject: [PATCH 5/9] refactor code and unit tests --- examples/gno.land/p/demo/bitmap/bitmap.gno | 20 +++- .../gno.land/p/demo/bitmap/bitmap_test.gno | 104 ++++++++++++------ examples/gno.land/p/demo/bitmap/gno.mod | 4 + 3 files changed, 92 insertions(+), 36 deletions(-) diff --git a/examples/gno.land/p/demo/bitmap/bitmap.gno b/examples/gno.land/p/demo/bitmap/bitmap.gno index 312039b4425..a351d8c5e54 100644 --- a/examples/gno.land/p/demo/bitmap/bitmap.gno +++ b/examples/gno.land/p/demo/bitmap/bitmap.gno @@ -1,5 +1,9 @@ package bitmap +import ( + "gno.land/p/demo/ufmt" +) + // A simple implementation of Bitmap // Bitmap represents a bitmap using a slice of bytes @@ -15,8 +19,22 @@ func New(size uint64) *Bitmap { } } +// MustSet sets the bit at the given index (0-based) and returns an error if out of bounds +func (b *Bitmap) Set(index uint64) error { + if index >= uint64(len(b.data))*8 { + return ufmt.Errorf("Index out of bounds") + } + + byteIndex := index / 8 + bitIndex := index % 8 + + b.data[byteIndex] |= 1 << uint(bitIndex) // Set the corresponding bit using bitwise OR + + return nil +} + // Set sets the bit at the given index (0-based) -func (b *Bitmap) Set(index uint64) { +func (b *Bitmap) MustSet(index uint64) { if index >= uint64(len(b.data))*8 { panic("Index out of bounds") } diff --git a/examples/gno.land/p/demo/bitmap/bitmap_test.gno b/examples/gno.land/p/demo/bitmap/bitmap_test.gno index 0bfcc47bf3f..78641f6e02c 100644 --- a/examples/gno.land/p/demo/bitmap/bitmap_test.gno +++ b/examples/gno.land/p/demo/bitmap/bitmap_test.gno @@ -4,59 +4,93 @@ import ( "testing" ) -func TestNewBitmap(t *testing.T) { - // Test creating a bitmap with zero size - bm := New(0) - if len(bm.data) != 0 { - t.Errorf("Expected empty data slice for size 0, got %d bytes", len(bm.data)) +func TestBitmap_New(t *testing.T) { + size := uint64(16) + bm := New(size) + + if len(bm.data)*8 != int(size) { + t.Errorf("Expected bitmap size: %d, got: %d", size, len(bm.data)*8) } +} + +func TestBitmap_SetAndGet(t *testing.T) { + bm := New(16) - // Test creating a bitmap with a small size - bm = New(8) - if len(bm.data) != 1 { - t.Errorf("Expected 1 byte for size 8, got %d bytes", len(bm.data)) + // Test setting and getting bits within bounds + err := bm.Set(2) + if err != nil { + t.Errorf("Expected no error, got: %v", err) } - // Test creating a bitmap with a size not divisible by 8 - bm = New(10) - if len(bm.data) != 2 { - t.Errorf("Expected 2 bytes for size 10, got %d bytes", len(bm.data)) + if !bm.Get(2) { + t.Errorf("Expected bit at index 2 to be set") } -} -func TestSetGet(t *testing.T) { - bm := New(16) + err = bm.Set(15) + if err != nil { + t.Errorf("Expected no error, got: %v", err) + } - // Test setting and getting a bit - bm.Set(5) - if !bm.Get(5) { - t.Errorf("Expected bit 5 to be set after setting") + if !bm.Get(15) { + t.Errorf("Expected bit at index 15 to be set") } - if bm.Get(10) { - t.Errorf("Expected bit 10 to be unset") + + // Test setting and getting bits out of bounds + err = bm.Set(16) + if err == nil { + t.Errorf("Expected error, got: nil") } +} + +func TestBitmap_MustSet(t *testing.T) { + bm := New(16) - // Test setting and getting out of bounds + // Test setting bits within bounds defer func() { - if recover() == nil { - t.Errorf("Expected panic for out of bounds index") + if r := recover(); r != nil { + t.Errorf("Expected no panic, but got panic: %v", r) } }() - bm.Set(20) // Should panic + bm.MustSet(2) + if !bm.Get(2) { + t.Errorf("Expected bit at index 2 to be set") + } + + bm.MustSet(15) + if !bm.Get(15) { + t.Errorf("Expected bit at index 15 to be set") + } + + // Test setting bits out of bounds defer func() { - if recover() == nil { - t.Errorf("Expected panic for out of bounds index") + if r := recover(); r == nil { + t.Errorf("Expected panic, but no panic occurred") } }() - bm.Get(20) // Should panic + + bm.MustSet(16 * 8) } -func TestLargeBitmap(t *testing.T) { - // Test creating and setting a bit in a larger bitmap - bm := New(1024) - bm.Set(512) - if !bm.Get(512) { - t.Errorf("Expected bit 512 to be set in a large bitmap") +func TestBitmap_Get(t *testing.T) { + bm := New(16) + + // Test getting bits within bounds + bm.MustSet(2) + if !bm.Get(2) { + t.Errorf("Expected bit at index 2 to be set") + } + + if bm.Get(3) { + t.Errorf("Expected bit at index 3 to be unset") } + + // Test getting bits out of bounds + defer func() { + if r := recover(); r == nil { + t.Errorf("Expected panic, but no panic occurred") + } + }() + + bm.Get(16 * 8) } diff --git a/examples/gno.land/p/demo/bitmap/gno.mod b/examples/gno.land/p/demo/bitmap/gno.mod index 02adc6bce14..059df78e23f 100644 --- a/examples/gno.land/p/demo/bitmap/gno.mod +++ b/examples/gno.land/p/demo/bitmap/gno.mod @@ -1 +1,5 @@ module gno.land/p/demo/bitmap + +require ( + gno.land/p/demo/testutils v0.0.0-latest +) \ No newline at end of file From e885be00db27ddccf9dbbddb12006bd4d8a84f72 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Thu, 23 May 2024 10:33:47 +0700 Subject: [PATCH 6/9] remove require --- examples/gno.land/p/demo/bitmap/gno.mod | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/gno.land/p/demo/bitmap/gno.mod b/examples/gno.land/p/demo/bitmap/gno.mod index 059df78e23f..192aa4108e8 100644 --- a/examples/gno.land/p/demo/bitmap/gno.mod +++ b/examples/gno.land/p/demo/bitmap/gno.mod @@ -1,5 +1 @@ -module gno.land/p/demo/bitmap - -require ( - gno.land/p/demo/testutils v0.0.0-latest -) \ No newline at end of file +module gno.land/p/demo/bitmap \ No newline at end of file From e20802046733876416a06f676f08d712989b52fc Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 20:24:56 +0700 Subject: [PATCH 7/9] add new line --- examples/gno.land/p/demo/bitmap/gno.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gno.land/p/demo/bitmap/gno.mod b/examples/gno.land/p/demo/bitmap/gno.mod index 192aa4108e8..02adc6bce14 100644 --- a/examples/gno.land/p/demo/bitmap/gno.mod +++ b/examples/gno.land/p/demo/bitmap/gno.mod @@ -1 +1 @@ -module gno.land/p/demo/bitmap \ No newline at end of file +module gno.land/p/demo/bitmap From 4b8a0dc0eaadafa4463e781ac644ec2165747fee Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 20:25:24 +0700 Subject: [PATCH 8/9] new line --- examples/gno.land/p/demo/bitmap/gno.mod | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/gno.land/p/demo/bitmap/gno.mod b/examples/gno.land/p/demo/bitmap/gno.mod index 02adc6bce14..757c3504851 100644 --- a/examples/gno.land/p/demo/bitmap/gno.mod +++ b/examples/gno.land/p/demo/bitmap/gno.mod @@ -1 +1,3 @@ module gno.land/p/demo/bitmap + +require gno.land/p/demo/ufmt v0.0.0-latest \ No newline at end of file From 421035279694a276863769a67295dcc134c2a50e Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 20:34:24 +0700 Subject: [PATCH 9/9] make tidy --- examples/gno.land/p/demo/bitmap/gno.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gno.land/p/demo/bitmap/gno.mod b/examples/gno.land/p/demo/bitmap/gno.mod index 757c3504851..57cb384bee6 100644 --- a/examples/gno.land/p/demo/bitmap/gno.mod +++ b/examples/gno.land/p/demo/bitmap/gno.mod @@ -1,3 +1,3 @@ module gno.land/p/demo/bitmap -require gno.land/p/demo/ufmt v0.0.0-latest \ No newline at end of file +require gno.land/p/demo/ufmt v0.0.0-latest