From a81153cf93caeb9200fc07549ff2fe2b90489a7c Mon Sep 17 00:00:00 2001 From: akhercha Date: Fri, 27 Oct 2023 11:19:04 +0200 Subject: [PATCH] feat(log_data_indexes): Replaced SerializableDict's Array by Span --- src/event/event_utils_sandbox.cairo | 10 +++--- src/utils/serializable_dict.cairo | 44 +++++++++++------------ tests/utils/test_serializable_dict.cairo | 45 ++++++++++++++++++------ 3 files changed, 62 insertions(+), 37 deletions(-) diff --git a/src/event/event_utils_sandbox.cairo b/src/event/event_utils_sandbox.cairo index f538e40f..bd676203 100644 --- a/src/event/event_utils_sandbox.cairo +++ b/src/event/event_utils_sandbox.cairo @@ -90,7 +90,7 @@ fn set_item_uint_items( fn set_item_array_uint_items( mut dict: SerializableFelt252Dict, key: felt252, values: Array ) -> SerializableFelt252Dict { - dict.add_array(key, values); + dict.add_span(key, values.span()); dict } @@ -106,7 +106,7 @@ fn set_item_int_items( fn set_item_array_int_items( mut dict: SerializableFelt252Dict, key: felt252, values: Array ) -> SerializableFelt252Dict { - dict.add_array(key, values); + dict.add_span(key, values.span()); dict } @@ -122,7 +122,7 @@ fn set_item_bool_items( fn set_item_array_bool_items( mut dict: SerializableFelt252Dict, key: felt252, values: Array ) -> SerializableFelt252Dict { - dict.add_array(key, values); + dict.add_span(key, values.span()); dict } @@ -138,7 +138,7 @@ fn set_item_Felt252_items( fn set_item_array_Felt252_items( mut dict: SerializableFelt252Dict, key: felt252, values: Array ) -> SerializableFelt252Dict { - dict.add_array(key, values); + dict.add_span(key, values.span()); dict } @@ -154,6 +154,6 @@ fn set_item_string_items( fn set_item_array_string_items( mut dict: SerializableFelt252Dict, key: felt252, values: Array ) -> SerializableFelt252Dict { - dict.add_array(key, values); + dict.add_span(key, values.span()); dict } diff --git a/src/utils/serializable_dict.cairo b/src/utils/serializable_dict.cairo index 43f03f03..d04df993 100644 --- a/src/utils/serializable_dict.cairo +++ b/src/utils/serializable_dict.cairo @@ -12,7 +12,7 @@ use alexandria_data_structures::array_ext::ArrayTraitExt; #[derive(Drop, Copy)] enum Item { Single: T, - Array: Array + Span: Span } #[generate_trait] @@ -20,21 +20,21 @@ impl ItemImpl of ItemTrait { fn is_single(self: @Item) -> bool { match self { Item::Single(v) => true, - Item::Array(arr) => false + Item::Span(arr) => false } } - fn is_array(self: @Item) -> bool { + fn is_span(self: @Item) -> bool { match self { Item::Single(v) => false, - Item::Array(arr) => true + Item::Span(arr) => true } } fn len(self: @Item) -> usize { match self { Item::Single(v) => 1, - Item::Array(arr) => arr.len() + Item::Span(s) => (*s).len() } } } @@ -101,7 +101,7 @@ trait SerializableFelt252DictTrait { /// Adds an element. fn add_single(ref self: SerializableFelt252Dict, key: felt252, value: T); /// Adds an array of elements. - fn add_array(ref self: SerializableFelt252Dict, key: felt252, values: Array); + fn add_span(ref self: SerializableFelt252Dict, key: felt252, values: Span); /// Gets an element. fn get>( ref self: SerializableFelt252Dict, key: felt252 @@ -122,12 +122,18 @@ impl SerializableFelt252DictTraitImpl< fn add_single(ref self: SerializableFelt252Dict, key: felt252, value: T) { let value = Item::Single(value); - self.values.insert(0, nullable_from_box(BoxTrait::new(value))); + if !self.keys.contains(key) { + self.keys.append(key); + } + self.values.insert(key, nullable_from_box(BoxTrait::new(value))); } - fn add_array(ref self: SerializableFelt252Dict, key: felt252, values: Array) { - let values = Item::Array(values); - self.values.insert(0, nullable_from_box(BoxTrait::new(values))); + fn add_span(ref self: SerializableFelt252Dict, key: felt252, values: Span) { + let values = Item::Span(values); + if !self.keys.contains(key) { + self.keys.append(key); + } + self.values.insert(key, nullable_from_box(BoxTrait::new(values))); } fn get>( @@ -193,13 +199,9 @@ impl SerializableFelt252DictSerde< // fn serialize(self: @SerializableFelt252Dict, ref output: Array) { let mut keys: Span = self.keys.span(); - let mut included_keys: Array = array![]; loop { match keys.pop_back() { Option::Some(key) => { - if (!included_keys.contains(*key)) { - continue; - } let mut ordered_dict = (*self); let nullable_value: Nullable> = ordered_dict.values.get(*key); let value: Item = match match_nullable(nullable_value) { @@ -214,12 +216,11 @@ impl SerializableFelt252DictSerde< output.append(1_felt252); // len output.append(v.into()); // value }, - Item::Array(arr) => { + Item::Span(mut arr) => { output.append(*key); // key output.append(arr.len().into()); // len - let mut arr_as_span: Span = arr.span(); loop { - match arr_as_span.pop_front() { + match arr.pop_front() { Option::Some(v) => { output.append((*v).into()); }, @@ -230,7 +231,6 @@ impl SerializableFelt252DictSerde< } } }; - included_keys.append(*key); }, Option::None => { break; @@ -258,7 +258,7 @@ impl SerializableFelt252DictSerde< Option::Some(size) => { // If only one element, insert it & quit if ((*size) == 1) { - let value: T = get_next_value_from(serialized); + let value: T = pop_front_next(serialized); let value: Item = Item::Single(value); d.values.insert(*key, nullable_from_box(BoxTrait::new(value))); continue; @@ -270,12 +270,12 @@ impl SerializableFelt252DictSerde< if (arr_size) == 0 { break; }; - let value: T = get_next_value_from(serialized); + let value: T = pop_front_next(serialized); arr_values.append(value); arr_size -= 1; }; // ... & insert it - let values: Item = Item::Array(arr_values); + let values: Item = Item::Span(arr_values.span()); d.values.insert(*key, nullable_from_box(BoxTrait::new(values))); }, Option::None => panic_with_felt252('err getting size') @@ -291,7 +291,7 @@ impl SerializableFelt252DictSerde< } -fn get_next_value_from>(mut serialized: Span) -> T { +fn pop_front_next>(mut serialized: Span) -> T { let value = match serialized.pop_front() { Option::Some(value) => value, Option::None => panic_with_felt252('err getting value') diff --git a/tests/utils/test_serializable_dict.cairo b/tests/utils/test_serializable_dict.cairo index aaa9dc04..9b731c1c 100644 --- a/tests/utils/test_serializable_dict.cairo +++ b/tests/utils/test_serializable_dict.cairo @@ -10,6 +10,7 @@ use starknet::{ }; use array::ArrayTrait; use traits::Default; +use alexandria_data_structures::array_ext::ArrayTraitExt; // Local imports. use satoru::utils::traits::ContractAddressDefault; @@ -29,18 +30,18 @@ fn test_item_single() { let item: Item = Item::Single(8); assert(item.is_single() == true, 'item should be single'); - assert(item.is_array() == false, 'item shouldnt be array'); + assert(item.is_span() == false, 'item shouldnt be a span'); assert(item.len() == 1, 'item len not 1'); } #[test] -fn test_item_multiple() { +fn test_item_span() { let arr: Array = array![1, 2, 3, 4, 5]; let expected_len: usize = arr.len(); - let item: Item = Item::Array(arr); + let item: Item = Item::Span(arr.span()); - assert(item.is_array() == true, 'item should be array'); + assert(item.is_span() == true, 'item should be a span'); assert(item.is_single() == false, 'item shouldnt be single'); assert(item.len() == expected_len, 'incorrect len'); } @@ -49,24 +50,48 @@ fn test_item_multiple() { #[test] fn test_serializable_dict_add_single() { - let mut dict: SerializableFelt252Dict = SerializableFelt252Dict { - keys: array![], values: Default::default() - }; + let mut dict: SerializableFelt252Dict = SerializableFelt252DictTrait::new(); let key: felt252 = 'starknet'; let expected_value: felt252 = 'cairo'; dict.add_single(key, expected_value); - let retrieved_item: Item = match dict.get(key) { + let retrieved_item = match dict.get(key) { Option::Some(i) => i, - Option::None => panic_with_felt252('err while searching key') + Option::None => panic_with_felt252('key should be in dict') }; let out_value: felt252 = match retrieved_item { Item::Single(v) => v, - Item::Array(_) => panic_with_felt252('should not be array') + Item::Span(_) => panic_with_felt252('item should not be a span') }; + assert(dict.keys.contains(key), 'key should be in dict'); assert(out_value == expected_value, 'wrong value'); } + +#[test] +fn test_serializable_dict_add_span() { + let mut dict: SerializableFelt252Dict = SerializableFelt252DictTrait::new(); + + let key: felt252 = 'starknet'; + let expected_array: Array = array![1, 2, 3]; + + dict.add_span(key, expected_array.span()); + + let retrieved_item = match dict.get(key) { + Option::Some(i) => i, + Option::None => panic_with_felt252('key should be in dict') + }; + + let out_span: Span = match retrieved_item { + Item::Single(_) => panic_with_felt252('item should not single'), + Item::Span(s) => s + }; + + assert(dict.keys.contains(key), 'key should be in dict'); + assert(out_span.at(0) == expected_array.at(0), 'wrong at idx 0'); + assert(out_span.at(1) == expected_array.at(1), 'wrong at idx 0'); + assert(out_span.at(2) == expected_array.at(2), 'wrong at idx 0'); +}