Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: speed gnovm integration tests #17

Open
wants to merge 41 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ea598bc
chore: experimental render proxy example for versioned realms (#3341)
jeronimoalbi Dec 20, 2024
46af920
fix: rework and speed gnovm integration tests
gfanton Dec 20, 2024
e74adaa
fix: gno.land config integration
gfanton Dec 20, 2024
e01d185
fix(gnoland): speed test & rework directory
gfanton Dec 20, 2024
9586dfe
wip: fork
gfanton Dec 20, 2024
2e332dd
fix(p/demo/avl): correct order for IterateByOffset (#3393)
thehowl Dec 20, 2024
bcb44c8
wip: poc fork node
gfanton Dec 20, 2024
ddef133
fix: test pk
gfanton Dec 20, 2024
eb3702a
fix: increase timeout
gfanton Dec 20, 2024
de031ca
fix: increase timeout 2
gfanton Dec 20, 2024
a9bde35
wip: use db dir
gfanton Dec 20, 2024
d3717e4
wip: verbose mode
gfanton Dec 20, 2024
7ac95fe
fix: set fork test sequential
gfanton Dec 21, 2024
88fb8cb
feat(examples): add p/demo/avl/list (#3324)
moul Dec 21, 2024
5dd2a66
fix: improve gno.land/gnoclient integration tests speed
gfanton Dec 21, 2024
cafdbbf
wip: fix gnolang integration test
gfanton Dec 21, 2024
bfafba6
wip: test without integ
gfanton Dec 21, 2024
c163a48
wip: integ
gfanton Dec 21, 2024
6f7c677
fix(cmd/gno): reset runtime metrics allocator on each test run (#3394)
thehowl Dec 23, 2024
ea32315
feat(stdlibs): add `encoding`, `encoding/{base32,binary,csv}` (#1290)
notJoon Dec 25, 2024
a3b76d4
fix: rename and update cmd -> process
gfanton Dec 27, 2024
0709984
feat(examples): Add Nemanya's Home Realm to Examples (#3410)
Nemanya8 Dec 27, 2024
3fd5571
feat(examples): add moul/typeutil (#3404)
moul Dec 27, 2024
a9b8e42
wip: cleanup
gfanton Dec 27, 2024
680180e
chore: cleanup
gfanton Dec 27, 2024
b6a4aab
fix(examples): run 'make fmt' (#3415)
moul Dec 27, 2024
597f3f5
chore: add r/demo/tests/test20 + add grc20.TokenGetter to reduce boil…
moul Dec 28, 2024
198af81
feat: command kind
gfanton Dec 29, 2024
20a2a76
chore: lint
gfanton Dec 29, 2024
f9a9b2f
chore: lint
gfanton Dec 29, 2024
c2064c0
chore: rename some files
gfanton Dec 29, 2024
54a776b
fix: make coverage works
gfanton Dec 29, 2024
ee516b8
Merge branch 'master' into fix/gnland/test-speed
gfanton Dec 29, 2024
c6af61d
chore: remove logger
gfanton Dec 30, 2024
beb48e7
feat(examples): add moul/ulist (#3407)
moul Dec 31, 2024
b3c3a83
Merge branch 'master' into fix/gnland/test-speed
gfanton Jan 5, 2025
d19d089
chore: doc integration command and cleanup
gfanton Jan 6, 2025
e530049
fix: make coverage happy
gfanton Jan 6, 2025
2d9e101
chore: cleanup lefthover file
gfanton Jan 6, 2025
dfe212b
fix: inmemory db cleanup
gfanton Jan 6, 2025
45b5921
chore: lint
gfanton Jan 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
paths:
- gnovm/**/*.gno
- examples/**/*.gno
- examples/**/gno.mod

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
Expand Down
1 change: 1 addition & 0 deletions examples/gno.land/p/demo/avl/list/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module gno.land/p/demo/avl/list
298 changes: 298 additions & 0 deletions examples/gno.land/p/demo/avl/list/list.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
// Package list implements a dynamic list data structure backed by an AVL tree.
// It provides O(log n) operations for most list operations while maintaining
// order stability.
//
// The list supports various operations including append, get, set, delete,
// range queries, and iteration. It can store values of any type.
//
// Example usage:
//
// // Create a new list and add elements
// var l list.List
// l.Append(1, 2, 3)
//
// // Get and set elements
// value := l.Get(1) // returns 2
// l.Set(1, 42) // updates index 1 to 42
//
// // Delete elements
// l.Delete(0) // removes first element
//
// // Iterate over elements
// l.ForEach(func(index int, value interface{}) bool {
// ufmt.Printf("index %d: %v\n", index, value)
// return false // continue iteration
// })
// // Output:
// // index 0: 42
// // index 1: 3
//
// // Create a list of specific size
// l = list.Make(3, "default") // creates [default, default, default]
//
// // Create a list using a variable declaration
// var l2 list.List
// l2.Append(4, 5, 6)
// println(l2.Len()) // Output: 3
package list

import (
"gno.land/p/demo/avl"
"gno.land/p/demo/seqid"
)

// List represents an ordered sequence of items backed by an AVL tree
type List struct {
tree avl.Tree
idGen seqid.ID
}

// Len returns the number of elements in the list.
//
// Example:
//
// l := list.New()
// l.Append(1, 2, 3)
// println(l.Len()) // Output: 3
func (l *List) Len() int {
return l.tree.Size()
}

// Append adds one or more values to the end of the list.
//
// Example:
//
// l := list.New()
// l.Append(1) // adds single value
// l.Append(2, 3, 4) // adds multiple values
// println(l.Len()) // Output: 4
func (l *List) Append(values ...interface{}) {
for _, v := range values {
l.tree.Set(l.idGen.Next().String(), v)
}
}

// Get returns the value at the specified index.
// Returns nil if index is out of bounds.
//
// Example:
//
// l := list.New()
// l.Append(1, 2, 3)
// println(l.Get(1)) // Output: 2
// println(l.Get(-1)) // Output: nil
// println(l.Get(999)) // Output: nil
func (l *List) Get(index int) interface{} {
if index < 0 || index >= l.tree.Size() {
return nil
}
_, value := l.tree.GetByIndex(index)
return value
}

// Set updates or appends a value at the specified index.
// Returns true if the operation was successful, false otherwise.
// For empty lists, only index 0 is valid (append case).
//
// Example:
//
// l := list.New()
// l.Append(1, 2, 3)
//
// l.Set(1, 42) // updates existing index
// println(l.Get(1)) // Output: 42
//
// l.Set(3, 4) // appends at end
// println(l.Get(3)) // Output: 4
//
// l.Set(-1, 5) // invalid index
// println(l.Len()) // Output: 4 (list unchanged)
func (l *List) Set(index int, value interface{}) bool {
size := l.tree.Size()

// Handle empty list case - only allow index 0
if size == 0 {
if index == 0 {
l.Append(value)
return true
}
return false
}

if index < 0 || index > size {
return false
}

// If setting at the end (append case)
if index == size {
l.Append(value)
return true
}

// Get the key at the specified index
key, _ := l.tree.GetByIndex(index)
if key == "" {
return false
}

// Update the value at the existing key
l.tree.Set(key, value)
return true
}

// Delete removes the element at the specified index.
// Returns the deleted value and true if successful, nil and false otherwise.
//
// Example:
//
// l := list.New()
// l.Append(1, 2, 3)
//
// val, ok := l.Delete(1)
// println(val, ok) // Output: 2 true
// println(l.Len()) // Output: 2
//
// val, ok = l.Delete(-1)
// println(val, ok) // Output: nil false
func (l *List) Delete(index int) (interface{}, bool) {
size := l.tree.Size()
// Always return nil, false for empty list
if size == 0 {
return nil, false
}

if index < 0 || index >= size {
return nil, false
}

key, value := l.tree.GetByIndex(index)
if key == "" {
return nil, false
}

l.tree.Remove(key)
return value, true
}

// Slice returns a slice of values from startIndex (inclusive) to endIndex (exclusive).
// Returns nil if the range is invalid.
//
// Example:
//
// l := list.New()
// l.Append(1, 2, 3, 4, 5)
//
// println(l.Slice(1, 4)) // Output: [2 3 4]
// println(l.Slice(-1, 2)) // Output: [1 2]
// println(l.Slice(3, 999)) // Output: [4 5]
// println(l.Slice(3, 2)) // Output: nil
func (l *List) Slice(startIndex, endIndex int) []interface{} {
size := l.tree.Size()

// Normalize bounds
if startIndex < 0 {
startIndex = 0
}
if endIndex > size {
endIndex = size
}
if startIndex >= endIndex {
return nil
}

count := endIndex - startIndex
result := make([]interface{}, count)

i := 0
l.tree.IterateByOffset(startIndex, count, func(_ string, value interface{}) bool {
result[i] = value
i++
return false
})
return result
}

// ForEach iterates through all elements in the list.
func (l *List) ForEach(fn func(index int, value interface{}) bool) {
if l.tree.Size() == 0 {
return
}

index := 0
l.tree.IterateByOffset(0, l.tree.Size(), func(_ string, value interface{}) bool {
result := fn(index, value)
index++
return result
})
}

// Clone creates a shallow copy of the list.
//
// Example:
//
// l := list.New()
// l.Append(1, 2, 3)
//
// clone := l.Clone()
// clone.Set(0, 42)
//
// println(l.Get(0)) // Output: 1
// println(clone.Get(0)) // Output: 42
func (l *List) Clone() *List {
newList := &List{
tree: avl.Tree{},
idGen: l.idGen,
}

size := l.tree.Size()
if size == 0 {
return newList
}

l.tree.IterateByOffset(0, size, func(_ string, value interface{}) bool {
newList.Append(value)
return false
})

return newList
}

// DeleteRange removes elements from startIndex (inclusive) to endIndex (exclusive).
// Returns the number of elements deleted.
//
// Example:
//
// l := list.New()
// l.Append(1, 2, 3, 4, 5)
//
// deleted := l.DeleteRange(1, 4)
// println(deleted) // Output: 3
// println(l.Range(0, l.Len())) // Output: [1 5]
func (l *List) DeleteRange(startIndex, endIndex int) int {
size := l.tree.Size()

// Normalize bounds
if startIndex < 0 {
startIndex = 0
}
if endIndex > size {
endIndex = size
}
if startIndex >= endIndex {
return 0
}

// Collect keys to delete
keysToDelete := make([]string, 0, endIndex-startIndex)
l.tree.IterateByOffset(startIndex, endIndex-startIndex, func(key string, _ interface{}) bool {
keysToDelete = append(keysToDelete, key)
return false
})

// Delete collected keys
for _, key := range keysToDelete {
l.tree.Remove(key)
}

return len(keysToDelete)
}
Loading
Loading