80 lines
3.2 KiB
Rust
80 lines
3.2 KiB
Rust
|
// Copyright (C) 2020 Éloïs SANCHEZ.
|
||
|
//
|
||
|
// This program is free software: you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU Affero General Public License as
|
||
|
// published by the Free Software Foundation, either version 3 of the
|
||
|
// License, or (at your option) any later version.
|
||
|
//
|
||
|
// This program is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
// GNU Affero General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU Affero General Public License
|
||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
|
||
|
use crate::*;
|
||
|
|
||
|
pub(super) fn apply_block_blocks_chunk<B: Backend>(
|
||
|
block: &DubpBlockV10,
|
||
|
gva_db: &mut GvaV1DbTxRw<B::Col>,
|
||
|
) -> KvResult<()> {
|
||
|
let block_number = block.number().0;
|
||
|
gva_db.current_blocks_chunk.upsert(
|
||
|
U32BE(block_number),
|
||
|
GvaBlockDbV1(DubpBlock::V10(block.clone())),
|
||
|
);
|
||
|
|
||
|
if block_number % 1_000 == 999 {
|
||
|
let current_chunk: Vec<GvaBlockDbV1> = gva_db
|
||
|
.current_blocks_chunk
|
||
|
.iter(.., |it| it.values().collect::<Result<Vec<_>, _>>())?;
|
||
|
let current_chunk_bin =
|
||
|
bincode::serialize(¤t_chunk).map_err(|e| KvError::DeserError(e.into()))?;
|
||
|
let chunk_hash = Hash::compute_blake3(current_chunk_bin.as_ref());
|
||
|
let compressed_chunk = lz4_flex::compress_prepend_size(current_chunk_bin.as_ref());
|
||
|
let chunk_index = U32BE(block_number / 1_000);
|
||
|
gva_db
|
||
|
.blocks_chunk_hash
|
||
|
.upsert(chunk_index, HashDb(chunk_hash));
|
||
|
gva_db
|
||
|
.compressed_blocks_chunk
|
||
|
.upsert(chunk_index, compressed_chunk);
|
||
|
}
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
pub(super) fn revert_block_blocks_chunk<B: Backend>(
|
||
|
block: &DubpBlockV10,
|
||
|
gva_db: &mut GvaV1DbTxRw<B::Col>,
|
||
|
) -> KvResult<()> {
|
||
|
let block_number = block.number().0;
|
||
|
if block_number % 1_000 == 999 {
|
||
|
// Uncompress las compressed chunk and replace it in current chunk
|
||
|
let chunk_index = U32BE(block_number / 1_000);
|
||
|
if let Some(compressed_chunk) = gva_db.compressed_blocks_chunk.get(&chunk_index)? {
|
||
|
gva_db.blocks_chunk_hash.remove(chunk_index);
|
||
|
gva_db.compressed_blocks_chunk.remove(chunk_index);
|
||
|
let current_chunk_bin = lz4_flex::decompress_size_prepended(compressed_chunk.as_ref())
|
||
|
.map_err(|e| KvError::Custom(format!("{:?}", e).into()))?;
|
||
|
let current_chunk: Vec<GvaBlockDbV1> = bincode::deserialize(current_chunk_bin.as_ref())
|
||
|
.map_err(|e| KvError::DeserError(e.into()))?;
|
||
|
let current_chunk_begin = block_number - 999;
|
||
|
for (i, block) in current_chunk.into_iter().enumerate() {
|
||
|
gva_db
|
||
|
.current_blocks_chunk
|
||
|
.upsert(U32BE(current_chunk_begin + i as u32), block);
|
||
|
}
|
||
|
} else {
|
||
|
return Err(KvError::DbCorrupted(
|
||
|
"Not found last compressed chunk".to_owned(),
|
||
|
));
|
||
|
}
|
||
|
} else {
|
||
|
gva_db.current_blocks_chunk.remove(U32BE(block_number));
|
||
|
}
|
||
|
|
||
|
Ok(())
|
||
|
}
|