diff options
author | Koni Marti <koni.marti@gmail.com> | 2022-10-20 16:43:42 +0200 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-10-27 22:44:39 +0200 |
commit | 206665a2d97106722a6b32e24a504863040ca515 (patch) | |
tree | a2921d527dc04b7a4a0bc6ff3718bbdea4a8aa06 /lib/iterator/index.go | |
parent | c5face0b6f922781f1d2ae754c00fdee6c58af20 (diff) | |
download | aerc-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.go | 51 |
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) +} |