radix_engine/kernel/
id_allocator.rs1use crate::errors::{IdAllocationError, KernelError, RuntimeError};
2use crate::internal_prelude::*;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct IdAllocator {
7 transaction_hash: Hash,
8 next_id: u32,
9}
10
11impl IdAllocator {
12 pub fn new(transaction_hash: Hash) -> Self {
13 Self {
14 transaction_hash,
15 next_id: 0u32,
16 }
17 }
18
19 pub fn allocate_node_id(&mut self, entity_type: EntityType) -> Result<NodeId, RuntimeError> {
20 let node_id = self
21 .next_node_id(entity_type)
22 .map_err(|e| RuntimeError::KernelError(KernelError::IdAllocationError(e)))?;
23
24 Ok(node_id)
25 }
26
27 fn next(&mut self) -> Result<u32, IdAllocationError> {
28 if self.next_id == u32::MAX {
29 Err(IdAllocationError::OutOfID)
30 } else {
31 let rtn = self.next_id;
32 self.next_id += 1;
33 Ok(rtn)
34 }
35 }
36
37 fn next_node_id(&mut self, entity_type: EntityType) -> Result<NodeId, IdAllocationError> {
38 let mut buf = [0u8; Hash::LENGTH + 4];
40 buf[..Hash::LENGTH].copy_from_slice(self.transaction_hash.as_ref());
41 buf[Hash::LENGTH..].copy_from_slice(&self.next()?.to_le_bytes());
42 let hash = hash(buf);
43
44 let mut node_id: [u8; NodeId::LENGTH] = hash.lower_bytes();
46 node_id[0] = entity_type as u8;
47
48 Ok(NodeId(node_id))
49 }
50}