aboutsummaryrefslogtreecommitdiffstats
path: root/lib/iterator/index.go
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2022-10-20 16:43:42 +0200
committerRobin Jarry <robin@jarry.cc>2022-10-27 22:44:39 +0200
commit206665a2d97106722a6b32e24a504863040ca515 (patch)
treea2921d527dc04b7a4a0bc6ff3718bbdea4a8aa06 /lib/iterator/index.go
parentc5face0b6f922781f1d2ae754c00fdee6c58af20 (diff)
downloadaerc-206665a2d97106722a6b32e24a504863040ca515.tar.gz
iterator: add functionality to move indices
Extract the index acrobatics from the message store and move it to iterator package for re-use and to add unit tests. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'lib/iterator/index.go')
-rw-r--r--lib/iterator/index.go51
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/iterator/index.go b/lib/iterator/index.go
new file mode 100644
index 00000000..dd660052
--- /dev/null
+++ b/lib/iterator/index.go
@@ -0,0 +1,51 @@
+package iterator
+
+// IndexProvider implements a subset of the Interator interface
+type IndexProvider interface {
+ StartIndex() int
+ EndIndex() int
+}
+
+// FixBounds will force the index i to either its lower- or upper-bound value
+// if out-of-bound
+func FixBounds(i, lower, upper int) int {
+ switch {
+ case i > upper:
+ i = upper
+ case i < lower:
+ i = lower
+ }
+ return i
+}
+
+// WrapBounds will wrap the index i around its upper- or lower-bound if
+// out-of-bound
+func WrapBounds(i, lower, upper int) int {
+ switch {
+ case i > upper:
+ i = lower + (i-upper-1)%upper
+ case i < lower:
+ i = upper - (lower-i-1)%upper
+ }
+ return i
+}
+
+type BoundsCheckFunc func(int, int, int) int
+
+// MoveIndex moves the index variable idx forward by delta steps and ensures
+// that the boundary policy as defined by the CheckBoundsFunc is enforced.
+//
+// If CheckBoundsFunc is nil, fix boundary checks are performed.
+func MoveIndex(idx, delta int, indexer IndexProvider, cb BoundsCheckFunc) int {
+ lower, upper := indexer.StartIndex(), indexer.EndIndex()
+ sign := 1
+ if upper < lower {
+ lower, upper = upper, lower
+ sign = -1
+ }
+ result := idx + sign*delta
+ if cb == nil {
+ return FixBounds(result, lower, upper)
+ }
+ return cb(result, lower, upper)
+}