refactor BoomIndex

This commit is contained in:
Alexander Weiss 2022-02-09 00:36:48 +01:00
parent addc0255de
commit f65ac2175b
6 changed files with 52 additions and 61 deletions

View File

@ -19,10 +19,3 @@ pub struct Blob {
tpe: BlobType,
id: Id,
}
#[derive(Debug, Clone, Constructor)]
pub struct BlobInformation {
blob: Blob,
offset: u32,
length: u32,
}

View File

@ -3,7 +3,7 @@ use clap::Parser;
use crate::backend::{FileType, MapResult, ReadBackend};
use crate::id::Id;
use crate::index::{indexfiles::AllIndexFiles, ReadIndex};
use crate::index::{AllIndexFiles, BoomIndex, ReadIndex};
#[derive(Parser)]
pub(super) struct Opts {
@ -19,7 +19,8 @@ pub(super) fn execute(be: &impl ReadBackend, dbe: &impl ReadBackend, opts: Opts)
// special treatment for catingg blobs: read the index and use it to locate the blob
"blob" => {
let id = Id::from_hex(&opts.id)?;
let dec = AllIndexFiles::new(be.clone())
let index = BoomIndex::from_iter(AllIndexFiles::new(be.clone()).into_iter());
let dec = index
.get_id(&id)
.ok_or(anyhow!("blob not found in index"))?
.read_data(be)?;

View File

@ -15,8 +15,10 @@ pub(super) fn execute(be: &impl ReadBackend, opts: Opts) -> Result<()> {
let tpe = match opts.tpe.as_str() {
// special treatment for listing blobs: read the index and display it
"blobs" => {
for ie in AllIndexFiles::new(be.clone()).into_iter() {
println!("{:?} {}", ie.tpe(), ie.id().to_hex());
for i in AllIndexFiles::new(be.clone()).into_iter() {
for blob in i.blobs() {
println!("{:?} {}", blob.tpe(), blob.id().to_hex());
}
}
return Ok(());
}

View File

@ -1,36 +1,61 @@
use boomphf::hashmap::BoomHashMap;
use super::{AllIndexFiles, IndexEntry, ReadIndex};
use crate::backend::ReadBackend;
use super::{BlobType, IndexEntry, ReadIndex};
use crate::id::Id;
use crate::repo::IndexPack;
pub struct BoomIndex(BoomHashMap<Id, IndexEntry>);
impl BoomIndex {
pub fn from_all_indexfiles<BE: ReadBackend>(aif: AllIndexFiles<BE>) -> Self {
Self::from_iter(aif.into_iter())
}
#[derive(Debug)]
struct BoomEntry {
pack_idx: usize,
tpe: BlobType,
offset: u32,
length: u32,
}
impl FromIterator<IndexEntry> for BoomIndex {
pub struct BoomIndex {
packs: Vec<Id>,
boom: BoomHashMap<Id, BoomEntry>,
}
impl FromIterator<IndexPack> for BoomIndex {
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = IndexEntry>,
T: IntoIterator<Item = IndexPack>,
{
let mut packs = Vec::new();
let mut ids = Vec::new();
let mut ies = Vec::new();
let mut bes = Vec::new();
for ie in iter {
ids.push(*ie.id());
ies.push(ie);
for i in iter {
let idx = packs.len();
packs.push(*i.id());
let len = i.blobs().len();
ids.reserve(len);
bes.reserve(len);
for blob in i.blobs() {
let be = BoomEntry {
pack_idx: idx,
tpe: *blob.tpe(),
offset: *blob.offset(),
length: *blob.length(),
};
ids.push(*blob.id());
bes.push(be);
}
}
BoomIndex(BoomHashMap::new(ids, ies))
Self {
packs,
boom: BoomHashMap::new(ids, bes),
}
}
}
impl ReadIndex for BoomIndex {
fn get_id(&self, id: &Id) -> Option<IndexEntry> {
self.0.get(id).map(IndexEntry::clone)
self.boom
.get(id)
.map(|be| IndexEntry::new(self.packs[be.pack_idx], be.tpe, be.offset, be.length))
}
}

View File

@ -1,7 +1,5 @@
use super::{IndexEntry, ReadIndex};
use crate::backend::{FileType, ReadBackend};
use crate::id::Id;
use crate::repo::IndexFile;
use crate::repo::{IndexFile, IndexPack};
#[derive(Clone)]
pub struct AllIndexFiles<BE> {
@ -15,25 +13,14 @@ impl<BE: ReadBackend> AllIndexFiles<BE> {
}
impl<BE: ReadBackend> AllIndexFiles<BE> {
pub fn into_iter(self) -> impl Iterator<Item = IndexEntry> {
pub fn into_iter(self) -> impl Iterator<Item = IndexPack> {
self.be
.list(FileType::Index)
.unwrap()
.into_iter()
.flat_map(move |id| {
let (_, packs) = IndexFile::from_backend(&self.be, id).unwrap().dissolve();
packs.into_iter().flat_map(|p| {
let (id, blobs) = p.dissolve();
blobs
.into_iter()
.map(move |b| IndexEntry::from_index_blob(id, b))
})
packs
})
}
}
impl<BE: ReadBackend> ReadIndex for AllIndexFiles<BE> {
fn get_id(&self, id: &Id) -> Option<IndexEntry> {
self.clone().into_iter().find(|ie| ie.id() == id)
}
}

View File

@ -1,7 +1,6 @@
use crate::backend::{FileType, ReadBackend};
use crate::blob::{Blob, BlobType};
use crate::blob::BlobType;
use crate::id::Id;
use crate::repo::IndexBlob;
use anyhow::Result;
use derive_getters::{Dissolve, Getters};
use derive_more::Constructor;
@ -16,31 +15,15 @@ pub use indexfiles::*;
pub struct IndexEntry {
pack: Id,
tpe: BlobType,
id: Id,
offset: u32,
length: u32,
}
impl IndexEntry {
pub fn from_index_blob(pid: Id, ie: IndexBlob) -> Self {
Self {
pack: pid,
tpe: *ie.tpe(),
id: *ie.id(),
offset: *ie.offset(),
length: *ie.length(),
}
}
/// Get a blob described by IndexEntry from the backend
pub fn read_data<B: ReadBackend>(&self, be: &B) -> Result<Vec<u8>> {
Ok(be.read_partial(FileType::Pack, self.pack, self.offset, self.length)?)
}
#[inline]
pub fn blob(&self) -> Blob {
Blob::new(self.tpe, self.id)
}
}
pub trait ReadIndex {
fn get_id(&self, id: &Id) -> Option<IndexEntry>;