Skip to content

Commit

Permalink
rework indexing strategy to use an enum (#694)
Browse files Browse the repository at this point in the history
  • Loading branch information
dryajov authored Feb 7, 2024
1 parent 2cf892c commit 2fc5383
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 67 deletions.
8 changes: 4 additions & 4 deletions codex/erasure/erasure.nim
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ proc prepareEncodingData(
##

let
strategy = SteppedIndexingStrategy.new(
strategy = SteppedStrategy.init(
firstIndex = 0,
lastIndex = params.rounded - 1,
numberOfIterations = params.steps
iterations = params.steps
)
indicies = toSeq(strategy.getIndicies(step))
pendingBlocksIter = self.getPendingBlocks(manifest, indicies.filterIt(it < manifest.blocksCount))
Expand Down Expand Up @@ -179,10 +179,10 @@ proc prepareDecodingData(
##

let
strategy = SteppedIndexingStrategy.new(
strategy = SteppedStrategy.init(
firstIndex = 0,
lastIndex = encoded.blocksCount - 1,
numberOfIterations = encoded.steps
iterations = encoded.steps
)
indicies = toSeq(strategy.getIndicies(step))
pendingBlocksIter = self.getPendingBlocks(encoded, indicies)
Expand Down
90 changes: 47 additions & 43 deletions codex/indexingstrategy.nim
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import std/sequtils

import ./errors
import ./utils
import ./utils/asynciter

{.push raises: [].}

type
StrategyType* = enum
# Simplest approach:
# 0 => 0, 1, 2
# 1 => 3, 4, 5
# 2 => 6, 7, 8
LinearStrategy,

# Stepped indexing:
# 0 => 0, 3, 6
# 1 => 1, 4, 7
# 2 => 2, 5, 8
SteppedStrategy

# Representing a strategy for grouping indices (of blocks usually)
# Given an interation-count as input, will produce a seq of
# selected indices.
Expand All @@ -15,57 +26,39 @@ type
IndexingWrongIndexError* = object of IndexingError
IndexingWrongIterationsError* = object of IndexingError

IndexingStrategy* = ref object of RootObj
IndexingStrategy* = object
strategyType*: StrategyType
firstIndex*: int # Lowest index that can be returned
lastIndex*: int # Highest index that can be returned
numberOfIterations*: int # getIndices(iteration) will run from 0 ..< numberOfIterations
iterations*: int # getIndices(iteration) will run from 0 ..< iterations
step*: int

# Simplest approach:
# 0 => 0, 1, 2
# 1 => 3, 4, 5
# 2 => 6, 7, 8
LinearIndexingStrategy* = ref object of IndexingStrategy

# Stepped indexing:
# 0 => 0, 3, 6
# 1 => 1, 4, 7
# 2 => 2, 5, 8
SteppedIndexingStrategy* = ref object of IndexingStrategy

proc checkIteration(
self: IndexingStrategy,
iteration: int): void {.raises: [IndexingError].} =
if iteration >= self.numberOfIterations:
func checkIteration(self: IndexingStrategy, iteration: int): void {.raises: [IndexingError].} =
if iteration >= self.iterations:
raise newException(
IndexingError,
"Indexing iteration can't be greater than or equal to numberOfIterations.")

method getIndicies*(
self: IndexingStrategy,
iteration: int): Iter[int] {.base, raises: [IndexingError].} =
raiseAssert("Not implemented")
"Indexing iteration can't be greater than or equal to iterations.")

proc getIter(first, last, step: int): Iter[int] =
var
finish = false
cur = first
proc get(): int =

func get(): int =
result = cur
cur += step

if cur > last:
finish = true

proc isFinished(): bool =
func isFinished(): bool =
finish

Iter.new(get, isFinished)

method getIndicies*(
self: LinearIndexingStrategy,
func getLinearIndicies(
self: IndexingStrategy,
iteration: int): Iter[int] {.raises: [IndexingError].} =

self.checkIteration(iteration)

let
Expand All @@ -74,33 +67,44 @@ method getIndicies*(

getIter(first, last, 1)

method getIndicies*(
self: SteppedIndexingStrategy,
func getSteppedIndicies(
self: IndexingStrategy,
iteration: int): Iter[int] {.raises: [IndexingError].} =

self.checkIteration(iteration)

let
first = self.firstIndex + iteration
last = self.lastIndex

getIter(first, last, self.numberOfIterations)
getIter(first, last, self.iterations)

func getIndicies*(
self: IndexingStrategy,
iteration: int): Iter[int] {.raises: [IndexingError].} =

case self.strategyType
of StrategyType.LinearStrategy:
self.getLinearIndicies(iteration)
of StrategyType.SteppedStrategy:
self.getSteppedIndicies(iteration)

func init*(
strategy: StrategyType,
firstIndex, lastIndex, iterations: int): IndexingStrategy {.raises: [IndexingError].} =

proc new*(
T: type IndexingStrategy,
firstIndex, lastIndex, numberOfIterations: int): T {.raises: [IndexingError].} =
if firstIndex > lastIndex:
raise newException(
IndexingWrongIndexError,
"firstIndex (" & $firstIndex & ") can't be greater than lastIndex (" & $lastIndex & ")")

if numberOfIterations <= 0:
if iterations <= 0:
raise newException(
IndexingWrongIterationsError,
"numberOfIteration (" & $numberOfIterations & ") must be greater than zero.")
"iterations (" & $iterations & ") must be greater than zero.")

T(
IndexingStrategy(
strategyType: strategy,
firstIndex: firstIndex,
lastIndex: lastIndex,
numberOfIterations: numberOfIterations,
step: divUp((lastIndex - firstIndex), numberOfIterations))
iterations: iterations,
step: divUp((lastIndex - firstIndex), iterations))
2 changes: 1 addition & 1 deletion codex/slots/builder/builder.nim
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ proc new*(

let
strategy = if strategy.isNone:
? SteppedIndexingStrategy.new(
? SteppedStrategy.init(
0, manifest.blocksCount - 1, manifest.numSlots).catch
else:
strategy.get
Expand Down
6 changes: 3 additions & 3 deletions codex/utils/asynciter.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import pkg/questionable
import pkg/chronos

type
Function*[T, U] = proc(fut: T): U {.raises: [CatchableError], gcsafe, closure.}
IsFinished* = proc(): bool {.raises: [], gcsafe, closure.}
GenNext*[T] = proc(): T {.raises: [CatchableError], gcsafe, closure.}
Function*[T, U] = proc(fut: T): U {.raises: [CatchableError], gcsafe, noSideEffect.}
IsFinished* = proc(): bool {.raises: [], gcsafe, noSideEffect.}
GenNext*[T] = proc(): T {.raises: [CatchableError], gcsafe.}
Iter*[T] = ref object
finished: bool
next*: GenNext[T]
Expand Down
2 changes: 1 addition & 1 deletion tests/codex/slots/provingtestenv.nim
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ proc createSlotTree(self: ProvingTestEnvironment, dSlotIndex: uint64): Future[Po
let
slotSize = (bytesPerBlock * numberOfSlotBlocks).uint64
blocksInSlot = slotSize div bytesPerBlock.uint64
datasetBlockIndexingStrategy = SteppedIndexingStrategy.new(0, self.datasetBlocks.len - 1, totalNumberOfSlots)
datasetBlockIndexingStrategy = SteppedStrategy.init(0, self.datasetBlocks.len - 1, totalNumberOfSlots)
datasetBlockIndices = toSeq(datasetBlockIndexingStrategy.getIndicies(dSlotIndex.int))

let
Expand Down
8 changes: 4 additions & 4 deletions tests/codex/slots/testslotbuilder.nim
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ suite "Slot builder":

test "Should build slot hashes for all slots":
let
steppedStrategy = SteppedIndexingStrategy.new(0, numTotalBlocks - 1, numSlots)
steppedStrategy = SteppedStrategy.init(0, numTotalBlocks - 1, numSlots)
slotBuilder = SlotsBuilder.new(
localStore,
protectedManifest,
Expand All @@ -224,7 +224,7 @@ suite "Slot builder":

test "Should build slot trees for all slots":
let
steppedStrategy = SteppedIndexingStrategy.new(0, numTotalBlocks - 1, numSlots)
steppedStrategy = SteppedStrategy.init(0, numTotalBlocks - 1, numSlots)
slotBuilder = SlotsBuilder.new(
localStore,
protectedManifest,
Expand Down Expand Up @@ -272,7 +272,7 @@ suite "Slot builder":

test "Should build correct verification root":
let
steppedStrategy = SteppedIndexingStrategy.new(0, numTotalBlocks - 1, numSlots)
steppedStrategy = SteppedStrategy.init(0, numTotalBlocks - 1, numSlots)
slotBuilder = SlotsBuilder.new(
localStore,
protectedManifest,
Expand Down Expand Up @@ -301,7 +301,7 @@ suite "Slot builder":

test "Should build correct verification root manifest":
let
steppedStrategy = SteppedIndexingStrategy.new(0, numTotalBlocks - 1, numSlots)
steppedStrategy = SteppedStrategy.init(0, numTotalBlocks - 1, numSlots)
slotBuilder = SlotsBuilder.new(
localStore,
protectedManifest,
Expand Down
22 changes: 11 additions & 11 deletions tests/codex/testindexingstrategy.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ for offset in @[0, 1, 2, 100]:
firstIndex = 0 + offset
lastIndex = 12 + offset
nIters = 3
linear = LinearIndexingStrategy.new(firstIndex, lastIndex, nIters)
stepped = SteppedIndexingStrategy.new(firstIndex, lastIndex, nIters)
linear = LinearStrategy.init(firstIndex, lastIndex, nIters)
stepped = SteppedStrategy.init(firstIndex, lastIndex, nIters)

test "linear":
check:
Expand All @@ -31,32 +31,32 @@ for offset in @[0, 1, 2, 100]:

suite "Indexing strategies":
let
linear = LinearIndexingStrategy.new(0, 10, 3)
stepped = SteppedIndexingStrategy.new(0, 10, 3)
linear = LinearStrategy.init(0, 10, 3)
stepped = SteppedStrategy.init(0, 10, 3)

test "smallest range 0":
let
l = LinearIndexingStrategy.new(0, 0, 1)
s = SteppedIndexingStrategy.new(0, 0, 1)
l = LinearStrategy.init(0, 0, 1)
s = SteppedStrategy.init(0, 0, 1)
check:
toSeq(l.getIndicies(0)) == @[0]
toSeq(s.getIndicies(0)) == @[0]

test "smallest range 1":
let
l = LinearIndexingStrategy.new(0, 1, 1)
s = SteppedIndexingStrategy.new(0, 1, 1)
l = LinearStrategy.init(0, 1, 1)
s = SteppedStrategy.init(0, 1, 1)
check:
toSeq(l.getIndicies(0)) == @[0, 1]
toSeq(s.getIndicies(0)) == @[0, 1]

test "first index must be smaller than last index":
expect IndexingWrongIndexError:
discard LinearIndexingStrategy.new(10, 0, 1)
discard LinearStrategy.init(10, 0, 1)

test "numberOfIterations must be greater than zero":
test "iterations must be greater than zero":
expect IndexingWrongIterationsError:
discard LinearIndexingStrategy.new(0, 10, 0)
discard LinearStrategy.init(0, 10, 0)

test "linear - oob":
expect IndexingError:
Expand Down

0 comments on commit 2fc5383

Please sign in to comment.