Add tc_index and ac_index (not utilized yet)

This commit is contained in:
Mike Dilger 2024-03-05 09:32:33 +13:00
parent e19174f124
commit 6ef2ebc871
2 changed files with 116 additions and 2 deletions

View File

@ -2,7 +2,7 @@ use super::Store;
use crate::error::Error;
use heed::RwTxn;
pub const CURRENT_MIGRATION_LEVEL: u32 = 1;
pub const CURRENT_MIGRATION_LEVEL: u32 = 2;
impl Store {
pub fn migrate(&self) -> Result<(), Error> {
@ -38,14 +38,15 @@ impl Store {
log::info!("Migrating database to {}", level);
match level {
1 => self.migrate_to_1(txn)?,
2 => self.migrate_to_2(txn)?,
_ => panic!("Unknown migration level {level}"),
}
Ok(())
}
// Populate ci_index
fn migrate_to_1(&self, txn: &mut RwTxn<'_>) -> Result<(), Error> {
// Build ci database
let loop_txn = self.env.read_txn()?;
let iter = self.i_index.iter(&loop_txn)?;
for result in iter {
@ -62,4 +63,43 @@ impl Store {
Ok(())
}
// Populate tc_index and ac_index
fn migrate_to_2(&self, txn: &mut RwTxn<'_>) -> Result<(), Error> {
let loop_txn = self.env.read_txn()?;
let iter = self.i_index.iter(&loop_txn)?;
for result in iter {
let (_key, offset) = result?;
if let Some(event) = self.events.get_event_by_offset(offset)? {
// Add to ac_index
self.ac_index.put(
txn,
&Self::key_ac_index(event.pubkey(), event.created_at(), event.id()),
&offset,
)?;
// Add to tc_index
for mut tsi in event.tags()?.iter() {
if let Some(tagname) = tsi.next() {
if tagname.len() == 1 {
if let Some(tagvalue) = tsi.next() {
self.tc_index.put(
txn,
&Self::key_tc_index(
tagname[0],
tagvalue,
event.created_at(),
event.id(),
),
&offset,
)?;
}
}
}
}
}
}
Ok(())
}
}

View File

@ -23,6 +23,8 @@ pub struct Store {
env: Env,
i_index: Database<UnalignedSlice<u8>, OwnedType<usize>>,
ci_index: Database<UnalignedSlice<u8>, OwnedType<usize>>,
tc_index: Database<UnalignedSlice<u8>, OwnedType<usize>>,
ac_index: Database<UnalignedSlice<u8>, OwnedType<usize>>,
akc_index: Database<UnalignedSlice<u8>, OwnedType<usize>>,
atc_index: Database<UnalignedSlice<u8>, OwnedType<usize>>,
ktc_index: Database<UnalignedSlice<u8>, OwnedType<usize>>,
@ -71,6 +73,16 @@ impl Store {
.types::<UnalignedSlice<u8>, OwnedType<usize>>()
.name("ci")
.create(&mut txn)?;
let tc_index = env
.database_options()
.types::<UnalignedSlice<u8>, OwnedType<usize>>()
.name("tci")
.create(&mut txn)?;
let ac_index = env
.database_options()
.types::<UnalignedSlice<u8>, OwnedType<usize>>()
.name("aci")
.create(&mut txn)?;
let akc_index = env
.database_options()
.types::<UnalignedSlice<u8>, OwnedType<usize>>()
@ -123,6 +135,8 @@ impl Store {
env,
i_index,
ci_index,
tc_index,
ac_index,
akc_index,
atc_index,
ktc_index,
@ -542,11 +556,29 @@ impl Store {
&offset,
)?;
self.ac_index.put(
txn,
&Self::key_ac_index(event.pubkey(), event.created_at(), event.id()),
&offset,
)?;
for mut tsi in event.tags()?.iter() {
if let Some(tagname) = tsi.next() {
// FIXME make sure it is a letter too
if tagname.len() == 1 {
if let Some(tagvalue) = tsi.next() {
// Index by tag (with created_at and id)
self.tc_index.put(
txn,
&Self::key_tc_index(
tagname[0],
tagvalue,
event.created_at(),
event.id(),
),
&offset,
)?;
// Index by author and tag (with created_at and id)
self.atc_index.put(
txn,
@ -610,11 +642,27 @@ impl Store {
event.id(),
),
)?;
// Index by tag (with created_at and id)
self.tc_index.delete(
txn,
&Self::key_tc_index(
tagname[0],
tagvalue,
event.created_at(),
event.id(),
),
)?;
}
}
}
}
self.ac_index.delete(
txn,
&Self::key_ac_index(event.pubkey(), event.created_at(), event.id()),
)?;
self.ci_index
.delete(txn, &Self::key_ci_index(event.created_at(), event.id()))?;
@ -750,6 +798,32 @@ impl Store {
key
}
fn key_tc_index(letter: u8, tag_value: &[u8], created_at: Time, id: Id) -> Vec<u8> {
const PADLEN: usize = 182;
let mut key: Vec<u8> =
Vec::with_capacity(PADLEN + std::mem::size_of::<Time>() + std::mem::size_of::<Id>());
key.push(letter);
if tag_value.len() <= PADLEN {
key.extend(tag_value);
key.extend(core::iter::repeat(0).take(PADLEN - tag_value.len()));
} else {
key.extend(&tag_value[..PADLEN]);
}
key.extend((u64::MAX - created_at.0).to_be_bytes().as_slice());
key.extend(id.as_slice());
key
}
fn key_ac_index(author: Pubkey, created_at: Time, id: Id) -> Vec<u8> {
let mut key: Vec<u8> = Vec::with_capacity(
std::mem::size_of::<Pubkey>() + std::mem::size_of::<Time>() + std::mem::size_of::<Id>(),
);
key.extend(author.as_slice());
key.extend((u64::MAX - created_at.0).to_be_bytes().as_slice());
key.extend(id.as_slice());
key
}
// For looking up event by Author and Kind
// author(32) + kind(2) + reversecreatedat(8) + id(32)
fn key_akc_index(author: Pubkey, kind: Kind, created_at: Time, id: Id) -> Vec<u8> {