···
pub struct RocksStorage {
pub db: Arc<DBWithThreadMode<MultiThreaded>>, // TODO: mov seqs here (concat merge op will be fun)
62
-
did_id_table: IdTable<Did, DidIdValue, true>,
63
-
target_id_table: IdTable<TargetKey, TargetId, true>,
62
+
did_id_table: IdTable<Did, DidIdValue>,
63
+
target_id_table: IdTable<TargetKey, TargetId>,
backup_task: Arc<Option<thread::JoinHandle<Result<()>>>>,
···
fn cf_descriptor(&self) -> ColumnFamilyDescriptor {
ColumnFamilyDescriptor::new(&self.name, rocks_opts_base())
91
-
fn init<const WITH_REVERSE: bool>(
93
-
db: &DBWithThreadMode<MultiThreaded>,
94
-
) -> Result<IdTable<Orig, IdVal, WITH_REVERSE>> {
91
+
fn init(self, db: &DBWithThreadMode<MultiThreaded>) -> Result<IdTable<Orig, IdVal>> {
if db.cf_handle(&self.name).is_none() {
bail!("failed to get cf handle from db -- was the db open with our .cf_descriptor()?");
···
125
-
struct IdTable<Orig, IdVal: IdTableValue, const WITH_REVERSE: bool>
122
+
struct IdTable<Orig, IdVal: IdTableValue>
for<'a> &'a Orig: AsRocksKey,
···
base: IdTableBase<Orig, IdVal>,
133
-
impl<Orig: Clone, IdVal: IdTableValue, const WITH_REVERSE: bool> IdTable<Orig, IdVal, WITH_REVERSE>
130
+
impl<Orig: Clone, IdVal: IdTableValue> IdTable<Orig, IdVal>
for<'v> &'v IdVal: AsRocksValue,
···
fn estimate_count(&self) -> u64 {
self.base.id_seq.load(Ordering::SeqCst) - 1 // -1 because seq zero is reserved
188
-
impl<Orig: Clone, IdVal: IdTableValue> IdTable<Orig, IdVal, true>
190
-
Orig: KeyFromRocks,
191
-
for<'v> &'v IdVal: AsRocksValue,
192
-
for<'k> &'k Orig: AsRocksKey,
db: &DBWithThreadMode<MultiThreaded>,
···
221
-
impl<Orig: Clone, IdVal: IdTableValue> IdTable<Orig, IdVal, false>
223
-
Orig: KeyFromRocks,
224
-
for<'v> &'v IdVal: AsRocksValue,
225
-
for<'k> &'k Orig: AsRocksKey,
227
-
fn get_or_create_id_val(
229
-
db: &DBWithThreadMode<MultiThreaded>,
230
-
batch: &mut WriteBatch,
232
-
) -> Result<IdVal> {
233
-
let cf = db.cf_handle(&self.base.name).unwrap();
234
-
self.__get_or_create_id_val(&cf, db, batch, orig)
impl IdTableValue for DidIdValue {
···
fn open_readmode(path: impl AsRef<Path>, readonly: bool) -> Result<Self> {
266
-
let did_id_table = IdTable::<_, _, true>::setup(DID_IDS_CF);
267
-
let target_id_table = IdTable::<_, _, true>::setup(TARGET_IDS_CF);
242
+
let did_id_table = IdTable::setup(DID_IDS_CF);
243
+
let target_id_table = IdTable::setup(TARGET_IDS_CF);
···
let filter_did_ids: HashMap<DidId, bool> = filter_dids
.filter_map(|did| self.did_id_table.get_id_val(&self.db, did).transpose())
.collect::<Result<Vec<DidIdValue>>>()?
.map(|DidIdValue(id, active)| (id, active))
867
-
let filter_to_target_ids = filter_to_targets
869
-
.filter_map(|target| {
870
-
self.target_id_table
873
-
&TargetKey(Target(target.to_string()), collection.clone(), path.clone()),
877
-
.collect::<Result<HashSet<TargetId>>>()?;
843
+
// stored targets are keyed by triples of (target, collection, path).
844
+
// target filtering only consideres the target itself, so we actually
845
+
// need to do a prefix iteration of all target ids for this target and
847
+
// i *think* the number of keys at a target prefix should usually be
848
+
// pretty small, so this is hopefully fine. but if it turns out to be
849
+
// large, we can push this filtering back into the main links loop and
850
+
// do forward db queries per backlink to get the raw target back out.
851
+
let mut filter_to_target_ids: HashSet<TargetId> = HashSet::new();
852
+
for t in filter_to_targets {
853
+
for (_, target_id) in self.iter_targets_for_target(&Target(t.to_string())) {
854
+
filter_to_target_ids.insert(target_id);
let linkers = self.get_target_linkers(&target_id)?;
···
// (this check continues after the did-lookup, which we have to do)
let page_is_full = grouped_counts.len() as u64 >= limit;
926
-
let current_max = grouped_counts.keys().rev().next().unwrap(); // limit should be non-zero bleh
905
+
let current_max = grouped_counts.keys().next_back().unwrap(); // limit should be non-zero bleh
if fwd_target > *current_max {
···
955
-
entry.1.insert(did_id.clone());
934
+
entry.1.insert(did_id);
grouped_counts.pop_last();
···
let mut items: Vec<(String, u64, u64)> = Vec::with_capacity(grouped_counts.len());
for (target_id, (n, dids)) in &grouped_counts {
964
-
let Some(target) = self.target_id_table.get_val_from_id(&self.db, target_id.0)? else {
943
+
let Some(target) = self
945
+
.get_val_from_id(&self.db, target_id.0)?
eprintln!("failed to look up target from target_id {target_id:?}");
968
-
items.push((target.0.0, *n, dids.len() as u64));
950
+
items.push((target.0 .0, *n, dids.len() as u64));
let next = if grouped_counts.len() as u64 >= limit {
// yeah.... it's a number saved as a string......sorry
.map(|k| format!("{}", k.0))