Last active
October 21, 2020 15:56
-
-
Save adria0/829f857351e7a3e758f02ecfba7472ef to your computer and use it in GitHub Desktop.
JournalTest1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::HashSet; | |
use std::rc::Rc; | |
use std::cell::RefCell; | |
struct AccessList(Rc<AccessListInt>); | |
struct AccessListInt { | |
v : RefCell<Option<HashSet<usize>>>, | |
prev: Option<Rc<AccessListInt>> | |
} | |
impl Default for AccessList { | |
fn default() -> Self { | |
AccessList( Rc::new ( | |
AccessListInt{ | |
v : RefCell::new(None), | |
prev: None | |
} | |
)) | |
} | |
} | |
impl Clone for AccessList { | |
fn clone(&self) -> Self { | |
AccessList ( self.0.clone() ) | |
} | |
} | |
impl AccessList { | |
fn clone(&self) -> Self { | |
AccessList ( Rc::new ( | |
AccessListInt { | |
v : RefCell::new(None), | |
prev: Some(self.0.clone()) | |
} | |
)) | |
} | |
pub fn insert(&self, n : usize) { | |
let mut v = self.0.v.borrow_mut(); | |
if v.is_none() { | |
*v = Some(HashSet::new()); | |
} | |
if let Some(ref mut v) = *v { | |
v.insert(n); | |
} | |
} | |
pub fn contains(&self, n : usize) -> bool { | |
let mut this = self.0.as_ref(); | |
loop { | |
if let Some(v) = this.v.borrow().as_ref() { | |
if v.contains(&n) { | |
return true; | |
} | |
} | |
if let Some(prev) = &this.prev { | |
this = prev.as_ref(); | |
} else { | |
return false; | |
} | |
} | |
} | |
} | |
fn main() { | |
let al0 = AccessList::default(); | |
al0.insert(0); | |
assert_eq!(true,al0.contains(0)); | |
assert_eq!(false,al0.contains(1)); | |
let al1 = al0.clone(); | |
al1.insert(1); | |
assert_eq!(true,al1.contains(0)); | |
assert_eq!(true,al1.contains(1)); | |
let al3 = al1.clone().clone(); | |
al3.insert(2); | |
assert_eq!(true,al3.contains(0)); | |
assert_eq!(true,al3.contains(1)); | |
assert_eq!(true,al3.contains(2)); | |
println!("helo"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::HashSet; | |
use std::rc::Rc; | |
use std::cell::RefCell; | |
struct AccessList(Rc<AccessListInt>); | |
struct AccessListInt { | |
v : RefCell<HashSet<usize>>, | |
prev: Option<Rc<AccessListInt>> | |
} | |
impl Default for AccessList { | |
fn default() -> Self { | |
AccessList( Rc::new ( | |
AccessListInt{ | |
v : RefCell::new(HashSet::with_capacity(0)), | |
prev: None | |
} | |
)) | |
} | |
} | |
impl Clone for AccessList { | |
fn clone(&self) -> Self { | |
AccessList ( self.0.clone() ) | |
} | |
} | |
impl AccessList { | |
fn clone(&self) -> Self { | |
AccessList ( Rc::new ( | |
AccessListInt { | |
v : RefCell::new(HashSet::with_capacity(0)), | |
prev: Some(self.0.clone()) | |
} | |
)) | |
} | |
pub fn insert(&self, n : usize) { | |
let mut v = self.0.v.borrow_mut(); | |
v.insert(n); | |
} | |
pub fn contains(&self, n : usize) -> bool { | |
let mut this = self.0.as_ref(); | |
loop { | |
if this.v.borrow().contains(&n) { | |
return true; | |
} | |
if let Some(prev) = &this.prev { | |
this = prev.as_ref(); | |
} else { | |
return false; | |
} | |
} | |
} | |
} | |
fn main() { | |
let al0 = AccessList::default(); | |
al0.insert(0); | |
assert_eq!(true,al0.contains(0)); | |
assert_eq!(false,al0.contains(1)); | |
let al1 = al0.clone(); | |
al1.insert(1); | |
assert_eq!(true,al1.contains(0)); | |
assert_eq!(true,al1.contains(1)); | |
let al3 = al1.clone().clone(); | |
al3.insert(2); | |
assert_eq!(true,al3.contains(0)); | |
assert_eq!(true,al3.contains(1)); | |
assert_eq!(true,al3.contains(2)); | |
println!("success"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::{HashSet, HashMap}; | |
use std::sync::Arc; | |
use std::cell::RefCell; | |
/* | |
// Implementation of a hasheable borrowed pair | |
trait KeyPair<A, B> { | |
fn a(&self) -> &A; | |
fn b(&self) -> &B; | |
} | |
impl<'a, A, B> Borrow<dyn KeyPair<A, B> + 'a> for (A, B) | |
where | |
A: Eq + Hash + 'a, | |
B: Eq + Hash + 'a, | |
{ | |
fn borrow(&self) -> &(dyn KeyPair<A, B> + 'a) { | |
self | |
} | |
} | |
impl<A: Hash, B: Hash> Hash for (dyn KeyPair<A, B> + '_) { | |
fn hash<H: Hasher>(&self, state: &mut H) { | |
self.a().hash(state); | |
self.b().hash(state); | |
} | |
} | |
impl<A: Eq, B: Eq> PartialEq for (dyn KeyPair<A, B> + '_) { | |
fn eq(&self, other: &Self) -> bool { | |
self.a() == other.a() && self.b() == other.b() | |
} | |
} | |
impl<A: Eq, B: Eq> Eq for (dyn KeyPair<A, B> + '_) {} | |
impl<A, B> KeyPair<A, B> for (A, B) { | |
fn a(&self) -> &A { | |
&self.0 | |
} | |
fn b(&self) -> &B { | |
&self.1 | |
} | |
} | |
impl<A, B> KeyPair<A, B> for (&A, &B) { | |
fn a(&self) -> &A { | |
self.0 | |
} | |
fn b(&self) -> &B { | |
self.1 | |
} | |
} | |
#[derive(Debug)] | |
struct Journal { | |
enabled: bool, | |
last_id :usize, | |
addresses: HashMap<Address, usize>, | |
storage_keys: HashMap<(Address, H256), usize>, | |
} | |
#[derive(Debug)] | |
pub struct AccessList { | |
id : usize, | |
journal : Arc<RefCell<Journal>>, | |
} | |
impl Clone for AccessList { | |
fn clone(&self) -> Self { | |
let mut journal = self.journal.as_ref().borrow_mut(); | |
let id = journal.last_id + 1; | |
journal.last_id = id; | |
Self { | |
id : id, | |
journal : self.journal.clone() | |
} | |
} | |
} | |
impl Default for AccessList { | |
fn default() -> Self { | |
let journal = Journal { | |
enabled: false, | |
last_id : 0, | |
addresses : HashMap::new(), | |
storage_keys: HashMap::new() | |
}; | |
Self { | |
id : 0, | |
journal : Arc::new(RefCell::new(journal)) | |
} | |
} | |
} | |
impl AccessList { | |
/// Returns if the list is enabled | |
pub fn is_enabled(&self) -> bool { | |
let journal = self.journal.as_ref().borrow(); | |
journal.enabled | |
} | |
/// Enable the access list control | |
pub fn enable(&mut self) { | |
let mut journal = self.journal.as_ref().borrow_mut(); | |
journal.enabled = true; | |
} | |
/// Checks if contains an storage key | |
pub fn contains_storage_key(&self, address: &Address, key: &H256) -> bool { | |
let journal = self.journal.as_ref().borrow(); | |
if journal.enabled { | |
journal.storage_keys | |
.contains_key(&(address, key) as &dyn KeyPair<Address, H256>) | |
} else { | |
false | |
} | |
} | |
/// Inserts a storage key | |
pub fn insert_storage_key(&mut self, address: Address, key: H256) { | |
let mut journal = self.journal.as_ref().borrow_mut(); | |
if journal.enabled { | |
journal.storage_keys.insert((address, key), self.id); | |
} | |
} | |
/// Checks if contains an address | |
pub fn contains_address(&self, address: &Address) -> bool { | |
let journal = self.journal.as_ref().borrow(); | |
if journal.enabled { | |
journal.addresses.contains_key(&address) | |
} else { | |
false | |
} | |
} | |
/// Inserts an address | |
pub fn insert_address(&mut self, address: Address) { | |
/* [adria0] eprintln!("insert_address({:?}) [{}]",address,self.addresses.contains(&address)); */ | |
let mut journal = self.journal.as_ref().borrow_mut(); | |
if journal.enabled { | |
journal.addresses.insert(address, self.id); | |
} | |
} | |
pub fn rollback(&mut self) { | |
let mut journal = self.journal.as_ref().borrow_mut(); | |
journal.addresses.retain(|_,id| *id != self.id); | |
journal.storage_keys.retain(|_,id| *id != self.id); | |
} | |
pub fn accrue(&mut self, _another: &AccessList) { | |
} | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment