Skip to content

Commit

Permalink
chore: fixup
Browse files Browse the repository at this point in the history
Signed-off-by: moul <[email protected]>
  • Loading branch information
moul committed Jan 15, 2025
1 parent d214d18 commit 2e11d2e
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 76 deletions.
47 changes: 36 additions & 11 deletions examples/gno.land/p/demo/avl/pager/pager.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,55 @@ import (

// NewPager creates a new Pager with default values.
func NewPager(tree avl.ITree, defaultPageSize int, reversed bool) *pageable.Pager {
wrappedTree := NewAVLWrapper(tree)
wrappedTree := NewWrapper(tree)
return pageable.NewPager(wrappedTree, defaultPageSize, reversed)
}

// AVLWrapper adapts an avl.ITree to implement Pageable
type AVLWrapper struct {
// Wrapper adapts an avl.ITree to implement Pageable
type Wrapper struct {
tree avl.ITree
}

func NewAVLWrapper(tree avl.ITree) *AVLWrapper {
return &AVLWrapper{tree: tree}
func NewWrapper(tree avl.ITree) *Wrapper {
return &Wrapper{tree: tree}
}

func (w *AVLWrapper) Size() int {
func (w *Wrapper) Size() int {
return w.tree.Size()
}

func (w *AVLWrapper) IterateByOffset(offset int, count int, cb func(index interface{}, value interface{}) bool) bool {
if count < 0 {
return w.tree.ReverseIterateByOffset(offset, count, func(key string, value interface{}) bool {
return cb(key, value)
})
func (w *Wrapper) IterateByOffset(offset int, count int, cb func(index interface{}, value interface{}) bool) bool {
if count == 0 {
return false
}

size := w.tree.Size()
if size == 0 {
return false
}

if offset >= size {
return false
}

// Use the tree's IterateByOffset with the full count
// (positive for forward, negative for reverse)
return w.tree.IterateByOffset(offset, count, func(key string, value interface{}) bool {
return cb(key, value)
})
}

// Helper functions
func max(a, b int) int {
if a > b {
return a
}
return b
}

func min(a, b int) int {
if a < b {
return a
}
return b
}
86 changes: 43 additions & 43 deletions examples/gno.land/p/demo/avl/pager/z_filetest.gno
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func main() {

println(ufmt.Sprintf("## Page %d of %d", page.PageNumber, page.TotalPages))
for idx, item := range page.Items {
println(ufmt.Sprintf("- idx=%d key=%s value=%d", idx, item.Key, item.Value))
println(ufmt.Sprintf("- idx=%d index=%s value=%d", idx, item.Index, item.Value))
}
println(page.Picker())
println()
Expand All @@ -38,63 +38,63 @@ func main() {
// _0_ | [1](?page=1) | [2](?page=2) | … | [6](?page=6)
//
// ## Page 1 of 6
// - idx=0 key=0000001 value=0
// - idx=1 key=0000002 value=1
// - idx=2 key=0000003 value=2
// - idx=3 key=0000004 value=3
// - idx=4 key=0000005 value=4
// - idx=5 key=0000006 value=5
// - idx=6 key=0000007 value=6
// - idx=0 index=0000001 value=0
// - idx=1 index=0000002 value=1
// - idx=2 index=0000003 value=2
// - idx=3 index=0000004 value=3
// - idx=4 index=0000005 value=4
// - idx=5 index=0000006 value=5
// - idx=6 index=0000007 value=6
// **1** | [2](?page=2) | [3](?page=3) | … | [6](?page=6)
//
// ## Page 2 of 6
// - idx=0 key=0000008 value=7
// - idx=1 key=0000009 value=8
// - idx=2 key=000000a value=9
// - idx=3 key=000000b value=10
// - idx=4 key=000000c value=11
// - idx=5 key=000000d value=12
// - idx=6 key=000000e value=13
// - idx=0 index=0000008 value=7
// - idx=1 index=0000009 value=8
// - idx=2 index=000000a value=9
// - idx=3 index=000000b value=10
// - idx=4 index=000000c value=11
// - idx=5 index=000000d value=12
// - idx=6 index=000000e value=13
// [1](?page=1) | **2** | [3](?page=3) | [4](?page=4) | … | [6](?page=6)
//
// ## Page 3 of 6
// - idx=0 key=000000f value=14
// - idx=1 key=000000g value=15
// - idx=2 key=000000h value=16
// - idx=3 key=000000j value=17
// - idx=4 key=000000k value=18
// - idx=5 key=000000m value=19
// - idx=6 key=000000n value=20
// - idx=0 index=000000f value=14
// - idx=1 index=000000g value=15
// - idx=2 index=000000h value=16
// - idx=3 index=000000j value=17
// - idx=4 index=000000k value=18
// - idx=5 index=000000m value=19
// - idx=6 index=000000n value=20
// [1](?page=1) | [2](?page=2) | **3** | [4](?page=4) | [5](?page=5) | [6](?page=6)
//
// ## Page 4 of 6
// - idx=0 key=000000p value=21
// - idx=1 key=000000q value=22
// - idx=2 key=000000r value=23
// - idx=3 key=000000s value=24
// - idx=4 key=000000t value=25
// - idx=5 key=000000v value=26
// - idx=6 key=000000w value=27
// - idx=0 index=000000p value=21
// - idx=1 index=000000q value=22
// - idx=2 index=000000r value=23
// - idx=3 index=000000s value=24
// - idx=4 index=000000t value=25
// - idx=5 index=000000v value=26
// - idx=6 index=000000w value=27
// [1](?page=1) | [2](?page=2) | [3](?page=3) | **4** | [5](?page=5) | [6](?page=6)
//
// ## Page 5 of 6
// - idx=0 key=000000x value=28
// - idx=1 key=000000y value=29
// - idx=2 key=000000z value=30
// - idx=3 key=0000010 value=31
// - idx=4 key=0000011 value=32
// - idx=5 key=0000012 value=33
// - idx=6 key=0000013 value=34
// - idx=0 index=000000x value=28
// - idx=1 index=000000y value=29
// - idx=2 index=000000z value=30
// - idx=3 index=0000010 value=31
// - idx=4 index=0000011 value=32
// - idx=5 index=0000012 value=33
// - idx=6 index=0000013 value=34
// [1](?page=1) | … | [3](?page=3) | [4](?page=4) | **5** | [6](?page=6)
//
// ## Page 6 of 6
// - idx=0 key=0000014 value=35
// - idx=1 key=0000015 value=36
// - idx=2 key=0000016 value=37
// - idx=3 key=0000017 value=38
// - idx=4 key=0000018 value=39
// - idx=5 key=0000019 value=40
// - idx=6 key=000001a value=41
// - idx=0 index=0000014 value=35
// - idx=1 index=0000015 value=36
// - idx=2 index=0000016 value=37
// - idx=3 index=0000017 value=38
// - idx=4 index=0000018 value=39
// - idx=5 index=0000019 value=40
// - idx=6 index=000001a value=41
// [1](?page=1) | … | [4](?page=4) | [5](?page=5) | **6**
//
// ## Page 7 of 6
Expand Down
55 changes: 34 additions & 21 deletions examples/gno.land/p/moul/pageable/pageable.gno
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
// Package pageable provides a generic pagination system
// Package pageable implements a flexible pagination system that can be used with any data structure
// that implements the Pageable interface. It provides functionality for:
//
// - Paginating through collections of items
// - Configurable page sizes
// - Forward and reverse iteration
// - URL query parameter parsing
// - Markdown-based pagination UI
//
// This package is currently used by:
// - gno.land/p/demo/avl/pager: implementation for AVL trees.
// - gno.land/p/moul/ulist/pager: implementation for ulist
package pageable

import (
Expand All @@ -9,13 +20,26 @@ import (
"gno.land/p/demo/ufmt"
)

// Pageable defines the minimal interface required for pagination
// Pageable defines the minimal interface required for pagination.
// This interface is intentionally lightweight, requiring only two methods.
// While some data structures (like AVL trees) might have separate methods for forward
// and reverse iteration, this interface consolidates both directions into a single
// IterateByOffset method. It's the responsibility of the implementing wrapper to
// handle the direction logic internally based on the offset and count parameters.
type Pageable interface {
// Size returns the total number of items
Size() int

// IterateByOffset performs iteration starting from offset for count elements
// The callback receives an index and a value, returns true to stop iteration
// IterateByOffset performs iteration starting from offset for count elements.
// The callback receives an index and a value, returns true to stop iteration.
//
// For reverse iteration, the implementation should handle the direction internally
// by adjusting how it interprets the offset and count parameters. For example:
// - In forward mode: offset 0, count 5 would return items [0,1,2,3,4]
// - In reverse mode: offset 0, count 5 would return items [4,3,2,1,0]
//
// This approach allows the interface to remain simple while supporting
// bidirectional iteration through the implementation layer.
IterateByOffset(offset int, count int, cb func(index interface{}, value interface{}) bool) bool
}

Expand Down Expand Up @@ -120,23 +144,12 @@ func (p *Pager) GetPageWithSize(pageNumber, pageSize int) *Page {
// Collect items for the current page
var items []Item
if p.Reversed {
// For reversed order, iterate from the end of the array
if offset == 0 && iterCount == 1 {
// Special case for last partial page
p.Source.IterateByOffset(0, 1, func(index interface{}, value interface{}) bool {
items = append(items, Item{Index: index, Value: value})
return true
})
} else {
startIndex := page.TotalItems - offset - 1
endIndex := startIndex - iterCount + 1
for i := startIndex; i >= endIndex && i >= 0; i-- {
p.Source.IterateByOffset(i, 1, func(index interface{}, value interface{}) bool {
items = append(items, Item{Index: index, Value: value})
return true
})
}
}
// For reversed order, use negative count to indicate reverse iteration
offset = page.TotalItems - offset - iterCount
p.Source.IterateByOffset(offset, -iterCount, func(index interface{}, value interface{}) bool {
items = append(items, Item{Index: index, Value: value})
return false
})
} else {
p.Source.IterateByOffset(offset, iterCount, func(index interface{}, value interface{}) bool {
items = append(items, Item{Index: index, Value: value})
Expand Down
2 changes: 1 addition & 1 deletion examples/gno.land/p/moul/pageable/pageable_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func TestReversedPager(t *testing.T) {
}

// Check if items are in reverse order
if page.Items[0].Value.(int) != 2 || page.Items[1].Value.(int) != 1 {
if page.Items[0].Value.(int) != 5 || page.Items[1].Value.(int) != 4 {
t.Errorf("items not in reverse order: got %v", page.Items)
}
}
Expand Down

0 comments on commit 2e11d2e

Please sign in to comment.