diff --git a/gnovm/stdlibs/std/addr_set.gno b/gnovm/stdlibs/std/addr_set.gno index 3f46f48b8b5..62266d226a3 100644 --- a/gnovm/stdlibs/std/addr_set.gno +++ b/gnovm/stdlibs/std/addr_set.gno @@ -1,9 +1,10 @@ package std -import "errors" +import ( + "errors" -//---------------------------------------- -// AddressSet + "gno.land/p/demo/avl" +) type AddressSet interface { Size() int @@ -11,37 +12,25 @@ type AddressSet interface { HasAddress(Address) bool } -//---------------------------------------- -// AddressList implements AddressSet. -// TODO implement AddressTree with avl. - -type AddressList []Address +type AddressList struct { + list *avl.Tree +} func NewAddressList() *AddressList { - return &AddressList{} + return &AddressList{list: avl.NewTree()} } -func (alist *AddressList) Size() int { - return len(*alist) +func (alist AddressList) Size() int { + return alist.list.Size() } func (alist *AddressList) AddAddress(newAddr Address) error { - // TODO optimize with binary algorithm - for _, addr := range *alist { - if addr == newAddr { - return errors.New("address already exists") - } + if alist.list.Set(newAddr.String(), newAddr) { + return errors.New("address already exists") } - *alist = append(*alist, newAddr) return nil } -func (alist *AddressList) HasAddress(newAddr Address) bool { - // TODO optimize with binary algorithm - for _, addr := range *alist { - if addr == newAddr { - return true - } - } - return false +func (alist AddressList) HasAddress(newAddr Address) bool { + return alist.list.Has(newAddr.String()) } diff --git a/gnovm/stdlibs/std/addr_set_test.gno b/gnovm/stdlibs/std/addr_set_test.gno new file mode 100644 index 00000000000..636b2152bcd --- /dev/null +++ b/gnovm/stdlibs/std/addr_set_test.gno @@ -0,0 +1,27 @@ +package std + +import ( + "testing" + + "gno.land/p/demo/testutils" +) + +func TestAddrSet(t *testing.T) { + addresslist := NewAddressList() + if addresslist.Size() != 0 { + t.Errorf("Expected size 0, got %d", addresslist.Size()) + } + test1 := testutils.TestAddress("test1") + if err := addresslist.AddAddress(test1); err != nil { + t.Errorf("Expected no error, got %v", err) + } + if !addresslist.HasAddress(test1) { + t.Errorf("Address doesnt exist: %v", addresslist.HasAddress(test1)) + } + if addresslist.Size() != 1 { + t.Errorf("Expected size 1, got %d", addresslist.Size()) + } + if err := addresslist.AddAddress(test1); err.Error() != "address already exists" { + t.Errorf("Expected \"address already exists\", got %v", err) + } +} diff --git a/gnovm/tests/files/zrealm_std1.gno b/gnovm/tests/files/zrealm_std1.gno index 87f75bcb871..7a1356fd582 100644 --- a/gnovm/tests/files/zrealm_std1.gno +++ b/gnovm/tests/files/zrealm_std1.gno @@ -25,7 +25,7 @@ func main() { } // Output: -// (slice[ref(1ed29bd278d735e20e296bd4afe927501941392f:4)] std.AddressList) +// (struct{(&(ref(1ed29bd278d735e20e296bd4afe927501941392f:5) gno.land/p/demo/avl.Tree) *gno.land/p/demo/avl.Tree)} std.AddressList) // error: address already exists // has: true // has: false diff --git a/gnovm/tests/files/zrealm_std2.gno b/gnovm/tests/files/zrealm_std2.gno index 1ae1fb4a881..b18f2126a30 100644 --- a/gnovm/tests/files/zrealm_std2.gno +++ b/gnovm/tests/files/zrealm_std2.gno @@ -26,7 +26,7 @@ func main() { } // Output: -// (slice[ref(1ed29bd278d735e20e296bd4afe927501941392f:4)] std.AddressList) +// (struct{(&(ref(1ed29bd278d735e20e296bd4afe927501941392f:5) gno.land/p/demo/avl.Tree) *gno.land/p/demo/avl.Tree)} std.AddressList) // error: address already exists // has: true // has: false