// 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 . use crate::*; pub(super) fn apply_block_blocks_chunk( block: &DubpBlockV10, gva_db: &mut GvaV1DbTxRw, ) -> 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 = gva_db .current_blocks_chunk .iter(.., |it| it.values().collect::, _>>())?; let current_chunk_bin = bincode_db() .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( block: &DubpBlockV10, gva_db: &mut GvaV1DbTxRw, ) -> 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 = bincode_db() .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(()) }