Remove Backend trait (#6407)
This commit is contained in:
parent
d865f1f0c5
commit
9e52d11ad0
|
@ -19,7 +19,7 @@ _ cargo +"$rust_stable" clippy --all --exclude solana-sdk-c -- --deny=warnings
|
||||||
_ cargo +"$rust_stable" clippy --manifest-path sdk-c/Cargo.toml -- --deny=warnings
|
_ cargo +"$rust_stable" clippy --manifest-path sdk-c/Cargo.toml -- --deny=warnings
|
||||||
|
|
||||||
_ cargo +"$rust_stable" audit --version
|
_ cargo +"$rust_stable" audit --version
|
||||||
_ cargo +"$rust_stable" audit --ignore RUSTSEC-2019-0013
|
_ cargo +"$rust_stable" audit --ignore RUSTSEC-2019-0013 --ignore RUSTSEC-2018-0015
|
||||||
_ ci/nits.sh
|
_ ci/nits.sh
|
||||||
_ ci/order-crates-for-publishing.py
|
_ ci/order-crates-for-publishing.py
|
||||||
_ book/build.sh
|
_ book/build.sh
|
||||||
|
|
|
@ -36,28 +36,19 @@ mod db;
|
||||||
mod meta;
|
mod meta;
|
||||||
mod rooted_slot_iterator;
|
mod rooted_slot_iterator;
|
||||||
|
|
||||||
macro_rules! db_imports {
|
|
||||||
{ $mod:ident, $db:ident, $db_path:expr } => {
|
|
||||||
mod $mod;
|
|
||||||
|
|
||||||
use $mod::$db;
|
|
||||||
use db::{columns as cf, IteratorMode, IteratorDirection};
|
|
||||||
pub use db::columns;
|
pub use db::columns;
|
||||||
|
use db::{columns as cf, IteratorDirection, IteratorMode};
|
||||||
|
|
||||||
pub type Database = db::Database<$db>;
|
pub type Database = db::Database;
|
||||||
pub type Cursor<C> = db::Cursor<$db, C>;
|
pub type Cursor<C> = db::Cursor<C>;
|
||||||
pub type LedgerColumn<C> = db::LedgerColumn<$db, C>;
|
pub type LedgerColumn<C> = db::LedgerColumn<C>;
|
||||||
pub type WriteBatch = db::WriteBatch<$db>;
|
pub type WriteBatch = db::WriteBatch;
|
||||||
type BatchProcessor = db::BatchProcessor<$db>;
|
type BatchProcessor = db::BatchProcessor;
|
||||||
|
|
||||||
pub trait Column: db::Column<$db> {}
|
pub trait Column: db::Column {}
|
||||||
impl<C: db::Column<$db>> Column for C {}
|
impl<C: db::Column> Column for C {}
|
||||||
|
|
||||||
pub const BLOCKTREE_DIRECTORY: &str = $db_path;
|
pub const BLOCKTREE_DIRECTORY: &str = "rocksdb";
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
db_imports! {rocks, Rocks, "rocksdb"}
|
|
||||||
|
|
||||||
pub const MAX_COMPLETED_SLOTS_IN_CHANNEL: usize = 100_000;
|
pub const MAX_COMPLETED_SLOTS_IN_CHANNEL: usize = 100_000;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::blocktree::{BlocktreeError, Result};
|
use crate::blocktree::{BlocktreeError, Result};
|
||||||
|
|
||||||
use bincode::{deserialize, serialize};
|
use bincode::{deserialize, serialize};
|
||||||
|
use byteorder::{BigEndian, ByteOrder};
|
||||||
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
@ -8,10 +9,21 @@ use serde::Serialize;
|
||||||
use solana_sdk::clock::Slot;
|
use solana_sdk::clock::Slot;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fs;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use rocksdb::{
|
||||||
|
self, ColumnFamily, ColumnFamilyDescriptor, DBIterator, DBRawIterator, Direction,
|
||||||
|
IteratorMode as RocksIteratorMode, Options, WriteBatch as RWriteBatch, DB,
|
||||||
|
};
|
||||||
|
|
||||||
|
// A good value for this is the number of cores on the machine
|
||||||
|
const TOTAL_THREADS: i32 = 8;
|
||||||
|
const MAX_WRITE_BUFFER_SIZE: u64 = 256 * 1024 * 1024; // 256MB
|
||||||
|
const MIN_WRITE_BUFFER_SIZE: u64 = 64 * 1024; // 64KB
|
||||||
|
|
||||||
pub enum IteratorMode<Index> {
|
pub enum IteratorMode<Index> {
|
||||||
Start,
|
Start,
|
||||||
End,
|
End,
|
||||||
|
@ -57,153 +69,434 @@ pub mod columns {
|
||||||
pub struct ShredCode;
|
pub struct ShredCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Backend: Sized + Send + Sync {
|
#[derive(Debug)]
|
||||||
type Key: ?Sized + ToOwned<Owned = Self::OwnedKey>;
|
pub struct Rocks(rocksdb::DB);
|
||||||
type OwnedKey: Borrow<Self::Key>;
|
|
||||||
type ColumnFamily: Clone;
|
|
||||||
type Cursor: DbCursor<Self>;
|
|
||||||
type Iter: Iterator<Item = (Box<Self::Key>, Box<[u8]>)>;
|
|
||||||
type WriteBatch: IWriteBatch<Self>;
|
|
||||||
type Error: Into<BlocktreeError>;
|
|
||||||
|
|
||||||
fn open(path: &Path) -> Result<Self>;
|
impl Rocks {
|
||||||
|
fn open(path: &Path) -> Result<Rocks> {
|
||||||
|
use crate::blocktree::db::columns::{
|
||||||
|
DeadSlots, ErasureMeta, Index, Orphans, Root, ShredCode, ShredData, SlotMeta,
|
||||||
|
};
|
||||||
|
|
||||||
fn columns(&self) -> Vec<&'static str>;
|
fs::create_dir_all(&path)?;
|
||||||
|
|
||||||
fn destroy(path: &Path) -> Result<()>;
|
// Use default database options
|
||||||
|
let db_options = get_db_options();
|
||||||
|
|
||||||
fn cf_handle(&self, cf: &str) -> Self::ColumnFamily;
|
// Column family names
|
||||||
|
let meta_cf_descriptor =
|
||||||
|
ColumnFamilyDescriptor::new(SlotMeta::NAME, get_cf_options(SlotMeta::NAME));
|
||||||
|
let dead_slots_cf_descriptor =
|
||||||
|
ColumnFamilyDescriptor::new(DeadSlots::NAME, get_cf_options(DeadSlots::NAME));
|
||||||
|
let erasure_meta_cf_descriptor =
|
||||||
|
ColumnFamilyDescriptor::new(ErasureMeta::NAME, get_cf_options(ErasureMeta::NAME));
|
||||||
|
let orphans_cf_descriptor =
|
||||||
|
ColumnFamilyDescriptor::new(Orphans::NAME, get_cf_options(Orphans::NAME));
|
||||||
|
let root_cf_descriptor =
|
||||||
|
ColumnFamilyDescriptor::new(Root::NAME, get_cf_options(Root::NAME));
|
||||||
|
let index_cf_descriptor =
|
||||||
|
ColumnFamilyDescriptor::new(Index::NAME, get_cf_options(Index::NAME));
|
||||||
|
let shred_data_cf_descriptor =
|
||||||
|
ColumnFamilyDescriptor::new(ShredData::NAME, get_cf_options(ShredData::NAME));
|
||||||
|
let shred_code_cf_descriptor =
|
||||||
|
ColumnFamilyDescriptor::new(ShredCode::NAME, get_cf_options(ShredCode::NAME));
|
||||||
|
|
||||||
fn get_cf(&self, cf: Self::ColumnFamily, key: &Self::Key) -> Result<Option<Vec<u8>>>;
|
let cfs = vec![
|
||||||
|
meta_cf_descriptor,
|
||||||
|
dead_slots_cf_descriptor,
|
||||||
|
erasure_meta_cf_descriptor,
|
||||||
|
orphans_cf_descriptor,
|
||||||
|
root_cf_descriptor,
|
||||||
|
index_cf_descriptor,
|
||||||
|
shred_data_cf_descriptor,
|
||||||
|
shred_code_cf_descriptor,
|
||||||
|
];
|
||||||
|
|
||||||
fn put_cf(&self, cf: Self::ColumnFamily, key: &Self::Key, value: &[u8]) -> Result<()>;
|
// Open the database
|
||||||
|
let db = Rocks(DB::open_cf_descriptors(&db_options, path, cfs)?);
|
||||||
|
|
||||||
fn delete_cf(&self, cf: Self::ColumnFamily, key: &Self::Key) -> Result<()>;
|
Ok(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn columns(&self) -> Vec<&'static str> {
|
||||||
|
use crate::blocktree::db::columns::{
|
||||||
|
DeadSlots, ErasureMeta, Index, Orphans, Root, ShredCode, ShredData, SlotMeta,
|
||||||
|
};
|
||||||
|
|
||||||
|
vec![
|
||||||
|
ErasureMeta::NAME,
|
||||||
|
DeadSlots::NAME,
|
||||||
|
Index::NAME,
|
||||||
|
Orphans::NAME,
|
||||||
|
Root::NAME,
|
||||||
|
SlotMeta::NAME,
|
||||||
|
ShredData::NAME,
|
||||||
|
ShredCode::NAME,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy(path: &Path) -> Result<()> {
|
||||||
|
DB::destroy(&Options::default(), path)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cf_handle(&self, cf: &str) -> ColumnFamily {
|
||||||
|
self.0
|
||||||
|
.cf_handle(cf)
|
||||||
|
.expect("should never get an unknown column")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cf(&self, cf: ColumnFamily, key: &[u8]) -> Result<Option<Vec<u8>>> {
|
||||||
|
let opt = self.0.get_cf(cf, key)?.map(|db_vec| db_vec.to_vec());
|
||||||
|
Ok(opt)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn put_cf(&self, cf: ColumnFamily, key: &[u8], value: &[u8]) -> Result<()> {
|
||||||
|
self.0.put_cf(cf, key, value)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_cf(&self, cf: ColumnFamily, key: &[u8]) -> Result<()> {
|
||||||
|
self.0.delete_cf(cf, key)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn iterator_cf(
|
fn iterator_cf(
|
||||||
&self,
|
&self,
|
||||||
cf: Self::ColumnFamily,
|
cf: ColumnFamily,
|
||||||
iterator_mode: IteratorMode<&Self::Key>,
|
iterator_mode: IteratorMode<&[u8]>,
|
||||||
) -> Result<Self::Iter>;
|
) -> Result<DBIterator> {
|
||||||
|
let iter = {
|
||||||
|
match iterator_mode {
|
||||||
|
IteratorMode::Start => self.0.iterator_cf(cf, RocksIteratorMode::Start)?,
|
||||||
|
IteratorMode::End => self.0.iterator_cf(cf, RocksIteratorMode::End)?,
|
||||||
|
IteratorMode::From(start_from, direction) => {
|
||||||
|
let rocks_direction = match direction {
|
||||||
|
IteratorDirection::Forward => Direction::Forward,
|
||||||
|
IteratorDirection::Reverse => Direction::Reverse,
|
||||||
|
};
|
||||||
|
self.0
|
||||||
|
.iterator_cf(cf, RocksIteratorMode::From(start_from, rocks_direction))?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
fn raw_iterator_cf(&self, cf: Self::ColumnFamily) -> Result<Self::Cursor>;
|
Ok(iter)
|
||||||
|
|
||||||
fn write(&self, batch: Self::WriteBatch) -> Result<()>;
|
|
||||||
|
|
||||||
fn batch(&self) -> Result<Self::WriteBatch>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Column<B>
|
fn raw_iterator_cf(&self, cf: ColumnFamily) -> Result<DBRawIterator> {
|
||||||
where
|
let raw_iter = self.0.raw_iterator_cf(cf)?;
|
||||||
B: Backend,
|
|
||||||
{
|
Ok(raw_iter)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn batch(&self) -> Result<RWriteBatch> {
|
||||||
|
Ok(RWriteBatch::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&self, batch: RWriteBatch) -> Result<()> {
|
||||||
|
self.0.write(batch)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Column {
|
||||||
const NAME: &'static str;
|
const NAME: &'static str;
|
||||||
type Index;
|
type Index;
|
||||||
|
|
||||||
fn key(index: Self::Index) -> B::OwnedKey;
|
fn key(index: Self::Index) -> Vec<u8>;
|
||||||
fn index(key: &B::Key) -> Self::Index;
|
fn index(key: &[u8]) -> Self::Index;
|
||||||
fn slot(index: Self::Index) -> Slot;
|
fn slot(index: Self::Index) -> Slot;
|
||||||
fn as_index(slot: Slot) -> Self::Index;
|
fn as_index(slot: Slot) -> Self::Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DbCursor<B>
|
pub trait DbCursor {
|
||||||
where
|
|
||||||
B: Backend,
|
|
||||||
{
|
|
||||||
fn valid(&self) -> bool;
|
fn valid(&self) -> bool;
|
||||||
|
|
||||||
fn seek(&mut self, key: &B::Key);
|
fn seek(&mut self, key: &[u8]);
|
||||||
|
|
||||||
fn seek_to_first(&mut self);
|
fn seek_to_first(&mut self);
|
||||||
|
|
||||||
fn next(&mut self);
|
fn next(&mut self);
|
||||||
|
|
||||||
fn key(&self) -> Option<B::OwnedKey>;
|
fn key(&self) -> Option<Vec<u8>>;
|
||||||
|
|
||||||
fn value(&self) -> Option<Vec<u8>>;
|
fn value(&self) -> Option<Vec<u8>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IWriteBatch<B>
|
pub trait IWriteBatch {
|
||||||
where
|
fn put_cf(&mut self, cf: ColumnFamily, key: &[u8], value: &[u8]) -> Result<()>;
|
||||||
B: Backend,
|
fn delete_cf(&mut self, cf: ColumnFamily, key: &[u8]) -> Result<()>;
|
||||||
{
|
|
||||||
fn put_cf(&mut self, cf: B::ColumnFamily, key: &B::Key, value: &[u8]) -> Result<()>;
|
|
||||||
fn delete_cf(&mut self, cf: B::ColumnFamily, key: &B::Key) -> Result<()>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TypedColumn<B>: Column<B>
|
pub trait TypedColumn: Column {
|
||||||
where
|
|
||||||
B: Backend,
|
|
||||||
{
|
|
||||||
type Type: Serialize + DeserializeOwned;
|
type Type: Serialize + DeserializeOwned;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
impl Column for columns::ShredCode {
|
||||||
pub struct Database<B>
|
const NAME: &'static str = super::CODE_SHRED_CF;
|
||||||
where
|
type Index = (u64, u64);
|
||||||
B: Backend,
|
|
||||||
{
|
fn key(index: (u64, u64)) -> Vec<u8> {
|
||||||
backend: Arc<B>,
|
columns::ShredData::key(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index(key: &[u8]) -> (u64, u64) {
|
||||||
|
columns::ShredData::index(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slot(index: Self::Index) -> Slot {
|
||||||
|
index.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_index(slot: Slot) -> Self::Index {
|
||||||
|
(slot, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Column for columns::ShredData {
|
||||||
|
const NAME: &'static str = super::DATA_SHRED_CF;
|
||||||
|
type Index = (u64, u64);
|
||||||
|
|
||||||
|
fn key((slot, index): (u64, u64)) -> Vec<u8> {
|
||||||
|
let mut key = vec![0; 16];
|
||||||
|
BigEndian::write_u64(&mut key[..8], slot);
|
||||||
|
BigEndian::write_u64(&mut key[8..16], index);
|
||||||
|
key
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index(key: &[u8]) -> (u64, u64) {
|
||||||
|
let slot = BigEndian::read_u64(&key[..8]);
|
||||||
|
let index = BigEndian::read_u64(&key[8..16]);
|
||||||
|
(slot, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slot(index: Self::Index) -> Slot {
|
||||||
|
index.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_index(slot: Slot) -> Self::Index {
|
||||||
|
(slot, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Column for columns::Index {
|
||||||
|
const NAME: &'static str = super::INDEX_CF;
|
||||||
|
type Index = u64;
|
||||||
|
|
||||||
|
fn key(slot: u64) -> Vec<u8> {
|
||||||
|
let mut key = vec![0; 8];
|
||||||
|
BigEndian::write_u64(&mut key[..], slot);
|
||||||
|
key
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index(key: &[u8]) -> u64 {
|
||||||
|
BigEndian::read_u64(&key[..8])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slot(index: Self::Index) -> Slot {
|
||||||
|
index
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_index(slot: Slot) -> Self::Index {
|
||||||
|
slot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypedColumn for columns::Index {
|
||||||
|
type Type = crate::blocktree::meta::Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Column for columns::DeadSlots {
|
||||||
|
const NAME: &'static str = super::DEAD_SLOTS_CF;
|
||||||
|
type Index = u64;
|
||||||
|
|
||||||
|
fn key(slot: u64) -> Vec<u8> {
|
||||||
|
let mut key = vec![0; 8];
|
||||||
|
BigEndian::write_u64(&mut key[..], slot);
|
||||||
|
key
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index(key: &[u8]) -> u64 {
|
||||||
|
BigEndian::read_u64(&key[..8])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slot(index: Self::Index) -> Slot {
|
||||||
|
index
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_index(slot: Slot) -> Self::Index {
|
||||||
|
slot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypedColumn for columns::DeadSlots {
|
||||||
|
type Type = bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Column for columns::Orphans {
|
||||||
|
const NAME: &'static str = super::ORPHANS_CF;
|
||||||
|
type Index = u64;
|
||||||
|
|
||||||
|
fn key(slot: u64) -> Vec<u8> {
|
||||||
|
let mut key = vec![0; 8];
|
||||||
|
BigEndian::write_u64(&mut key[..], slot);
|
||||||
|
key
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index(key: &[u8]) -> u64 {
|
||||||
|
BigEndian::read_u64(&key[..8])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slot(index: Self::Index) -> Slot {
|
||||||
|
index
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_index(slot: Slot) -> Self::Index {
|
||||||
|
slot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypedColumn for columns::Orphans {
|
||||||
|
type Type = bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Column for columns::Root {
|
||||||
|
const NAME: &'static str = super::ROOT_CF;
|
||||||
|
type Index = u64;
|
||||||
|
|
||||||
|
fn key(slot: u64) -> Vec<u8> {
|
||||||
|
let mut key = vec![0; 8];
|
||||||
|
BigEndian::write_u64(&mut key[..], slot);
|
||||||
|
key
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index(key: &[u8]) -> u64 {
|
||||||
|
BigEndian::read_u64(&key[..8])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slot(index: Self::Index) -> Slot {
|
||||||
|
index
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_index(slot: Slot) -> Self::Index {
|
||||||
|
slot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypedColumn for columns::Root {
|
||||||
|
type Type = bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Column for columns::SlotMeta {
|
||||||
|
const NAME: &'static str = super::META_CF;
|
||||||
|
type Index = u64;
|
||||||
|
|
||||||
|
fn key(slot: u64) -> Vec<u8> {
|
||||||
|
let mut key = vec![0; 8];
|
||||||
|
BigEndian::write_u64(&mut key[..], slot);
|
||||||
|
key
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index(key: &[u8]) -> u64 {
|
||||||
|
BigEndian::read_u64(&key[..8])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slot(index: Self::Index) -> Slot {
|
||||||
|
index
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_index(slot: Slot) -> Self::Index {
|
||||||
|
slot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypedColumn for columns::SlotMeta {
|
||||||
|
type Type = super::SlotMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Column for columns::ErasureMeta {
|
||||||
|
const NAME: &'static str = super::ERASURE_META_CF;
|
||||||
|
type Index = (u64, u64);
|
||||||
|
|
||||||
|
fn index(key: &[u8]) -> (u64, u64) {
|
||||||
|
let slot = BigEndian::read_u64(&key[..8]);
|
||||||
|
let set_index = BigEndian::read_u64(&key[8..]);
|
||||||
|
|
||||||
|
(slot, set_index)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key((slot, set_index): (u64, u64)) -> Vec<u8> {
|
||||||
|
let mut key = vec![0; 16];
|
||||||
|
BigEndian::write_u64(&mut key[..8], slot);
|
||||||
|
BigEndian::write_u64(&mut key[8..], set_index);
|
||||||
|
key
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slot(index: Self::Index) -> Slot {
|
||||||
|
index.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_index(slot: Slot) -> Self::Index {
|
||||||
|
(slot, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypedColumn for columns::ErasureMeta {
|
||||||
|
type Type = super::ErasureMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct BatchProcessor<B>
|
pub struct Database {
|
||||||
where
|
backend: Arc<Rocks>,
|
||||||
B: Backend,
|
|
||||||
{
|
|
||||||
backend: Arc<B>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Cursor<B, C>
|
pub struct BatchProcessor {
|
||||||
|
backend: Arc<Rocks>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Cursor<C>
|
||||||
where
|
where
|
||||||
B: Backend,
|
C: Column,
|
||||||
C: Column<B>,
|
|
||||||
{
|
{
|
||||||
db_cursor: B::Cursor,
|
db_cursor: DBRawIterator,
|
||||||
column: PhantomData<C>,
|
column: PhantomData<C>,
|
||||||
backend: PhantomData<B>,
|
backend: PhantomData<Rocks>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct LedgerColumn<B, C>
|
pub struct LedgerColumn<C>
|
||||||
where
|
where
|
||||||
B: Backend,
|
C: Column,
|
||||||
C: Column<B>,
|
|
||||||
{
|
{
|
||||||
backend: Arc<B>,
|
backend: Arc<Rocks>,
|
||||||
column: PhantomData<C>,
|
column: PhantomData<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
pub struct WriteBatch {
|
||||||
pub struct WriteBatch<B>
|
write_batch: RWriteBatch,
|
||||||
where
|
backend: PhantomData<Rocks>,
|
||||||
B: Backend,
|
map: HashMap<&'static str, ColumnFamily>,
|
||||||
{
|
|
||||||
write_batch: B::WriteBatch,
|
|
||||||
backend: PhantomData<B>,
|
|
||||||
map: HashMap<&'static str, B::ColumnFamily>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> Database<B>
|
impl Database {
|
||||||
where
|
|
||||||
B: Backend,
|
|
||||||
{
|
|
||||||
pub fn open(path: &Path) -> Result<Self> {
|
pub fn open(path: &Path) -> Result<Self> {
|
||||||
let backend = Arc::new(B::open(path)?);
|
let backend = Arc::new(Rocks::open(path)?);
|
||||||
|
|
||||||
Ok(Database { backend })
|
Ok(Database { backend })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(path: &Path) -> Result<()> {
|
pub fn destroy(path: &Path) -> Result<()> {
|
||||||
B::destroy(path)?;
|
Rocks::destroy(path)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_bytes<C>(&self, key: C::Index) -> Result<Option<Vec<u8>>>
|
pub fn get_bytes<C>(&self, key: C::Index) -> Result<Option<Vec<u8>>>
|
||||||
where
|
where
|
||||||
C: Column<B>,
|
C: Column,
|
||||||
{
|
{
|
||||||
self.backend
|
self.backend
|
||||||
.get_cf(self.cf_handle::<C>(), C::key(key).borrow())
|
.get_cf(self.cf_handle::<C>(), C::key(key).borrow())
|
||||||
|
@ -211,7 +504,7 @@ where
|
||||||
|
|
||||||
pub fn put_bytes<C>(&self, key: C::Index, data: &[u8]) -> Result<()>
|
pub fn put_bytes<C>(&self, key: C::Index, data: &[u8]) -> Result<()>
|
||||||
where
|
where
|
||||||
C: Column<B>,
|
C: Column,
|
||||||
{
|
{
|
||||||
self.backend
|
self.backend
|
||||||
.put_cf(self.cf_handle::<C>(), C::key(key).borrow(), data)
|
.put_cf(self.cf_handle::<C>(), C::key(key).borrow(), data)
|
||||||
|
@ -219,7 +512,7 @@ where
|
||||||
|
|
||||||
pub fn delete<C>(&self, key: C::Index) -> Result<()>
|
pub fn delete<C>(&self, key: C::Index) -> Result<()>
|
||||||
where
|
where
|
||||||
C: Column<B>,
|
C: Column,
|
||||||
{
|
{
|
||||||
self.backend
|
self.backend
|
||||||
.delete_cf(self.cf_handle::<C>(), C::key(key).borrow())
|
.delete_cf(self.cf_handle::<C>(), C::key(key).borrow())
|
||||||
|
@ -227,7 +520,7 @@ where
|
||||||
|
|
||||||
pub fn get<C>(&self, key: C::Index) -> Result<Option<C::Type>>
|
pub fn get<C>(&self, key: C::Index) -> Result<Option<C::Type>>
|
||||||
where
|
where
|
||||||
C: TypedColumn<B>,
|
C: TypedColumn,
|
||||||
{
|
{
|
||||||
if let Some(serialized_value) = self
|
if let Some(serialized_value) = self
|
||||||
.backend
|
.backend
|
||||||
|
@ -243,7 +536,7 @@ where
|
||||||
|
|
||||||
pub fn put<C>(&self, key: C::Index, value: &C::Type) -> Result<()>
|
pub fn put<C>(&self, key: C::Index, value: &C::Type) -> Result<()>
|
||||||
where
|
where
|
||||||
C: TypedColumn<B>,
|
C: TypedColumn,
|
||||||
{
|
{
|
||||||
let serialized_value = serialize(value)?;
|
let serialized_value = serialize(value)?;
|
||||||
|
|
||||||
|
@ -254,9 +547,9 @@ where
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cursor<C>(&self) -> Result<Cursor<B, C>>
|
pub fn cursor<C>(&self) -> Result<Cursor<C>>
|
||||||
where
|
where
|
||||||
C: Column<B>,
|
C: Column,
|
||||||
{
|
{
|
||||||
let db_cursor = self.backend.raw_iterator_cf(self.cf_handle::<C>())?;
|
let db_cursor = self.backend.raw_iterator_cf(self.cf_handle::<C>())?;
|
||||||
|
|
||||||
|
@ -272,7 +565,7 @@ where
|
||||||
iterator_mode: IteratorMode<C::Index>,
|
iterator_mode: IteratorMode<C::Index>,
|
||||||
) -> Result<impl Iterator<Item = (C::Index, Box<[u8]>)>>
|
) -> Result<impl Iterator<Item = (C::Index, Box<[u8]>)>>
|
||||||
where
|
where
|
||||||
C: Column<B>,
|
C: Column,
|
||||||
{
|
{
|
||||||
let iter = {
|
let iter = {
|
||||||
match iterator_mode {
|
match iterator_mode {
|
||||||
|
@ -296,16 +589,16 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cf_handle<C>(&self) -> B::ColumnFamily
|
pub fn cf_handle<C>(&self) -> ColumnFamily
|
||||||
where
|
where
|
||||||
C: Column<B>,
|
C: Column,
|
||||||
{
|
{
|
||||||
self.backend.cf_handle(C::NAME).clone()
|
self.backend.cf_handle(C::NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn column<C>(&self) -> LedgerColumn<B, C>
|
pub fn column<C>(&self) -> LedgerColumn<C>
|
||||||
where
|
where
|
||||||
C: Column<B>,
|
C: Column,
|
||||||
{
|
{
|
||||||
LedgerColumn {
|
LedgerColumn {
|
||||||
backend: Arc::clone(&self.backend),
|
backend: Arc::clone(&self.backend),
|
||||||
|
@ -318,18 +611,15 @@ where
|
||||||
// blocktree.batch_processor, so this API should only be used if the caller is sure they
|
// blocktree.batch_processor, so this API should only be used if the caller is sure they
|
||||||
// are writing to data in columns that will not be corrupted by any simultaneous blocktree
|
// are writing to data in columns that will not be corrupted by any simultaneous blocktree
|
||||||
// operations.
|
// operations.
|
||||||
pub unsafe fn batch_processor(&self) -> BatchProcessor<B> {
|
pub unsafe fn batch_processor(&self) -> BatchProcessor {
|
||||||
BatchProcessor {
|
BatchProcessor {
|
||||||
backend: Arc::clone(&self.backend),
|
backend: Arc::clone(&self.backend),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> BatchProcessor<B>
|
impl BatchProcessor {
|
||||||
where
|
pub fn batch(&mut self) -> Result<WriteBatch> {
|
||||||
B: Backend,
|
|
||||||
{
|
|
||||||
pub fn batch(&mut self) -> Result<WriteBatch<B>> {
|
|
||||||
let db_write_batch = self.backend.batch()?;
|
let db_write_batch = self.backend.batch()?;
|
||||||
let map = self
|
let map = self
|
||||||
.backend
|
.backend
|
||||||
|
@ -345,15 +635,14 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(&mut self, batch: WriteBatch<B>) -> Result<()> {
|
pub fn write(&mut self, batch: WriteBatch) -> Result<()> {
|
||||||
self.backend.write(batch.write_batch)
|
self.backend.write(batch.write_batch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B, C> Cursor<B, C>
|
impl<C> Cursor<C>
|
||||||
where
|
where
|
||||||
B: Backend,
|
C: Column,
|
||||||
C: Column<B>,
|
|
||||||
{
|
{
|
||||||
pub fn valid(&self) -> bool {
|
pub fn valid(&self) -> bool {
|
||||||
self.db_cursor.valid()
|
self.db_cursor.valid()
|
||||||
|
@ -384,10 +673,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B, C> Cursor<B, C>
|
impl<C> Cursor<C>
|
||||||
where
|
where
|
||||||
B: Backend,
|
C: TypedColumn,
|
||||||
C: TypedColumn<B>,
|
|
||||||
{
|
{
|
||||||
pub fn value(&self) -> Option<C::Type> {
|
pub fn value(&self) -> Option<C::Type> {
|
||||||
if let Some(bytes) = self.db_cursor.value() {
|
if let Some(bytes) = self.db_cursor.value() {
|
||||||
|
@ -399,16 +687,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B, C> LedgerColumn<B, C>
|
impl<C> LedgerColumn<C>
|
||||||
where
|
where
|
||||||
B: Backend,
|
C: Column,
|
||||||
C: Column<B>,
|
|
||||||
{
|
{
|
||||||
pub fn get_bytes(&self, key: C::Index) -> Result<Option<Vec<u8>>> {
|
pub fn get_bytes(&self, key: C::Index) -> Result<Option<Vec<u8>>> {
|
||||||
self.backend.get_cf(self.handle(), C::key(key).borrow())
|
self.backend.get_cf(self.handle(), C::key(key).borrow())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cursor(&self) -> Result<Cursor<B, C>> {
|
pub fn cursor(&self) -> Result<Cursor<C>> {
|
||||||
let db_cursor = self.backend.raw_iterator_cf(self.handle())?;
|
let db_cursor = self.backend.raw_iterator_cf(self.handle())?;
|
||||||
|
|
||||||
Ok(Cursor {
|
Ok(Cursor {
|
||||||
|
@ -441,7 +728,7 @@ where
|
||||||
|
|
||||||
pub fn delete_slot(
|
pub fn delete_slot(
|
||||||
&self,
|
&self,
|
||||||
batch: &mut WriteBatch<B>,
|
batch: &mut WriteBatch,
|
||||||
from: Option<Slot>,
|
from: Option<Slot>,
|
||||||
to: Option<Slot>,
|
to: Option<Slot>,
|
||||||
) -> Result<bool>
|
) -> Result<bool>
|
||||||
|
@ -474,8 +761,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn handle(&self) -> B::ColumnFamily {
|
pub fn handle(&self) -> ColumnFamily {
|
||||||
self.backend.cf_handle(C::NAME).clone()
|
self.backend.cf_handle(C::NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_empty(&self) -> Result<bool> {
|
pub fn is_empty(&self) -> Result<bool> {
|
||||||
|
@ -494,10 +781,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B, C> LedgerColumn<B, C>
|
impl<C> LedgerColumn<C>
|
||||||
where
|
where
|
||||||
B: Backend,
|
C: TypedColumn,
|
||||||
C: TypedColumn<B>,
|
|
||||||
{
|
{
|
||||||
pub fn get(&self, key: C::Index) -> Result<Option<C::Type>> {
|
pub fn get(&self, key: C::Index) -> Result<Option<C::Type>> {
|
||||||
if let Some(serialized_value) = self.backend.get_cf(self.handle(), C::key(key).borrow())? {
|
if let Some(serialized_value) = self.backend.get_cf(self.handle(), C::key(key).borrow())? {
|
||||||
|
@ -517,28 +803,106 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> WriteBatch<B>
|
impl WriteBatch {
|
||||||
where
|
pub fn put_bytes<C: Column>(&mut self, key: C::Index, bytes: &[u8]) -> Result<()> {
|
||||||
B: Backend,
|
|
||||||
{
|
|
||||||
pub fn put_bytes<C: Column<B>>(&mut self, key: C::Index, bytes: &[u8]) -> Result<()> {
|
|
||||||
self.write_batch
|
self.write_batch
|
||||||
.put_cf(self.get_cf::<C>(), C::key(key).borrow(), bytes)
|
.put_cf(self.get_cf::<C>(), C::key(key).borrow(), bytes)
|
||||||
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete<C: Column<B>>(&mut self, key: C::Index) -> Result<()> {
|
pub fn delete<C: Column>(&mut self, key: C::Index) -> Result<()> {
|
||||||
self.write_batch
|
self.write_batch
|
||||||
.delete_cf(self.get_cf::<C>(), C::key(key).borrow())
|
.delete_cf(self.get_cf::<C>(), C::key(key).borrow())
|
||||||
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put<C: TypedColumn<B>>(&mut self, key: C::Index, value: &C::Type) -> Result<()> {
|
pub fn put<C: TypedColumn>(&mut self, key: C::Index, value: &C::Type) -> Result<()> {
|
||||||
let serialized_value = serialize(&value)?;
|
let serialized_value = serialize(&value)?;
|
||||||
self.write_batch
|
self.write_batch
|
||||||
.put_cf(self.get_cf::<C>(), C::key(key).borrow(), &serialized_value)
|
.put_cf(self.get_cf::<C>(), C::key(key).borrow(), &serialized_value)
|
||||||
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_cf<C: Column<B>>(&self) -> B::ColumnFamily {
|
fn get_cf<C: Column>(&self) -> ColumnFamily {
|
||||||
self.map[C::NAME].clone()
|
self.map[C::NAME]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DbCursor for DBRawIterator {
|
||||||
|
fn valid(&self) -> bool {
|
||||||
|
DBRawIterator::valid(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn seek(&mut self, key: &[u8]) {
|
||||||
|
DBRawIterator::seek(self, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn seek_to_first(&mut self) {
|
||||||
|
DBRawIterator::seek_to_first(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next(&mut self) {
|
||||||
|
DBRawIterator::next(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key(&self) -> Option<Vec<u8>> {
|
||||||
|
DBRawIterator::key(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value(&self) -> Option<Vec<u8>> {
|
||||||
|
DBRawIterator::value(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IWriteBatch for RWriteBatch {
|
||||||
|
fn put_cf(&mut self, cf: ColumnFamily, key: &[u8], value: &[u8]) -> Result<()> {
|
||||||
|
RWriteBatch::put_cf(self, cf, key, value)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_cf(&mut self, cf: ColumnFamily, key: &[u8]) -> Result<()> {
|
||||||
|
RWriteBatch::delete_cf(self, cf, key)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<rocksdb::Error> for BlocktreeError {
|
||||||
|
fn from(e: rocksdb::Error) -> BlocktreeError {
|
||||||
|
BlocktreeError::RocksDb(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cf_options(name: &'static str) -> Options {
|
||||||
|
use crate::blocktree::db::columns::{ErasureMeta, Index, ShredCode, ShredData};
|
||||||
|
|
||||||
|
let mut options = Options::default();
|
||||||
|
match name {
|
||||||
|
ShredCode::NAME | ShredData::NAME | Index::NAME | ErasureMeta::NAME => {
|
||||||
|
// 512MB * 8 = 4GB. 2 of these columns should take no more than 8GB of RAM
|
||||||
|
options.set_max_write_buffer_number(8);
|
||||||
|
options.set_write_buffer_size(MAX_WRITE_BUFFER_SIZE as usize);
|
||||||
|
options.set_target_file_size_base(MAX_WRITE_BUFFER_SIZE / 10);
|
||||||
|
options.set_max_bytes_for_level_base(MAX_WRITE_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// We want smaller CFs to flush faster. This results in more WAL files but lowers
|
||||||
|
// overall WAL space utilization and increases flush frequency
|
||||||
|
options.set_write_buffer_size(MIN_WRITE_BUFFER_SIZE as usize);
|
||||||
|
options.set_target_file_size_base(MIN_WRITE_BUFFER_SIZE);
|
||||||
|
options.set_max_bytes_for_level_base(MIN_WRITE_BUFFER_SIZE);
|
||||||
|
options.set_level_zero_file_num_compaction_trigger(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_db_options() -> Options {
|
||||||
|
let mut options = Options::default();
|
||||||
|
options.create_if_missing(true);
|
||||||
|
options.create_missing_column_families(true);
|
||||||
|
options.increase_parallelism(TOTAL_THREADS);
|
||||||
|
options.set_max_background_flushes(4);
|
||||||
|
options.set_max_background_compactions(4);
|
||||||
|
options
|
||||||
|
}
|
||||||
|
|
|
@ -1,452 +0,0 @@
|
||||||
use crate::blocktree::db::columns as cf;
|
|
||||||
use crate::blocktree::db::{
|
|
||||||
Backend, Column, DbCursor, IWriteBatch, IteratorDirection, IteratorMode, TypedColumn,
|
|
||||||
};
|
|
||||||
use crate::blocktree::{BlocktreeError, Result};
|
|
||||||
use solana_sdk::clock::Slot;
|
|
||||||
|
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
|
||||||
|
|
||||||
use rocksdb::{
|
|
||||||
self, ColumnFamily, ColumnFamilyDescriptor, DBIterator, DBRawIterator, Direction,
|
|
||||||
IteratorMode as RocksIteratorMode, Options, WriteBatch as RWriteBatch, DB,
|
|
||||||
};
|
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
// A good value for this is the number of cores on the machine
|
|
||||||
const TOTAL_THREADS: i32 = 8;
|
|
||||||
const MAX_WRITE_BUFFER_SIZE: u64 = 256 * 1024 * 1024; // 256MB
|
|
||||||
const MIN_WRITE_BUFFER_SIZE: u64 = 64 * 1024; // 64KB
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Rocks(rocksdb::DB);
|
|
||||||
|
|
||||||
impl Backend for Rocks {
|
|
||||||
type Key = [u8];
|
|
||||||
type OwnedKey = Vec<u8>;
|
|
||||||
type ColumnFamily = ColumnFamily;
|
|
||||||
type Cursor = DBRawIterator;
|
|
||||||
type Iter = DBIterator;
|
|
||||||
type WriteBatch = RWriteBatch;
|
|
||||||
type Error = rocksdb::Error;
|
|
||||||
|
|
||||||
fn open(path: &Path) -> Result<Rocks> {
|
|
||||||
use crate::blocktree::db::columns::{
|
|
||||||
DeadSlots, ErasureMeta, Index, Orphans, Root, ShredCode, ShredData, SlotMeta,
|
|
||||||
};
|
|
||||||
|
|
||||||
fs::create_dir_all(&path)?;
|
|
||||||
|
|
||||||
// Use default database options
|
|
||||||
let db_options = get_db_options();
|
|
||||||
|
|
||||||
// Column family names
|
|
||||||
let meta_cf_descriptor =
|
|
||||||
ColumnFamilyDescriptor::new(SlotMeta::NAME, get_cf_options(SlotMeta::NAME));
|
|
||||||
let dead_slots_cf_descriptor =
|
|
||||||
ColumnFamilyDescriptor::new(DeadSlots::NAME, get_cf_options(DeadSlots::NAME));
|
|
||||||
let erasure_meta_cf_descriptor =
|
|
||||||
ColumnFamilyDescriptor::new(ErasureMeta::NAME, get_cf_options(ErasureMeta::NAME));
|
|
||||||
let orphans_cf_descriptor =
|
|
||||||
ColumnFamilyDescriptor::new(Orphans::NAME, get_cf_options(Orphans::NAME));
|
|
||||||
let root_cf_descriptor =
|
|
||||||
ColumnFamilyDescriptor::new(Root::NAME, get_cf_options(Root::NAME));
|
|
||||||
let index_cf_descriptor =
|
|
||||||
ColumnFamilyDescriptor::new(Index::NAME, get_cf_options(Index::NAME));
|
|
||||||
let shred_data_cf_descriptor =
|
|
||||||
ColumnFamilyDescriptor::new(ShredData::NAME, get_cf_options(ShredData::NAME));
|
|
||||||
let shred_code_cf_descriptor =
|
|
||||||
ColumnFamilyDescriptor::new(ShredCode::NAME, get_cf_options(ShredCode::NAME));
|
|
||||||
|
|
||||||
let cfs = vec![
|
|
||||||
meta_cf_descriptor,
|
|
||||||
dead_slots_cf_descriptor,
|
|
||||||
erasure_meta_cf_descriptor,
|
|
||||||
orphans_cf_descriptor,
|
|
||||||
root_cf_descriptor,
|
|
||||||
index_cf_descriptor,
|
|
||||||
shred_data_cf_descriptor,
|
|
||||||
shred_code_cf_descriptor,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Open the database
|
|
||||||
let db = Rocks(DB::open_cf_descriptors(&db_options, path, cfs)?);
|
|
||||||
|
|
||||||
Ok(db)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn columns(&self) -> Vec<&'static str> {
|
|
||||||
use crate::blocktree::db::columns::{
|
|
||||||
DeadSlots, ErasureMeta, Index, Orphans, Root, ShredCode, ShredData, SlotMeta,
|
|
||||||
};
|
|
||||||
|
|
||||||
vec![
|
|
||||||
ErasureMeta::NAME,
|
|
||||||
DeadSlots::NAME,
|
|
||||||
Index::NAME,
|
|
||||||
Orphans::NAME,
|
|
||||||
Root::NAME,
|
|
||||||
SlotMeta::NAME,
|
|
||||||
ShredData::NAME,
|
|
||||||
ShredCode::NAME,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn destroy(path: &Path) -> Result<()> {
|
|
||||||
DB::destroy(&Options::default(), path)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cf_handle(&self, cf: &str) -> ColumnFamily {
|
|
||||||
self.0
|
|
||||||
.cf_handle(cf)
|
|
||||||
.expect("should never get an unknown column")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_cf(&self, cf: ColumnFamily, key: &[u8]) -> Result<Option<Vec<u8>>> {
|
|
||||||
let opt = self.0.get_cf(cf, key)?.map(|db_vec| db_vec.to_vec());
|
|
||||||
Ok(opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn put_cf(&self, cf: ColumnFamily, key: &[u8], value: &[u8]) -> Result<()> {
|
|
||||||
self.0.put_cf(cf, key, value)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delete_cf(&self, cf: ColumnFamily, key: &[u8]) -> Result<()> {
|
|
||||||
self.0.delete_cf(cf, key)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn iterator_cf(
|
|
||||||
&self,
|
|
||||||
cf: ColumnFamily,
|
|
||||||
iterator_mode: IteratorMode<&[u8]>,
|
|
||||||
) -> Result<DBIterator> {
|
|
||||||
let iter = {
|
|
||||||
match iterator_mode {
|
|
||||||
IteratorMode::Start => self.0.iterator_cf(cf, RocksIteratorMode::Start)?,
|
|
||||||
IteratorMode::End => self.0.iterator_cf(cf, RocksIteratorMode::End)?,
|
|
||||||
IteratorMode::From(start_from, direction) => {
|
|
||||||
let rocks_direction = match direction {
|
|
||||||
IteratorDirection::Forward => Direction::Forward,
|
|
||||||
IteratorDirection::Reverse => Direction::Reverse,
|
|
||||||
};
|
|
||||||
self.0
|
|
||||||
.iterator_cf(cf, RocksIteratorMode::From(start_from, rocks_direction))?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(iter)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn raw_iterator_cf(&self, cf: ColumnFamily) -> Result<DBRawIterator> {
|
|
||||||
let raw_iter = self.0.raw_iterator_cf(cf)?;
|
|
||||||
|
|
||||||
Ok(raw_iter)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn batch(&self) -> Result<RWriteBatch> {
|
|
||||||
Ok(RWriteBatch::default())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write(&self, batch: RWriteBatch) -> Result<()> {
|
|
||||||
self.0.write(batch)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Column<Rocks> for cf::ShredCode {
|
|
||||||
const NAME: &'static str = super::CODE_SHRED_CF;
|
|
||||||
type Index = (u64, u64);
|
|
||||||
|
|
||||||
fn key(index: (u64, u64)) -> Vec<u8> {
|
|
||||||
cf::ShredData::key(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index(key: &[u8]) -> (u64, u64) {
|
|
||||||
cf::ShredData::index(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn slot(index: Self::Index) -> Slot {
|
|
||||||
index.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_index(slot: Slot) -> Self::Index {
|
|
||||||
(slot, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Column<Rocks> for cf::ShredData {
|
|
||||||
const NAME: &'static str = super::DATA_SHRED_CF;
|
|
||||||
type Index = (u64, u64);
|
|
||||||
|
|
||||||
fn key((slot, index): (u64, u64)) -> Vec<u8> {
|
|
||||||
let mut key = vec![0; 16];
|
|
||||||
BigEndian::write_u64(&mut key[..8], slot);
|
|
||||||
BigEndian::write_u64(&mut key[8..16], index);
|
|
||||||
key
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index(key: &[u8]) -> (u64, u64) {
|
|
||||||
let slot = BigEndian::read_u64(&key[..8]);
|
|
||||||
let index = BigEndian::read_u64(&key[8..16]);
|
|
||||||
(slot, index)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn slot(index: Self::Index) -> Slot {
|
|
||||||
index.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_index(slot: Slot) -> Self::Index {
|
|
||||||
(slot, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Column<Rocks> for cf::Index {
|
|
||||||
const NAME: &'static str = super::INDEX_CF;
|
|
||||||
type Index = u64;
|
|
||||||
|
|
||||||
fn key(slot: u64) -> Vec<u8> {
|
|
||||||
let mut key = vec![0; 8];
|
|
||||||
BigEndian::write_u64(&mut key[..], slot);
|
|
||||||
key
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index(key: &[u8]) -> u64 {
|
|
||||||
BigEndian::read_u64(&key[..8])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn slot(index: Self::Index) -> Slot {
|
|
||||||
index
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_index(slot: Slot) -> Self::Index {
|
|
||||||
slot
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypedColumn<Rocks> for cf::Index {
|
|
||||||
type Type = crate::blocktree::meta::Index;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Column<Rocks> for cf::DeadSlots {
|
|
||||||
const NAME: &'static str = super::DEAD_SLOTS_CF;
|
|
||||||
type Index = u64;
|
|
||||||
|
|
||||||
fn key(slot: u64) -> Vec<u8> {
|
|
||||||
let mut key = vec![0; 8];
|
|
||||||
BigEndian::write_u64(&mut key[..], slot);
|
|
||||||
key
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index(key: &[u8]) -> u64 {
|
|
||||||
BigEndian::read_u64(&key[..8])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn slot(index: Self::Index) -> Slot {
|
|
||||||
index
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_index(slot: Slot) -> Self::Index {
|
|
||||||
slot
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypedColumn<Rocks> for cf::DeadSlots {
|
|
||||||
type Type = bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Column<Rocks> for cf::Orphans {
|
|
||||||
const NAME: &'static str = super::ORPHANS_CF;
|
|
||||||
type Index = u64;
|
|
||||||
|
|
||||||
fn key(slot: u64) -> Vec<u8> {
|
|
||||||
let mut key = vec![0; 8];
|
|
||||||
BigEndian::write_u64(&mut key[..], slot);
|
|
||||||
key
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index(key: &[u8]) -> u64 {
|
|
||||||
BigEndian::read_u64(&key[..8])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn slot(index: Self::Index) -> Slot {
|
|
||||||
index
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_index(slot: Slot) -> Self::Index {
|
|
||||||
slot
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypedColumn<Rocks> for cf::Orphans {
|
|
||||||
type Type = bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Column<Rocks> for cf::Root {
|
|
||||||
const NAME: &'static str = super::ROOT_CF;
|
|
||||||
type Index = u64;
|
|
||||||
|
|
||||||
fn key(slot: u64) -> Vec<u8> {
|
|
||||||
let mut key = vec![0; 8];
|
|
||||||
BigEndian::write_u64(&mut key[..], slot);
|
|
||||||
key
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index(key: &[u8]) -> u64 {
|
|
||||||
BigEndian::read_u64(&key[..8])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn slot(index: Self::Index) -> Slot {
|
|
||||||
index
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_index(slot: Slot) -> Self::Index {
|
|
||||||
slot
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypedColumn<Rocks> for cf::Root {
|
|
||||||
type Type = bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Column<Rocks> for cf::SlotMeta {
|
|
||||||
const NAME: &'static str = super::META_CF;
|
|
||||||
type Index = u64;
|
|
||||||
|
|
||||||
fn key(slot: u64) -> Vec<u8> {
|
|
||||||
let mut key = vec![0; 8];
|
|
||||||
BigEndian::write_u64(&mut key[..], slot);
|
|
||||||
key
|
|
||||||
}
|
|
||||||
|
|
||||||
fn index(key: &[u8]) -> u64 {
|
|
||||||
BigEndian::read_u64(&key[..8])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn slot(index: Self::Index) -> Slot {
|
|
||||||
index
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_index(slot: Slot) -> Self::Index {
|
|
||||||
slot
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypedColumn<Rocks> for cf::SlotMeta {
|
|
||||||
type Type = super::SlotMeta;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Column<Rocks> for cf::ErasureMeta {
|
|
||||||
const NAME: &'static str = super::ERASURE_META_CF;
|
|
||||||
type Index = (u64, u64);
|
|
||||||
|
|
||||||
fn index(key: &[u8]) -> (u64, u64) {
|
|
||||||
let slot = BigEndian::read_u64(&key[..8]);
|
|
||||||
let set_index = BigEndian::read_u64(&key[8..]);
|
|
||||||
|
|
||||||
(slot, set_index)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn key((slot, set_index): (u64, u64)) -> Vec<u8> {
|
|
||||||
let mut key = vec![0; 16];
|
|
||||||
BigEndian::write_u64(&mut key[..8], slot);
|
|
||||||
BigEndian::write_u64(&mut key[8..], set_index);
|
|
||||||
key
|
|
||||||
}
|
|
||||||
|
|
||||||
fn slot(index: Self::Index) -> Slot {
|
|
||||||
index.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_index(slot: Slot) -> Self::Index {
|
|
||||||
(slot, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypedColumn<Rocks> for cf::ErasureMeta {
|
|
||||||
type Type = super::ErasureMeta;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DbCursor<Rocks> for DBRawIterator {
|
|
||||||
fn valid(&self) -> bool {
|
|
||||||
DBRawIterator::valid(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn seek(&mut self, key: &[u8]) {
|
|
||||||
DBRawIterator::seek(self, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn seek_to_first(&mut self) {
|
|
||||||
DBRawIterator::seek_to_first(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn next(&mut self) {
|
|
||||||
DBRawIterator::next(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn key(&self) -> Option<Vec<u8>> {
|
|
||||||
DBRawIterator::key(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn value(&self) -> Option<Vec<u8>> {
|
|
||||||
DBRawIterator::value(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IWriteBatch<Rocks> for RWriteBatch {
|
|
||||||
fn put_cf(&mut self, cf: ColumnFamily, key: &[u8], value: &[u8]) -> Result<()> {
|
|
||||||
RWriteBatch::put_cf(self, cf, key, value)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delete_cf(&mut self, cf: ColumnFamily, key: &[u8]) -> Result<()> {
|
|
||||||
RWriteBatch::delete_cf(self, cf, key)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::convert::From<rocksdb::Error> for BlocktreeError {
|
|
||||||
fn from(e: rocksdb::Error) -> BlocktreeError {
|
|
||||||
BlocktreeError::RocksDb(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_cf_options(name: &'static str) -> Options {
|
|
||||||
use crate::blocktree::db::columns::{ErasureMeta, Index, ShredCode, ShredData};
|
|
||||||
|
|
||||||
let mut options = Options::default();
|
|
||||||
match name {
|
|
||||||
ShredCode::NAME | ShredData::NAME | Index::NAME | ErasureMeta::NAME => {
|
|
||||||
// 512MB * 8 = 4GB. 2 of these columns should take no more than 8GB of RAM
|
|
||||||
options.set_max_write_buffer_number(8);
|
|
||||||
options.set_write_buffer_size(MAX_WRITE_BUFFER_SIZE as usize);
|
|
||||||
options.set_target_file_size_base(MAX_WRITE_BUFFER_SIZE / 10);
|
|
||||||
options.set_max_bytes_for_level_base(MAX_WRITE_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// We want smaller CFs to flush faster. This results in more WAL files but lowers
|
|
||||||
// overall WAL space utilization and increases flush frequency
|
|
||||||
options.set_write_buffer_size(MIN_WRITE_BUFFER_SIZE as usize);
|
|
||||||
options.set_target_file_size_base(MIN_WRITE_BUFFER_SIZE);
|
|
||||||
options.set_max_bytes_for_level_base(MIN_WRITE_BUFFER_SIZE);
|
|
||||||
options.set_level_zero_file_num_compaction_trigger(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
options
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_db_options() -> Options {
|
|
||||||
let mut options = Options::default();
|
|
||||||
options.create_if_missing(true);
|
|
||||||
options.create_missing_column_families(true);
|
|
||||||
options.increase_parallelism(TOTAL_THREADS);
|
|
||||||
options.set_max_background_flushes(4);
|
|
||||||
options.set_max_background_compactions(4);
|
|
||||||
options
|
|
||||||
}
|
|
|
@ -157,7 +157,7 @@ impl Crds {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, key: &CrdsValueLabel) {
|
pub fn remove(&mut self, key: &CrdsValueLabel) {
|
||||||
self.table.remove(key);
|
self.table.swap_remove(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -270,7 +270,7 @@ impl CrdsGossipPush {
|
||||||
keys.shuffle(&mut rand::thread_rng());
|
keys.shuffle(&mut rand::thread_rng());
|
||||||
let num = keys.len() / ratio;
|
let num = keys.len() / ratio;
|
||||||
for k in &keys[..num] {
|
for k in &keys[..num] {
|
||||||
self.active_set.remove(k);
|
self.active_set.swap_remove(k);
|
||||||
}
|
}
|
||||||
for (k, v) in new_items {
|
for (k, v) in new_items {
|
||||||
self.active_set.insert(k, v);
|
self.active_set.insert(k, v);
|
||||||
|
|
|
@ -62,7 +62,7 @@ name = "atty"
|
||||||
version = "0.2.13"
|
version = "0.2.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
"backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -89,7 +89,7 @@ version = "0.1.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -248,7 +248,7 @@ name = "chrono"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -543,7 +543,7 @@ version = "1.0.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -621,7 +621,7 @@ version = "0.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -777,7 +777,7 @@ name = "iovec"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -808,7 +808,7 @@ version = "0.1.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -839,7 +839,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.62"
|
version = "0.2.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -883,7 +883,7 @@ name = "memmap"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -926,7 +926,7 @@ dependencies = [
|
||||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -951,7 +951,7 @@ version = "0.2.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1009,7 +1009,7 @@ name = "num_cpus"
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1039,7 +1039,7 @@ name = "parking_lot_core"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1132,7 +1132,7 @@ version = "0.4.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1144,7 +1144,7 @@ version = "0.6.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1162,7 +1162,7 @@ version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1236,7 +1236,7 @@ name = "rand_jitter"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -1248,7 +1248,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1377,7 +1377,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"web-sys 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"web-sys 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1531,7 +1531,7 @@ version = "0.20.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"solana-logger 0.20.0",
|
"solana-logger 0.20.0",
|
||||||
|
@ -1694,7 +1694,7 @@ dependencies = [
|
||||||
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"reqwest 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"reqwest 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1764,7 +1764,7 @@ dependencies = [
|
||||||
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1900,7 +1900,7 @@ dependencies = [
|
||||||
"combine 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"combine 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"elfkit 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"elfkit 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hash32 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hash32 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1994,7 +1994,7 @@ version = "0.5.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2003,7 +2003,7 @@ version = "3.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2039,7 +2039,7 @@ name = "time"
|
||||||
version = "0.1.42"
|
version = "0.1.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -2589,7 +2589,7 @@ dependencies = [
|
||||||
"checksum js-sys 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "1efc4f2a556c58e79c5500912e221dd826bec64ff4aabd8ce71ccef6da02d7d4"
|
"checksum js-sys 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "1efc4f2a556c58e79c5500912e221dd826bec64ff4aabd8ce71ccef6da02d7d4"
|
||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
"checksum libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)" = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c"
|
||||||
"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
|
"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
|
||||||
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
|
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
|
||||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||||
|
|
Loading…
Reference in New Issue