1use ckb_db::RocksDBWriteBatch;
2use ckb_db_schema::{
3 COLUMN_BLOCK_BODY, COLUMN_BLOCK_EXTENSION, COLUMN_BLOCK_HEADER, COLUMN_BLOCK_PROPOSAL_IDS,
4 COLUMN_BLOCK_UNCLE, COLUMN_CELL, COLUMN_CELL_DATA, COLUMN_CELL_DATA_HASH, COLUMN_NUMBER_HASH,
5 Col,
6};
7use ckb_error::Error;
8use ckb_types::{core::BlockNumber, packed, prelude::*};
9
10pub struct StoreWriteBatch {
12 pub(crate) inner: RocksDBWriteBatch,
13}
14
15impl StoreWriteBatch {
16 pub fn put(&mut self, col: Col, key: &[u8], value: &[u8]) -> Result<(), Error> {
18 self.inner.put(col, key, value)
19 }
20
21 pub fn delete(&mut self, col: Col, key: &[u8]) -> Result<(), Error> {
23 self.inner.delete(col, key)
24 }
25
26 pub fn size_in_bytes(&self) -> usize {
28 self.inner.size_in_bytes()
29 }
30
31 pub fn len(&self) -> usize {
33 self.inner.len()
34 }
35
36 pub fn is_empty(&self) -> bool {
38 self.inner.is_empty()
39 }
40
41 pub fn clear(&mut self) -> Result<(), Error> {
43 self.inner.clear()
44 }
45
46 pub fn insert_cells(
48 &mut self,
49 cells: impl Iterator<
50 Item = (
51 packed::OutPoint,
52 packed::CellEntry,
53 Option<packed::CellDataEntry>,
54 ),
55 >,
56 ) -> Result<(), Error> {
57 for (out_point, cell, cell_data) in cells {
58 let key = out_point.to_cell_key();
59 self.put(COLUMN_CELL, &key, cell.as_slice())?;
60 if let Some(data) = cell_data {
61 self.put(COLUMN_CELL_DATA, &key, data.as_slice())?;
62 self.put(
63 COLUMN_CELL_DATA_HASH,
64 &key,
65 data.output_data_hash().as_slice(),
66 )?;
67 } else {
68 self.put(COLUMN_CELL_DATA, &key, &[])?;
69 self.put(COLUMN_CELL_DATA_HASH, &key, &[])?;
70 }
71 }
72 Ok(())
73 }
74
75 pub fn delete_cells(
77 &mut self,
78 out_points: impl Iterator<Item = packed::OutPoint>,
79 ) -> Result<(), Error> {
80 for out_point in out_points {
81 let key = out_point.to_cell_key();
82 self.delete(COLUMN_CELL, &key)?;
83 self.delete(COLUMN_CELL_DATA, &key)?;
84 self.delete(COLUMN_CELL_DATA_HASH, &key)?;
85 }
86
87 Ok(())
88 }
89
90 pub fn delete_block_body(
92 &mut self,
93 number: BlockNumber,
94 hash: &packed::Byte32,
95 txs_len: u32,
96 ) -> Result<(), Error> {
97 self.inner.delete(COLUMN_BLOCK_UNCLE, hash.as_slice())?;
98 self.inner.delete(COLUMN_BLOCK_EXTENSION, hash.as_slice())?;
99 self.inner
100 .delete(COLUMN_BLOCK_PROPOSAL_IDS, hash.as_slice())?;
101 self.inner.delete(
102 COLUMN_NUMBER_HASH,
103 packed::NumberHash::new_builder()
104 .number(number)
105 .block_hash(hash.clone())
106 .build()
107 .as_slice(),
108 )?;
109
110 let key_range = (0u32..txs_len).map(|i| {
111 packed::TransactionKey::new_builder()
112 .block_hash(hash.clone())
113 .index(i)
114 .build()
115 });
116
117 self.inner.delete_range(COLUMN_BLOCK_BODY, key_range)?;
118 Ok(())
119 }
120
121 pub fn delete_block(
123 &mut self,
124 number: BlockNumber,
125 hash: &packed::Byte32,
126 txs_len: u32,
127 ) -> Result<(), Error> {
128 self.inner.delete(COLUMN_BLOCK_HEADER, hash.as_slice())?;
129 self.delete_block_body(number, hash, txs_len)
130 }
131}