rework indexing strategy to use an enum (#694)
This commit is contained in:
parent
2cf892c467
commit
2fc538337b
|
@ -130,10 +130,10 @@ proc prepareEncodingData(
|
||||||
##
|
##
|
||||||
|
|
||||||
let
|
let
|
||||||
strategy = SteppedIndexingStrategy.new(
|
strategy = SteppedStrategy.init(
|
||||||
firstIndex = 0,
|
firstIndex = 0,
|
||||||
lastIndex = params.rounded - 1,
|
lastIndex = params.rounded - 1,
|
||||||
numberOfIterations = params.steps
|
iterations = params.steps
|
||||||
)
|
)
|
||||||
indicies = toSeq(strategy.getIndicies(step))
|
indicies = toSeq(strategy.getIndicies(step))
|
||||||
pendingBlocksIter = self.getPendingBlocks(manifest, indicies.filterIt(it < manifest.blocksCount))
|
pendingBlocksIter = self.getPendingBlocks(manifest, indicies.filterIt(it < manifest.blocksCount))
|
||||||
|
@ -179,10 +179,10 @@ proc prepareDecodingData(
|
||||||
##
|
##
|
||||||
|
|
||||||
let
|
let
|
||||||
strategy = SteppedIndexingStrategy.new(
|
strategy = SteppedStrategy.init(
|
||||||
firstIndex = 0,
|
firstIndex = 0,
|
||||||
lastIndex = encoded.blocksCount - 1,
|
lastIndex = encoded.blocksCount - 1,
|
||||||
numberOfIterations = encoded.steps
|
iterations = encoded.steps
|
||||||
)
|
)
|
||||||
indicies = toSeq(strategy.getIndicies(step))
|
indicies = toSeq(strategy.getIndicies(step))
|
||||||
pendingBlocksIter = self.getPendingBlocks(encoded, indicies)
|
pendingBlocksIter = self.getPendingBlocks(encoded, indicies)
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import std/sequtils
|
|
||||||
|
|
||||||
import ./errors
|
import ./errors
|
||||||
import ./utils
|
import ./utils
|
||||||
import ./utils/asynciter
|
import ./utils/asynciter
|
||||||
|
@ -7,6 +5,19 @@ import ./utils/asynciter
|
||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
type
|
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)
|
# Representing a strategy for grouping indices (of blocks usually)
|
||||||
# Given an interation-count as input, will produce a seq of
|
# Given an interation-count as input, will produce a seq of
|
||||||
# selected indices.
|
# selected indices.
|
||||||
|
@ -15,57 +26,39 @@ type
|
||||||
IndexingWrongIndexError* = object of IndexingError
|
IndexingWrongIndexError* = object of IndexingError
|
||||||
IndexingWrongIterationsError* = object of IndexingError
|
IndexingWrongIterationsError* = object of IndexingError
|
||||||
|
|
||||||
IndexingStrategy* = ref object of RootObj
|
IndexingStrategy* = object
|
||||||
|
strategyType*: StrategyType
|
||||||
firstIndex*: int # Lowest index that can be returned
|
firstIndex*: int # Lowest index that can be returned
|
||||||
lastIndex*: int # Highest 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
|
step*: int
|
||||||
|
|
||||||
# Simplest approach:
|
func checkIteration(self: IndexingStrategy, iteration: int): void {.raises: [IndexingError].} =
|
||||||
# 0 => 0, 1, 2
|
if iteration >= self.iterations:
|
||||||
# 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:
|
|
||||||
raise newException(
|
raise newException(
|
||||||
IndexingError,
|
IndexingError,
|
||||||
"Indexing iteration can't be greater than or equal to numberOfIterations.")
|
"Indexing iteration can't be greater than or equal to iterations.")
|
||||||
|
|
||||||
method getIndicies*(
|
|
||||||
self: IndexingStrategy,
|
|
||||||
iteration: int): Iter[int] {.base, raises: [IndexingError].} =
|
|
||||||
raiseAssert("Not implemented")
|
|
||||||
|
|
||||||
proc getIter(first, last, step: int): Iter[int] =
|
proc getIter(first, last, step: int): Iter[int] =
|
||||||
var
|
var
|
||||||
finish = false
|
finish = false
|
||||||
cur = first
|
cur = first
|
||||||
proc get(): int =
|
|
||||||
|
func get(): int =
|
||||||
result = cur
|
result = cur
|
||||||
cur += step
|
cur += step
|
||||||
|
|
||||||
if cur > last:
|
if cur > last:
|
||||||
finish = true
|
finish = true
|
||||||
|
|
||||||
proc isFinished(): bool =
|
func isFinished(): bool =
|
||||||
finish
|
finish
|
||||||
|
|
||||||
Iter.new(get, isFinished)
|
Iter.new(get, isFinished)
|
||||||
|
|
||||||
method getIndicies*(
|
func getLinearIndicies(
|
||||||
self: LinearIndexingStrategy,
|
self: IndexingStrategy,
|
||||||
iteration: int): Iter[int] {.raises: [IndexingError].} =
|
iteration: int): Iter[int] {.raises: [IndexingError].} =
|
||||||
|
|
||||||
self.checkIteration(iteration)
|
self.checkIteration(iteration)
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -74,33 +67,44 @@ method getIndicies*(
|
||||||
|
|
||||||
getIter(first, last, 1)
|
getIter(first, last, 1)
|
||||||
|
|
||||||
method getIndicies*(
|
func getSteppedIndicies(
|
||||||
self: SteppedIndexingStrategy,
|
self: IndexingStrategy,
|
||||||
iteration: int): Iter[int] {.raises: [IndexingError].} =
|
iteration: int): Iter[int] {.raises: [IndexingError].} =
|
||||||
|
|
||||||
self.checkIteration(iteration)
|
self.checkIteration(iteration)
|
||||||
|
|
||||||
let
|
let
|
||||||
first = self.firstIndex + iteration
|
first = self.firstIndex + iteration
|
||||||
last = self.lastIndex
|
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:
|
if firstIndex > lastIndex:
|
||||||
raise newException(
|
raise newException(
|
||||||
IndexingWrongIndexError,
|
IndexingWrongIndexError,
|
||||||
"firstIndex (" & $firstIndex & ") can't be greater than lastIndex (" & $lastIndex & ")")
|
"firstIndex (" & $firstIndex & ") can't be greater than lastIndex (" & $lastIndex & ")")
|
||||||
|
|
||||||
if numberOfIterations <= 0:
|
if iterations <= 0:
|
||||||
raise newException(
|
raise newException(
|
||||||
IndexingWrongIterationsError,
|
IndexingWrongIterationsError,
|
||||||
"numberOfIteration (" & $numberOfIterations & ") must be greater than zero.")
|
"iterations (" & $iterations & ") must be greater than zero.")
|
||||||
|
|
||||||
T(
|
IndexingStrategy(
|
||||||
|
strategyType: strategy,
|
||||||
firstIndex: firstIndex,
|
firstIndex: firstIndex,
|
||||||
lastIndex: lastIndex,
|
lastIndex: lastIndex,
|
||||||
numberOfIterations: numberOfIterations,
|
iterations: iterations,
|
||||||
step: divUp((lastIndex - firstIndex), numberOfIterations))
|
step: divUp((lastIndex - firstIndex), iterations))
|
||||||
|
|
|
@ -341,7 +341,7 @@ proc new*(
|
||||||
|
|
||||||
let
|
let
|
||||||
strategy = if strategy.isNone:
|
strategy = if strategy.isNone:
|
||||||
? SteppedIndexingStrategy.new(
|
? SteppedStrategy.init(
|
||||||
0, manifest.blocksCount - 1, manifest.numSlots).catch
|
0, manifest.blocksCount - 1, manifest.numSlots).catch
|
||||||
else:
|
else:
|
||||||
strategy.get
|
strategy.get
|
||||||
|
|
|
@ -4,9 +4,9 @@ import pkg/questionable
|
||||||
import pkg/chronos
|
import pkg/chronos
|
||||||
|
|
||||||
type
|
type
|
||||||
Function*[T, U] = proc(fut: T): U {.raises: [CatchableError], gcsafe, closure.}
|
Function*[T, U] = proc(fut: T): U {.raises: [CatchableError], gcsafe, noSideEffect.}
|
||||||
IsFinished* = proc(): bool {.raises: [], gcsafe, closure.}
|
IsFinished* = proc(): bool {.raises: [], gcsafe, noSideEffect.}
|
||||||
GenNext*[T] = proc(): T {.raises: [CatchableError], gcsafe, closure.}
|
GenNext*[T] = proc(): T {.raises: [CatchableError], gcsafe.}
|
||||||
Iter*[T] = ref object
|
Iter*[T] = ref object
|
||||||
finished: bool
|
finished: bool
|
||||||
next*: GenNext[T]
|
next*: GenNext[T]
|
||||||
|
|
|
@ -83,7 +83,7 @@ proc createSlotTree(self: ProvingTestEnvironment, dSlotIndex: uint64): Future[Po
|
||||||
let
|
let
|
||||||
slotSize = (bytesPerBlock * numberOfSlotBlocks).uint64
|
slotSize = (bytesPerBlock * numberOfSlotBlocks).uint64
|
||||||
blocksInSlot = slotSize div bytesPerBlock.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))
|
datasetBlockIndices = toSeq(datasetBlockIndexingStrategy.getIndicies(dSlotIndex.int))
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
|
@ -201,7 +201,7 @@ suite "Slot builder":
|
||||||
|
|
||||||
test "Should build slot hashes for all slots":
|
test "Should build slot hashes for all slots":
|
||||||
let
|
let
|
||||||
steppedStrategy = SteppedIndexingStrategy.new(0, numTotalBlocks - 1, numSlots)
|
steppedStrategy = SteppedStrategy.init(0, numTotalBlocks - 1, numSlots)
|
||||||
slotBuilder = SlotsBuilder.new(
|
slotBuilder = SlotsBuilder.new(
|
||||||
localStore,
|
localStore,
|
||||||
protectedManifest,
|
protectedManifest,
|
||||||
|
@ -224,7 +224,7 @@ suite "Slot builder":
|
||||||
|
|
||||||
test "Should build slot trees for all slots":
|
test "Should build slot trees for all slots":
|
||||||
let
|
let
|
||||||
steppedStrategy = SteppedIndexingStrategy.new(0, numTotalBlocks - 1, numSlots)
|
steppedStrategy = SteppedStrategy.init(0, numTotalBlocks - 1, numSlots)
|
||||||
slotBuilder = SlotsBuilder.new(
|
slotBuilder = SlotsBuilder.new(
|
||||||
localStore,
|
localStore,
|
||||||
protectedManifest,
|
protectedManifest,
|
||||||
|
@ -272,7 +272,7 @@ suite "Slot builder":
|
||||||
|
|
||||||
test "Should build correct verification root":
|
test "Should build correct verification root":
|
||||||
let
|
let
|
||||||
steppedStrategy = SteppedIndexingStrategy.new(0, numTotalBlocks - 1, numSlots)
|
steppedStrategy = SteppedStrategy.init(0, numTotalBlocks - 1, numSlots)
|
||||||
slotBuilder = SlotsBuilder.new(
|
slotBuilder = SlotsBuilder.new(
|
||||||
localStore,
|
localStore,
|
||||||
protectedManifest,
|
protectedManifest,
|
||||||
|
@ -301,7 +301,7 @@ suite "Slot builder":
|
||||||
|
|
||||||
test "Should build correct verification root manifest":
|
test "Should build correct verification root manifest":
|
||||||
let
|
let
|
||||||
steppedStrategy = SteppedIndexingStrategy.new(0, numTotalBlocks - 1, numSlots)
|
steppedStrategy = SteppedStrategy.init(0, numTotalBlocks - 1, numSlots)
|
||||||
slotBuilder = SlotsBuilder.new(
|
slotBuilder = SlotsBuilder.new(
|
||||||
localStore,
|
localStore,
|
||||||
protectedManifest,
|
protectedManifest,
|
||||||
|
|
|
@ -14,8 +14,8 @@ for offset in @[0, 1, 2, 100]:
|
||||||
firstIndex = 0 + offset
|
firstIndex = 0 + offset
|
||||||
lastIndex = 12 + offset
|
lastIndex = 12 + offset
|
||||||
nIters = 3
|
nIters = 3
|
||||||
linear = LinearIndexingStrategy.new(firstIndex, lastIndex, nIters)
|
linear = LinearStrategy.init(firstIndex, lastIndex, nIters)
|
||||||
stepped = SteppedIndexingStrategy.new(firstIndex, lastIndex, nIters)
|
stepped = SteppedStrategy.init(firstIndex, lastIndex, nIters)
|
||||||
|
|
||||||
test "linear":
|
test "linear":
|
||||||
check:
|
check:
|
||||||
|
@ -31,32 +31,32 @@ for offset in @[0, 1, 2, 100]:
|
||||||
|
|
||||||
suite "Indexing strategies":
|
suite "Indexing strategies":
|
||||||
let
|
let
|
||||||
linear = LinearIndexingStrategy.new(0, 10, 3)
|
linear = LinearStrategy.init(0, 10, 3)
|
||||||
stepped = SteppedIndexingStrategy.new(0, 10, 3)
|
stepped = SteppedStrategy.init(0, 10, 3)
|
||||||
|
|
||||||
test "smallest range 0":
|
test "smallest range 0":
|
||||||
let
|
let
|
||||||
l = LinearIndexingStrategy.new(0, 0, 1)
|
l = LinearStrategy.init(0, 0, 1)
|
||||||
s = SteppedIndexingStrategy.new(0, 0, 1)
|
s = SteppedStrategy.init(0, 0, 1)
|
||||||
check:
|
check:
|
||||||
toSeq(l.getIndicies(0)) == @[0]
|
toSeq(l.getIndicies(0)) == @[0]
|
||||||
toSeq(s.getIndicies(0)) == @[0]
|
toSeq(s.getIndicies(0)) == @[0]
|
||||||
|
|
||||||
test "smallest range 1":
|
test "smallest range 1":
|
||||||
let
|
let
|
||||||
l = LinearIndexingStrategy.new(0, 1, 1)
|
l = LinearStrategy.init(0, 1, 1)
|
||||||
s = SteppedIndexingStrategy.new(0, 1, 1)
|
s = SteppedStrategy.init(0, 1, 1)
|
||||||
check:
|
check:
|
||||||
toSeq(l.getIndicies(0)) == @[0, 1]
|
toSeq(l.getIndicies(0)) == @[0, 1]
|
||||||
toSeq(s.getIndicies(0)) == @[0, 1]
|
toSeq(s.getIndicies(0)) == @[0, 1]
|
||||||
|
|
||||||
test "first index must be smaller than last index":
|
test "first index must be smaller than last index":
|
||||||
expect IndexingWrongIndexError:
|
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:
|
expect IndexingWrongIterationsError:
|
||||||
discard LinearIndexingStrategy.new(0, 10, 0)
|
discard LinearStrategy.init(0, 10, 0)
|
||||||
|
|
||||||
test "linear - oob":
|
test "linear - oob":
|
||||||
expect IndexingError:
|
expect IndexingError:
|
||||||
|
|
Loading…
Reference in New Issue