simplify compression and move it out of rlp crate (#7957)
* simplify compression and move it out of rlp crate * removed lazy_static dependency from rlp
This commit is contained in:
parent
ee93be80c0
commit
73756ce262
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -499,6 +499,7 @@ dependencies = [
|
|||||||
"rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.2.1",
|
"rlp 0.2.1",
|
||||||
|
"rlp_compress 0.1.0",
|
||||||
"rlp_derive 0.1.0",
|
"rlp_derive 0.1.0",
|
||||||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1391,7 +1392,6 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"kvdb 0.1.0",
|
"kvdb 0.1.0",
|
||||||
"parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.2.1",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1406,7 +1406,6 @@ dependencies = [
|
|||||||
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.2.1",
|
|
||||||
"rocksdb 0.4.5 (git+https://github.com/paritytech/rust-rocksdb)",
|
"rocksdb 0.4.5 (git+https://github.com/paritytech/rust-rocksdb)",
|
||||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -2664,10 +2663,18 @@ dependencies = [
|
|||||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethereum-types 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethereum-types 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rlp_compress"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rlp 0.2.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rlp_derive"
|
name = "rlp_derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -131,4 +131,5 @@ members = [
|
|||||||
"miner",
|
"miner",
|
||||||
"transaction-pool",
|
"transaction-pool",
|
||||||
"whisper",
|
"whisper",
|
||||||
|
"util/rlp_compress"
|
||||||
]
|
]
|
||||||
|
@ -47,6 +47,7 @@ price-info = { path = "../price-info" }
|
|||||||
rayon = "0.8"
|
rayon = "0.8"
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
rlp = { path = "../util/rlp" }
|
rlp = { path = "../util/rlp" }
|
||||||
|
rlp_compress = { path = "../util/rlp_compress" }
|
||||||
rlp_derive = { path = "../util/rlp_derive" }
|
rlp_derive = { path = "../util/rlp_derive" }
|
||||||
kvdb = { path = "../util/kvdb" }
|
kvdb = { path = "../util/kvdb" }
|
||||||
kvdb-rocksdb = { path = "../util/kvdb-rocksdb" }
|
kvdb-rocksdb = { path = "../util/kvdb-rocksdb" }
|
||||||
|
@ -25,6 +25,7 @@ use ethereum_types::{H256, Bloom, U256};
|
|||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use rlp::*;
|
use rlp::*;
|
||||||
|
use rlp_compress::{compress, decompress, blocks_swapper};
|
||||||
use header::*;
|
use header::*;
|
||||||
use transaction::*;
|
use transaction::*;
|
||||||
use views::*;
|
use views::*;
|
||||||
@ -254,7 +255,7 @@ impl BlockProvider for BlockChain {
|
|||||||
|
|
||||||
let result = match opt {
|
let result = match opt {
|
||||||
Some(b) => {
|
Some(b) => {
|
||||||
let bytes: Bytes = UntrustedRlp::new(&b).decompress(RlpType::Blocks).into_vec();
|
let bytes = decompress(&b, blocks_swapper()).into_vec();
|
||||||
let mut write = self.block_headers.write();
|
let mut write = self.block_headers.write();
|
||||||
write.insert(*hash, bytes.clone());
|
write.insert(*hash, bytes.clone());
|
||||||
Some(encoded::Header::new(bytes))
|
Some(encoded::Header::new(bytes))
|
||||||
@ -290,7 +291,7 @@ impl BlockProvider for BlockChain {
|
|||||||
|
|
||||||
let result = match opt {
|
let result = match opt {
|
||||||
Some(b) => {
|
Some(b) => {
|
||||||
let bytes: Bytes = UntrustedRlp::new(&b).decompress(RlpType::Blocks).into_vec();
|
let bytes = decompress(&b, blocks_swapper()).into_vec();
|
||||||
let mut write = self.block_bodies.write();
|
let mut write = self.block_bodies.write();
|
||||||
write.insert(*hash, bytes.clone());
|
write.insert(*hash, bytes.clone());
|
||||||
Some(encoded::Body::new(bytes))
|
Some(encoded::Body::new(bytes))
|
||||||
@ -702,9 +703,8 @@ impl BlockChain {
|
|||||||
|
|
||||||
assert!(self.pending_best_block.read().is_none());
|
assert!(self.pending_best_block.read().is_none());
|
||||||
|
|
||||||
let block_rlp = UntrustedRlp::new(bytes);
|
let compressed_header = compress(block.header_rlp().as_raw(), blocks_swapper());
|
||||||
let compressed_header = block_rlp.at(0).unwrap().compress(RlpType::Blocks);
|
let compressed_body = compress(&Self::block_to_body(bytes), blocks_swapper());
|
||||||
let compressed_body = UntrustedRlp::new(&Self::block_to_body(bytes)).compress(RlpType::Blocks);
|
|
||||||
|
|
||||||
// store block in db
|
// store block in db
|
||||||
batch.put(db::COL_HEADERS, &hash, &compressed_header);
|
batch.put(db::COL_HEADERS, &hash, &compressed_header);
|
||||||
@ -901,9 +901,12 @@ impl BlockChain {
|
|||||||
|
|
||||||
assert!(self.pending_best_block.read().is_none());
|
assert!(self.pending_best_block.read().is_none());
|
||||||
|
|
||||||
|
let compressed_header = compress(block.header_rlp().as_raw(), blocks_swapper());
|
||||||
|
let compressed_body = compress(&Self::block_to_body(bytes), blocks_swapper());
|
||||||
|
|
||||||
// store block in db
|
// store block in db
|
||||||
batch.put_compressed(db::COL_HEADERS, &hash, block.header_rlp().as_raw().to_vec());
|
batch.put(db::COL_HEADERS, &hash, &compressed_header);
|
||||||
batch.put_compressed(db::COL_BODIES, &hash, Self::block_to_body(bytes));
|
batch.put(db::COL_BODIES, &hash, &compressed_body);
|
||||||
|
|
||||||
let info = self.block_info(&header);
|
let info = self.block_info(&header);
|
||||||
|
|
||||||
|
@ -83,6 +83,7 @@ extern crate price_info;
|
|||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate rayon;
|
extern crate rayon;
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
|
extern crate rlp_compress;
|
||||||
extern crate keccak_hash as hash;
|
extern crate keccak_hash as hash;
|
||||||
extern crate heapsize;
|
extern crate heapsize;
|
||||||
extern crate memorydb;
|
extern crate memorydb;
|
||||||
|
@ -485,7 +485,7 @@ impl fmt::Debug for Account {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use rlp::{UntrustedRlp, RlpType, Compressible};
|
use rlp_compress::{compress, decompress, snapshot_swapper};
|
||||||
use ethereum_types::{H256, Address};
|
use ethereum_types::{H256, Address};
|
||||||
use memorydb::MemoryDB;
|
use memorydb::MemoryDB;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
@ -495,10 +495,9 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn account_compress() {
|
fn account_compress() {
|
||||||
let raw = Account::new_basic(2.into(), 4.into()).rlp();
|
let raw = Account::new_basic(2.into(), 4.into()).rlp();
|
||||||
let rlp = UntrustedRlp::new(&raw);
|
let compact_vec = compress(&raw, snapshot_swapper());
|
||||||
let compact_vec = rlp.compress(RlpType::Snapshot).into_vec();
|
|
||||||
assert!(raw.len() > compact_vec.len());
|
assert!(raw.len() > compact_vec.len());
|
||||||
let again_raw = UntrustedRlp::new(&compact_vec).decompress(RlpType::Snapshot);
|
let again_raw = decompress(&compact_vec, snapshot_swapper());
|
||||||
assert_eq!(raw, again_raw.into_vec());
|
assert_eq!(raw, again_raw.into_vec());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,5 +5,4 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
parking_lot = "0.5"
|
parking_lot = "0.5"
|
||||||
rlp = { path = "../rlp" }
|
|
||||||
kvdb = { path = "../kvdb" }
|
kvdb = { path = "../kvdb" }
|
||||||
|
@ -16,12 +16,10 @@
|
|||||||
|
|
||||||
extern crate parking_lot;
|
extern crate parking_lot;
|
||||||
extern crate kvdb;
|
extern crate kvdb;
|
||||||
extern crate rlp;
|
|
||||||
|
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use kvdb::{DBValue, DBTransaction, KeyValueDB, DBOp, Result};
|
use kvdb::{DBValue, DBTransaction, KeyValueDB, DBOp, Result};
|
||||||
use rlp::{RlpType, UntrustedRlp, Compressible};
|
|
||||||
|
|
||||||
/// A key-value database fulfilling the `KeyValueDB` trait, living in memory.
|
/// A key-value database fulfilling the `KeyValueDB` trait, living in memory.
|
||||||
/// This is generally intended for tests and is not particularly optimized.
|
/// This is generally intended for tests and is not particularly optimized.
|
||||||
@ -75,14 +73,6 @@ impl KeyValueDB for InMemory {
|
|||||||
col.insert(key.into_vec(), value);
|
col.insert(key.into_vec(), value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DBOp::InsertCompressed { col, key, value } => {
|
|
||||||
if let Some(col) = columns.get_mut(&col) {
|
|
||||||
let compressed = UntrustedRlp::new(&value).compress(RlpType::Blocks);
|
|
||||||
let mut value = DBValue::new();
|
|
||||||
value.append_slice(&compressed);
|
|
||||||
col.insert(key.into_vec(), value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DBOp::Delete { col, key } => {
|
DBOp::Delete { col, key } => {
|
||||||
if let Some(col) = columns.get_mut(&col) {
|
if let Some(col) = columns.get_mut(&col) {
|
||||||
col.remove(&*key);
|
col.remove(&*key);
|
||||||
|
@ -11,7 +11,6 @@ log = "0.3"
|
|||||||
num_cpus = "1.0"
|
num_cpus = "1.0"
|
||||||
parking_lot = "0.5"
|
parking_lot = "0.5"
|
||||||
regex = "0.2"
|
regex = "0.2"
|
||||||
rlp = { path = "../rlp" }
|
|
||||||
rocksdb = { git = "https://github.com/paritytech/rust-rocksdb" }
|
rocksdb = { git = "https://github.com/paritytech/rust-rocksdb" }
|
||||||
interleaved-ordered = "0.1.0"
|
interleaved-ordered = "0.1.0"
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ extern crate rocksdb;
|
|||||||
|
|
||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
extern crate kvdb;
|
extern crate kvdb;
|
||||||
extern crate rlp;
|
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -42,7 +41,6 @@ use rocksdb::{
|
|||||||
use interleaved_ordered::{interleave_ordered, InterleaveOrdered};
|
use interleaved_ordered::{interleave_ordered, InterleaveOrdered};
|
||||||
|
|
||||||
use elastic_array::ElasticArray32;
|
use elastic_array::ElasticArray32;
|
||||||
use rlp::{UntrustedRlp, RlpType, Compressible};
|
|
||||||
use kvdb::{KeyValueDB, DBTransaction, DBValue, DBOp, Result};
|
use kvdb::{KeyValueDB, DBTransaction, DBValue, DBOp, Result};
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
@ -56,7 +54,6 @@ const DB_DEFAULT_MEMORY_BUDGET_MB: usize = 128;
|
|||||||
|
|
||||||
enum KeyState {
|
enum KeyState {
|
||||||
Insert(DBValue),
|
Insert(DBValue),
|
||||||
InsertCompressed(DBValue),
|
|
||||||
Delete,
|
Delete,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,10 +403,6 @@ impl Database {
|
|||||||
let c = Self::to_overlay_column(col);
|
let c = Self::to_overlay_column(col);
|
||||||
overlay[c].insert(key, KeyState::Insert(value));
|
overlay[c].insert(key, KeyState::Insert(value));
|
||||||
},
|
},
|
||||||
DBOp::InsertCompressed { col, key, value } => {
|
|
||||||
let c = Self::to_overlay_column(col);
|
|
||||||
overlay[c].insert(key, KeyState::InsertCompressed(value));
|
|
||||||
},
|
|
||||||
DBOp::Delete { col, key } => {
|
DBOp::Delete { col, key } => {
|
||||||
let c = Self::to_overlay_column(col);
|
let c = Self::to_overlay_column(col);
|
||||||
overlay[c].insert(key, KeyState::Delete);
|
overlay[c].insert(key, KeyState::Delete);
|
||||||
@ -442,14 +435,6 @@ impl Database {
|
|||||||
batch.put(&key, &value)?;
|
batch.put(&key, &value)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
KeyState::InsertCompressed(ref value) => {
|
|
||||||
let compressed = UntrustedRlp::new(&value).compress(RlpType::Blocks);
|
|
||||||
if c > 0 {
|
|
||||||
batch.put_cf(cfs[c - 1], &key, &compressed)?;
|
|
||||||
} else {
|
|
||||||
batch.put(&key, &value)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -498,10 +483,6 @@ impl Database {
|
|||||||
DBOp::Insert { col, key, value } => {
|
DBOp::Insert { col, key, value } => {
|
||||||
col.map_or_else(|| batch.put(&key, &value), |c| batch.put_cf(cfs[c as usize], &key, &value))?
|
col.map_or_else(|| batch.put(&key, &value), |c| batch.put_cf(cfs[c as usize], &key, &value))?
|
||||||
},
|
},
|
||||||
DBOp::InsertCompressed { col, key, value } => {
|
|
||||||
let compressed = UntrustedRlp::new(&value).compress(RlpType::Blocks);
|
|
||||||
col.map_or_else(|| batch.put(&key, &compressed), |c| batch.put_cf(cfs[c as usize], &key, &compressed))?
|
|
||||||
},
|
|
||||||
DBOp::Delete { col, key } => {
|
DBOp::Delete { col, key } => {
|
||||||
col.map_or_else(|| batch.delete(&key), |c| batch.delete_cf(cfs[c as usize], &key))?
|
col.map_or_else(|| batch.delete(&key), |c| batch.delete_cf(cfs[c as usize], &key))?
|
||||||
},
|
},
|
||||||
@ -522,12 +503,12 @@ impl Database {
|
|||||||
Some(DBAndColumns { ref db, ref cfs }) => {
|
Some(DBAndColumns { ref db, ref cfs }) => {
|
||||||
let overlay = &self.overlay.read()[Self::to_overlay_column(col)];
|
let overlay = &self.overlay.read()[Self::to_overlay_column(col)];
|
||||||
match overlay.get(key) {
|
match overlay.get(key) {
|
||||||
Some(&KeyState::Insert(ref value)) | Some(&KeyState::InsertCompressed(ref value)) => Ok(Some(value.clone())),
|
Some(&KeyState::Insert(ref value)) => Ok(Some(value.clone())),
|
||||||
Some(&KeyState::Delete) => Ok(None),
|
Some(&KeyState::Delete) => Ok(None),
|
||||||
None => {
|
None => {
|
||||||
let flushing = &self.flushing.read()[Self::to_overlay_column(col)];
|
let flushing = &self.flushing.read()[Self::to_overlay_column(col)];
|
||||||
match flushing.get(key) {
|
match flushing.get(key) {
|
||||||
Some(&KeyState::Insert(ref value)) | Some(&KeyState::InsertCompressed(ref value)) => Ok(Some(value.clone())),
|
Some(&KeyState::Insert(ref value)) => Ok(Some(value.clone())),
|
||||||
Some(&KeyState::Delete) => Ok(None),
|
Some(&KeyState::Delete) => Ok(None),
|
||||||
None => {
|
None => {
|
||||||
col.map_or_else(
|
col.map_or_else(
|
||||||
@ -562,8 +543,7 @@ impl Database {
|
|||||||
let overlay = &self.overlay.read()[Self::to_overlay_column(col)];
|
let overlay = &self.overlay.read()[Self::to_overlay_column(col)];
|
||||||
let mut overlay_data = overlay.iter()
|
let mut overlay_data = overlay.iter()
|
||||||
.filter_map(|(k, v)| match *v {
|
.filter_map(|(k, v)| match *v {
|
||||||
KeyState::Insert(ref value) |
|
KeyState::Insert(ref value) =>
|
||||||
KeyState::InsertCompressed(ref value) =>
|
|
||||||
Some((k.clone().into_vec().into_boxed_slice(), value.clone().into_vec().into_boxed_slice())),
|
Some((k.clone().into_vec().into_boxed_slice(), value.clone().into_vec().into_boxed_slice())),
|
||||||
KeyState::Delete => None,
|
KeyState::Delete => None,
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
|
@ -56,11 +56,6 @@ pub enum DBOp {
|
|||||||
key: ElasticArray32<u8>,
|
key: ElasticArray32<u8>,
|
||||||
value: DBValue,
|
value: DBValue,
|
||||||
},
|
},
|
||||||
InsertCompressed {
|
|
||||||
col: Option<u32>,
|
|
||||||
key: ElasticArray32<u8>,
|
|
||||||
value: DBValue,
|
|
||||||
},
|
|
||||||
Delete {
|
Delete {
|
||||||
col: Option<u32>,
|
col: Option<u32>,
|
||||||
key: ElasticArray32<u8>,
|
key: ElasticArray32<u8>,
|
||||||
@ -72,7 +67,6 @@ impl DBOp {
|
|||||||
pub fn key(&self) -> &[u8] {
|
pub fn key(&self) -> &[u8] {
|
||||||
match *self {
|
match *self {
|
||||||
DBOp::Insert { ref key, .. } => key,
|
DBOp::Insert { ref key, .. } => key,
|
||||||
DBOp::InsertCompressed { ref key, .. } => key,
|
|
||||||
DBOp::Delete { ref key, .. } => key,
|
DBOp::Delete { ref key, .. } => key,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,7 +75,6 @@ impl DBOp {
|
|||||||
pub fn col(&self) -> Option<u32> {
|
pub fn col(&self) -> Option<u32> {
|
||||||
match *self {
|
match *self {
|
||||||
DBOp::Insert { col, .. } => col,
|
DBOp::Insert { col, .. } => col,
|
||||||
DBOp::InsertCompressed { col, .. } => col,
|
|
||||||
DBOp::Delete { col, .. } => col,
|
DBOp::Delete { col, .. } => col,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,18 +115,6 @@ impl DBTransaction {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a key-value pair in the transaction. Any existing value will be overwritten upon write.
|
|
||||||
/// Value will be RLP-compressed on flush
|
|
||||||
pub fn put_compressed(&mut self, col: Option<u32>, key: &[u8], value: Bytes) {
|
|
||||||
let mut ekey = ElasticArray32::new();
|
|
||||||
ekey.append_slice(key);
|
|
||||||
self.ops.push(DBOp::InsertCompressed {
|
|
||||||
col: col,
|
|
||||||
key: ekey,
|
|
||||||
value: DBValue::from_vec(value),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Delete value by key.
|
/// Delete value by key.
|
||||||
pub fn delete(&mut self, col: Option<u32>, key: &[u8]) {
|
pub fn delete(&mut self, col: Option<u32>, key: &[u8]) {
|
||||||
let mut ekey = ElasticArray32::new();
|
let mut ekey = ElasticArray32::new();
|
||||||
|
@ -9,6 +9,5 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
elastic-array = "0.9"
|
elastic-array = "0.9"
|
||||||
ethereum-types = "0.2"
|
ethereum-types = "0.2"
|
||||||
lazy_static = "1.0"
|
|
||||||
rustc-hex = "1.0"
|
rustc-hex = "1.0"
|
||||||
byteorder = "1.0"
|
byteorder = "1.0"
|
||||||
|
File diff suppressed because one or more lines are too long
@ -43,27 +43,21 @@ extern crate ethereum_types as bigint;
|
|||||||
extern crate elastic_array;
|
extern crate elastic_array;
|
||||||
extern crate rustc_hex;
|
extern crate rustc_hex;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
|
||||||
|
|
||||||
mod traits;
|
mod traits;
|
||||||
mod error;
|
mod error;
|
||||||
mod rlpin;
|
mod rlpin;
|
||||||
mod untrusted_rlp;
|
mod untrusted_rlp;
|
||||||
mod stream;
|
mod stream;
|
||||||
mod compression;
|
|
||||||
mod common;
|
|
||||||
mod impls;
|
mod impls;
|
||||||
|
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use elastic_array::ElasticArray1024;
|
use elastic_array::ElasticArray1024;
|
||||||
|
|
||||||
pub use error::DecoderError;
|
pub use error::DecoderError;
|
||||||
pub use traits::{Decodable, Encodable, Compressible};
|
pub use traits::{Decodable, Encodable};
|
||||||
pub use untrusted_rlp::{UntrustedRlp, UntrustedRlpIterator, PayloadInfo, Prototype};
|
pub use untrusted_rlp::{UntrustedRlp, UntrustedRlpIterator, PayloadInfo, Prototype};
|
||||||
pub use rlpin::{Rlp, RlpIterator};
|
pub use rlpin::{Rlp, RlpIterator};
|
||||||
pub use stream::RlpStream;
|
pub use stream::RlpStream;
|
||||||
pub use compression::RlpType;
|
|
||||||
|
|
||||||
/// The RLP encoded empty data (used to mean "null value").
|
/// The RLP encoded empty data (used to mean "null value").
|
||||||
pub const NULL_RLP: [u8; 1] = [0x80; 1];
|
pub const NULL_RLP: [u8; 1] = [0x80; 1];
|
||||||
|
@ -28,14 +28,3 @@ pub trait Encodable {
|
|||||||
s.drain()
|
s.drain()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for compressing and decompressing RLP by replacement of common terms.
|
|
||||||
pub trait Compressible: Sized {
|
|
||||||
/// Indicates the origin of RLP to be compressed.
|
|
||||||
type DataType;
|
|
||||||
|
|
||||||
/// Compress given RLP type using appropriate methods.
|
|
||||||
fn compress(&self, t: Self::DataType) -> ElasticArray1024<u8>;
|
|
||||||
/// Decompress given RLP type using appropriate methods.
|
|
||||||
fn decompress(&self, t: Self::DataType) -> ElasticArray1024<u8>;
|
|
||||||
}
|
|
||||||
|
9
util/rlp_compress/Cargo.toml
Normal file
9
util/rlp_compress/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "rlp_compress"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rlp = { path = "../rlp" }
|
||||||
|
elastic-array = "0.9"
|
||||||
|
lazy_static = "1.0"
|
@ -8,16 +8,16 @@
|
|||||||
|
|
||||||
//! Contains RLPs used for compression.
|
//! Contains RLPs used for compression.
|
||||||
|
|
||||||
use compression::InvalidRlpSwapper;
|
use Swapper;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Swapper for snapshot compression.
|
/// Swapper for snapshot compression.
|
||||||
pub static ref SNAPSHOT_RLP_SWAPPER: InvalidRlpSwapper<'static> = InvalidRlpSwapper::new(EMPTY_RLPS, INVALID_RLPS);
|
pub static ref SNAPSHOT_SWAPPER: Swapper<'static> = Swapper::new(EMPTY_RLPS, INVALID_RLPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Swapper with common long RLPs, up to 127 can be added.
|
/// Swapper with common long RLPs, up to 127 can be added.
|
||||||
pub static ref BLOCKS_RLP_SWAPPER: InvalidRlpSwapper<'static> = InvalidRlpSwapper::new(COMMON_RLPS, INVALID_RLPS);
|
pub static ref BLOCKS_SWAPPER: Swapper<'static> = Swapper::new(COMMON_RLPS, INVALID_RLPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static EMPTY_RLPS: &'static [&'static [u8]] = &[
|
static EMPTY_RLPS: &'static [&'static [u8]] = &[
|
110
util/rlp_compress/src/lib.rs
Normal file
110
util/rlp_compress/src/lib.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
// Copyright 2015-2018 Parity Technologies
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <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.
|
||||||
|
|
||||||
|
extern crate elastic_array;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
extern crate rlp;
|
||||||
|
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
use std::cmp;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use elastic_array::ElasticArray1024;
|
||||||
|
use rlp::{UntrustedRlp, RlpStream};
|
||||||
|
use common::{SNAPSHOT_SWAPPER, BLOCKS_SWAPPER};
|
||||||
|
|
||||||
|
pub fn snapshot_swapper() -> &'static Swapper<'static> {
|
||||||
|
&SNAPSHOT_SWAPPER as &Swapper
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn blocks_swapper() -> &'static Swapper<'static> {
|
||||||
|
&BLOCKS_SWAPPER as &Swapper
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A trait used to compress rlp.
|
||||||
|
pub trait Compressor {
|
||||||
|
/// Get compressed version of given rlp.
|
||||||
|
fn compressed(&self, rlp: &[u8]) -> Option<&[u8]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A trait used to convert compressed rlp into it's original version.
|
||||||
|
pub trait Decompressor {
|
||||||
|
/// Get decompressed rlp.
|
||||||
|
fn decompressed(&self, compressed: &[u8]) -> Option<&[u8]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call this function to compress rlp.
|
||||||
|
pub fn compress(c: &[u8], swapper: &Compressor) -> ElasticArray1024<u8> {
|
||||||
|
let rlp = UntrustedRlp::new(c);
|
||||||
|
if rlp.is_data() {
|
||||||
|
ElasticArray1024::from_slice(swapper.compressed(rlp.as_raw()).unwrap_or_else(|| rlp.as_raw()))
|
||||||
|
} else {
|
||||||
|
map_rlp(&rlp, |r| compress(r.as_raw(), swapper))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call this function to decompress rlp.
|
||||||
|
pub fn decompress(c: &[u8], swapper: &Decompressor) -> ElasticArray1024<u8> {
|
||||||
|
let rlp = UntrustedRlp::new(c);
|
||||||
|
if rlp.is_data() {
|
||||||
|
ElasticArray1024::from_slice(swapper.decompressed(rlp.as_raw()).unwrap_or_else(|| rlp.as_raw()))
|
||||||
|
} else {
|
||||||
|
map_rlp(&rlp, |r| decompress(r.as_raw(), swapper))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_rlp<F: Fn(&UntrustedRlp) -> ElasticArray1024<u8>>(rlp: &UntrustedRlp, f: F) -> ElasticArray1024<u8> {
|
||||||
|
let mut stream = RlpStream::new_list(rlp.item_count().unwrap_or_default());
|
||||||
|
for subrlp in rlp.iter() {
|
||||||
|
stream.append_raw(&f(&subrlp), 1);
|
||||||
|
}
|
||||||
|
stream.drain()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stores RLPs used for compression
|
||||||
|
pub struct Swapper<'a> {
|
||||||
|
compressed_to_rlp: HashMap<&'a [u8], &'a [u8]>,
|
||||||
|
rlp_to_compressed: HashMap<&'a [u8], &'a [u8]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Swapper<'a> {
|
||||||
|
/// Construct a swapper from a list of common RLPs
|
||||||
|
pub fn new(rlps_to_swap: &[&'a [u8]], compressed: &[&'a [u8]]) -> Self {
|
||||||
|
if rlps_to_swap.len() > 0x7e {
|
||||||
|
panic!("Invalid usage, only 127 RLPs can be swappable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
let items = cmp::min(rlps_to_swap.len(), compressed.len());
|
||||||
|
let mut compressed_to_rlp = HashMap::with_capacity(items);
|
||||||
|
let mut rlp_to_compressed = HashMap::with_capacity(items);
|
||||||
|
|
||||||
|
for (&rlp, &compressed) in rlps_to_swap.iter().zip(compressed.iter()) {
|
||||||
|
compressed_to_rlp.insert(compressed, rlp);
|
||||||
|
rlp_to_compressed.insert(rlp, compressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
Swapper {
|
||||||
|
compressed_to_rlp,
|
||||||
|
rlp_to_compressed,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Decompressor for Swapper<'a> {
|
||||||
|
fn decompressed(&self, compressed: &[u8]) -> Option<&[u8]> {
|
||||||
|
self.compressed_to_rlp.get(compressed).cloned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Compressor for Swapper<'a> {
|
||||||
|
fn compressed(&self, rlp: &[u8]) -> Option<&[u8]> {
|
||||||
|
self.rlp_to_compressed.get(rlp).cloned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
50
util/rlp_compress/tests/compress.rs
Normal file
50
util/rlp_compress/tests/compress.rs
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user