Skip to content

Commit

Permalink
feat(log_data_indexes): Replaced SerializableDict's Array by Span
Browse files Browse the repository at this point in the history
  • Loading branch information
akhercha committed Oct 27, 2023
1 parent 5e72d6c commit a81153c
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 37 deletions.
10 changes: 5 additions & 5 deletions src/event/event_utils_sandbox.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ fn set_item_uint_items(
fn set_item_array_uint_items(
mut dict: SerializableFelt252Dict<u128>, key: felt252, values: Array<u128>
) -> SerializableFelt252Dict<u128> {
dict.add_array(key, values);
dict.add_span(key, values.span());
dict
}

Expand All @@ -106,7 +106,7 @@ fn set_item_int_items(
fn set_item_array_int_items(
mut dict: SerializableFelt252Dict<i128>, key: felt252, values: Array<i128>
) -> SerializableFelt252Dict<i128> {
dict.add_array(key, values);
dict.add_span(key, values.span());
dict
}

Expand All @@ -122,7 +122,7 @@ fn set_item_bool_items(
fn set_item_array_bool_items(
mut dict: SerializableFelt252Dict<bool>, key: felt252, values: Array<bool>
) -> SerializableFelt252Dict<bool> {
dict.add_array(key, values);
dict.add_span(key, values.span());
dict
}

Expand All @@ -138,7 +138,7 @@ fn set_item_Felt252_items(
fn set_item_array_Felt252_items(
mut dict: SerializableFelt252Dict<felt252>, key: felt252, values: Array<felt252>
) -> SerializableFelt252Dict<felt252> {
dict.add_array(key, values);
dict.add_span(key, values.span());
dict
}

Expand All @@ -154,6 +154,6 @@ fn set_item_string_items(
fn set_item_array_string_items(
mut dict: SerializableFelt252Dict<felt252>, key: felt252, values: Array<felt252>
) -> SerializableFelt252Dict<felt252> {
dict.add_array(key, values);
dict.add_span(key, values.span());
dict
}
44 changes: 22 additions & 22 deletions src/utils/serializable_dict.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,29 @@ use alexandria_data_structures::array_ext::ArrayTraitExt;
#[derive(Drop, Copy)]
enum Item<T> {
Single: T,
Array: Array<T>
Span: Span<T>
}

#[generate_trait]
impl ItemImpl<T> of ItemTrait<T> {
fn is_single(self: @Item<T>) -> bool {
match self {
Item::Single(v) => true,
Item::Array(arr) => false
Item::Span(arr) => false
}
}

fn is_array(self: @Item<T>) -> bool {
fn is_span(self: @Item<T>) -> bool {
match self {
Item::Single(v) => false,
Item::Array(arr) => true
Item::Span(arr) => true
}
}

fn len(self: @Item<T>) -> usize {
match self {
Item::Single(v) => 1,
Item::Array(arr) => arr.len()
Item::Span(s) => (*s).len()
}
}
}
Expand Down Expand Up @@ -101,7 +101,7 @@ trait SerializableFelt252DictTrait<T> {
/// Adds an element.
fn add_single(ref self: SerializableFelt252Dict<T>, key: felt252, value: T);
/// Adds an array of elements.
fn add_array(ref self: SerializableFelt252Dict<T>, key: felt252, values: Array<T>);
fn add_span(ref self: SerializableFelt252Dict<T>, key: felt252, values: Span<T>);
/// Gets an element.
fn get<impl TCopy: Copy<T>>(
ref self: SerializableFelt252Dict<T>, key: felt252
Expand All @@ -122,12 +122,18 @@ impl SerializableFelt252DictTraitImpl<

fn add_single(ref self: SerializableFelt252Dict<T>, 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<T>, key: felt252, values: Array<T>) {
let values = Item::Array(values);
self.values.insert(0, nullable_from_box(BoxTrait::new(values)));
fn add_span(ref self: SerializableFelt252Dict<T>, key: felt252, values: Span<T>) {
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<impl TCopy: Copy<T>>(
Expand Down Expand Up @@ -193,13 +199,9 @@ impl SerializableFelt252DictSerde<
//
fn serialize(self: @SerializableFelt252Dict<T>, ref output: Array<felt252>) {
let mut keys: Span<felt252> = self.keys.span();
let mut included_keys: Array<felt252> = array![];
loop {
match keys.pop_back() {
Option::Some(key) => {
if (!included_keys.contains(*key)) {
continue;
}
let mut ordered_dict = (*self);
let nullable_value: Nullable<Item<T>> = ordered_dict.values.get(*key);
let value: Item<T> = match match_nullable(nullable_value) {
Expand All @@ -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<T> = arr.span();
loop {
match arr_as_span.pop_front() {
match arr.pop_front() {
Option::Some(v) => {
output.append((*v).into());
},
Expand All @@ -230,7 +231,6 @@ impl SerializableFelt252DictSerde<
}
}
};
included_keys.append(*key);
},
Option::None => {
break;
Expand Down Expand Up @@ -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<T> = Item::Single(value);
d.values.insert(*key, nullable_from_box(BoxTrait::new(value)));
continue;
Expand All @@ -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<T> = Item::Array(arr_values);
let values: Item<T> = Item::Span(arr_values.span());
d.values.insert(*key, nullable_from_box(BoxTrait::new(values)));
},
Option::None => panic_with_felt252('err getting size')
Expand All @@ -291,7 +291,7 @@ impl SerializableFelt252DictSerde<
}


fn get_next_value_from<T, impl TInto: Into<felt252, T>>(mut serialized: Span<felt252>) -> T {
fn pop_front_next<T, impl TInto: Into<felt252, T>>(mut serialized: Span<felt252>) -> T {
let value = match serialized.pop_front() {
Option::Some(value) => value,
Option::None => panic_with_felt252('err getting value')
Expand Down
45 changes: 35 additions & 10 deletions tests/utils/test_serializable_dict.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -29,18 +30,18 @@ fn test_item_single() {
let item: Item<u8> = 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<u8> = array![1, 2, 3, 4, 5];
let expected_len: usize = arr.len();

let item: Item<u8> = Item::Array(arr);
let item: Item<u8> = 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');
}
Expand All @@ -49,24 +50,48 @@ fn test_item_multiple() {

#[test]
fn test_serializable_dict_add_single() {
let mut dict: SerializableFelt252Dict<felt252> = SerializableFelt252Dict {
keys: array![], values: Default::default()
};
let mut dict: SerializableFelt252Dict<felt252> = SerializableFelt252DictTrait::new();

let key: felt252 = 'starknet';
let expected_value: felt252 = 'cairo';

dict.add_single(key, expected_value);

let retrieved_item: Item<felt252> = 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<u8> = SerializableFelt252DictTrait::new();

let key: felt252 = 'starknet';
let expected_array: Array<u8> = 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<u8> = 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');
}

0 comments on commit a81153c

Please sign in to comment.