github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/src/journal/block_store.rs (about) 1 /* 2 * Copyright 2018 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * ------------------------------------------------------------------------------ 16 */ 17 18 use std::collections::HashMap; 19 20 use block::Block; 21 22 #[derive(Debug)] 23 pub enum BlockStoreError { 24 Error(String), 25 UnknownBlock, 26 } 27 28 pub trait BlockStore { 29 fn get<'a>(&'a self, block_ids: Vec<String>) -> Box<Iterator<Item = &'a Block> + 'a>; 30 31 fn delete(&mut self, block_ids: Vec<String>) -> Result<(), BlockStoreError>; 32 33 fn put(&mut self, blocks: Vec<Block>) -> Result<(), BlockStoreError>; 34 } 35 36 #[derive(Default)] 37 pub struct InMemoryBlockStore { 38 block_by_block_id: HashMap<String, Block>, 39 } 40 41 impl InMemoryBlockStore { 42 pub fn new() -> Self { 43 InMemoryBlockStore::default() 44 } 45 46 fn get_block_by_block_id(&self, block_id: &str) -> Option<&Block> { 47 self.block_by_block_id.get(block_id) 48 } 49 } 50 51 impl BlockStore for InMemoryBlockStore { 52 fn get<'a>(&'a self, block_ids: Vec<String>) -> Box<Iterator<Item = &'a Block> + 'a> { 53 let iterator: InMemoryGetBlockIterator = InMemoryGetBlockIterator::new(self, block_ids); 54 55 Box::new(iterator) 56 } 57 58 fn delete(&mut self, block_ids: Vec<String>) -> Result<(), BlockStoreError> { 59 if block_ids 60 .iter() 61 .any(|block_id| !self.block_by_block_id.contains_key(block_id)) 62 { 63 return Err(BlockStoreError::UnknownBlock); 64 } 65 block_ids.iter().for_each(|block_id| { 66 self.block_by_block_id.remove(block_id); 67 }); 68 Ok(()) 69 } 70 71 fn put(&mut self, blocks: Vec<Block>) -> Result<(), BlockStoreError> { 72 blocks.into_iter().for_each(|block| { 73 self.block_by_block_id 74 .insert(block.header_signature.clone(), block); 75 }); 76 Ok(()) 77 } 78 } 79 80 struct InMemoryGetBlockIterator<'a> { 81 blockstore: &'a InMemoryBlockStore, 82 block_ids: Vec<String>, 83 index: usize, 84 } 85 86 impl<'a> InMemoryGetBlockIterator<'a> { 87 fn new( 88 blockstore: &'a InMemoryBlockStore, 89 block_ids: Vec<String>, 90 ) -> InMemoryGetBlockIterator<'a> { 91 InMemoryGetBlockIterator { 92 blockstore, 93 block_ids, 94 index: 0, 95 } 96 } 97 } 98 99 impl<'a> Iterator for InMemoryGetBlockIterator<'a> { 100 type Item = &'a Block; 101 102 fn next(&mut self) -> Option<Self::Item> { 103 let block = match self.block_ids.get(self.index) { 104 Some(block_id) => self.blockstore.get_block_by_block_id(block_id), 105 None => None, 106 }; 107 self.index += 1; 108 block 109 } 110 }