rework indexing strategy to use an enum (#694)
This commit is contained in:
parent
2cf892c467
commit
2fc538337b
|
@ -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))
|
||||
|
@ -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)
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import std/sequtils
|
||||
|
||||
import ./errors
|
||||
import ./utils
|
||||
import ./utils/asynciter
|
||||
|
@ -7,6 +5,19 @@ 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.
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue