nimbus-eth1/nimbus/db/aristo/aristo_journal/journal_get.nim

132 lines
3.8 KiB
Nim

# nimbus-eth1
# Copyright (c) 2023-2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed
# except according to those terms.
import
std/options,
eth/common,
results,
".."/[aristo_desc, aristo_desc/desc_backend],
./journal_scheduler
# ------------------------------------------------------------------------------
# Public functions
# ------------------------------------------------------------------------------
proc journalGetInx*(
be: BackendRef;
fid: Option[FilterID];
earlierOK = false;
): Result[JournalInx,AristoError] =
## If there is some argument `fid`, find the filter on the journal with ID
## not larger than `fid` (i e. the resulting filter must not be more recent.)
##
## If the argument `earlierOK` is passed `false`, the function succeeds only
## if the filter ID of the returned filter is equal to the argument `fid`.
##
## In case that there is no argument `fid`, the filter with the smallest
## filter ID (i.e. the oldest filter) is returned. here, the argument
## `earlierOK` is ignored.
##
if be.journal.isNil:
return err(FilQuSchedDisabled)
var cache = (QueueID(0),FilterRef(nil)) # Avoids double lookup for last entry
proc qid2fid(qid: QueueID): Result[FilterID,void] =
if qid == cache[0]: # Avoids double lookup for last entry
return ok cache[1].fid
let fil = be.getFilFn(qid).valueOr:
return err()
cache = (qid,fil)
ok fil.fid
let qid = block:
if fid.isNone:
# Get oldest filter
be.journal[^1]
else:
# Find filter with ID not smaller than `fid`
be.journal.le(fid.unsafeGet, qid2fid, forceEQ = not earlierOK)
if not qid.isValid:
return err(FilFilterNotFound)
var fip: JournalInx
fip.fil = block:
if cache[0] == qid:
cache[1]
else:
be.getFilFn(qid).valueOr:
return err(error)
fip.inx = be.journal[qid]
if fip.inx < 0:
return err(FilInxByQidFailed)
ok fip
proc journalGetFilter*(
be: BackendRef;
inx: int;
): Result[FilterRef,AristoError] =
## Fetch filter from journal where the argument `inx` relates to the age
## starting with `0` for the most recent.
##
if be.journal.isNil:
return err(FilQuSchedDisabled)
let qid = be.journal[inx]
if qid.isValid:
let fil = be.getFilFn(qid).valueOr:
return err(error)
return ok(fil)
err(FilFilterNotFound)
proc journalGetOverlap*(
be: BackendRef;
filter: FilterRef;
): int =
## This function will find the overlap of an argument `filter` which is
## composed by some recent filter slots from the journal.
##
## The function returns the number of most recent journal filters that are
## reverted by the argument `filter`. This requires that `src`, `trg`, and
## `fid` of the argument `filter` is properly calculated (e.g. using
## `journalOpsFetchSlots()`.)
##
# Check against the top-fifo entry.
let qid = be.journal[0]
if not qid.isValid:
return 0
let top = be.getFilFn(qid).valueOr:
return 0
# The `filter` must match the `top`
if filter.src != top.src:
return 0
# Does the filter revert the fitst entry?
if filter.trg == top.trg:
return 1
# Check against some stored filter IDs
if filter.isValid:
let fp = be.journalGetInx(some(filter.fid), earlierOK=true).valueOr:
return 0
if filter.trg == fp.fil.trg:
return 1 + fp.inx
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------