diff --git a/src/get_array.nr b/src/get_array.nr index 9645a39..8292287 100644 --- a/src/get_array.nr +++ b/src/get_array.nr @@ -36,21 +36,7 @@ impl where, if the array exists, the JSON object will have the requested array as its root value **/ pub(crate) fn get_array(self, key: [u8; KeyBytes]) -> Option { - assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key"); - let (exists, key_index) = self.key_exists_impl(key); - let entry: JSONEntry = self.json_entries_packed[key_index].into(); - assert( - (entry.entry_type - END_ARRAY_TOKEN as Field) * exists as Field == 0, - "key does not describe an object", - ); - - let result = self.update_json_array(entry, key_index); - - if exists { - Option::some(result) - } else { - Option::none() - } + self.get_array_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** @@ -58,12 +44,7 @@ impl(self, key: [u8; KeyBytes]) -> Self { - assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key"); - - let (entry, key_index) = self.get_json_entry_unchecked_with_key_index(key); - assert(entry.entry_type == END_ARRAY_TOKEN as Field, "key does not describe an object"); - - self.update_json_array(entry, key_index) + self.get_array_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** diff --git a/src/get_literal.nr b/src/get_literal.nr index 01c8c52..9514d4e 100644 --- a/src/get_literal.nr +++ b/src/get_literal.nr @@ -74,21 +74,7 @@ impl which will be null if the literal does not exist **/ pub(crate) fn get_literal(self, key: [u8; KeyBytes]) -> Option { - assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key"); - - let (exists, entry) = self.get_json_entry(key); - assert( - (entry.entry_type - LITERAL_TOKEN as Field) * exists as Field == 0, - "get_literal: entry exists but is not a literal!", - ); - let mut parsed_string: [u8; MAX_LITERAL_LENGTH_AS_STRING] = - self.extract_string_entry(entry); - - if exists { - Option::some(extract_literal_from_array(parsed_string, entry.json_length)) - } else { - Option::none() - } + self.get_literal_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** @@ -96,23 +82,13 @@ impl(self, key: [u8; KeyBytes]) -> JSONLiteral { - assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key"); - - let entry = self.get_json_entry_unchecked(key); - assert( - entry.entry_type == LITERAL_TOKEN as Field, - "get_literal_unchecked_var: entry exists but is not a literal!", - ); - let mut parsed_string: [u8; MAX_LITERAL_LENGTH_AS_STRING] = - self.extract_string_entry(entry); - - extract_literal_from_array(parsed_string, entry.json_length) + self.get_literal_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** * @brief same as `get_literal` for where the key length may be less than KeyBytes **/ - fn get_literal_var( + pub(crate) fn get_literal_var( self, key: BoundedVec, ) -> Option { @@ -136,7 +112,7 @@ impl( + pub(crate) fn get_literal_unchecked_var( self, key: BoundedVec, ) -> JSONLiteral { diff --git a/src/get_number.nr b/src/get_number.nr index f78e827..f117b96 100644 --- a/src/get_number.nr +++ b/src/get_number.nr @@ -55,18 +55,7 @@ impl which will be null if the key does not exist **/ pub(crate) fn get_number(self, key: [u8; KeyBytes]) -> Option { - let (exists, entry) = self.get_json_entry(key); - assert( - (entry.entry_type - NUMERIC_TOKEN as Field) * exists as Field == 0, - "get_number: entry exists but is not a number!", - ); - let mut parsed_string: [u8; U64_LENGTH_AS_BASE10_STRING] = self.extract_string_entry(entry); - - if exists { - Option::some(extract_number_from_array(parsed_string, entry.json_length)) - } else { - Option::none() - } + self.get_number_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** @@ -74,20 +63,16 @@ impl(self, key: [u8; KeyBytes]) -> u64 { - let entry = self.get_json_entry_unchecked(key); - assert( - entry.entry_type == NUMERIC_TOKEN as Field, - "get_number_unchecked: entry exists but is not a number!", - ); - let mut parsed_string: [u8; U64_LENGTH_AS_BASE10_STRING] = self.extract_string_entry(entry); - - extract_number_from_array(parsed_string, entry.json_length) + self.get_number_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** * @brief same as `get_number` for where the key length may be less than KeyBytes **/ - fn get_number_var(self, key: BoundedVec) -> Option { + pub(crate) fn get_number_var( + self, + key: BoundedVec, + ) -> Option { let (exists, entry) = self.get_json_entry_var(key); assert( (entry.entry_type - NUMERIC_TOKEN as Field) * exists as Field == 0, @@ -105,7 +90,10 @@ impl(self, key: BoundedVec) -> u64 { + pub(crate) fn get_number_unchecked_var( + self, + key: BoundedVec, + ) -> u64 { let entry = self.get_json_entry_unchecked_var(key); assert( entry.entry_type == NUMERIC_TOKEN as Field, diff --git a/src/get_object.nr b/src/get_object.nr index ba86510..22112b5 100644 --- a/src/get_object.nr +++ b/src/get_object.nr @@ -25,22 +25,7 @@ impl where, if the object exists, the JSON object will have the requested object as its root value **/ pub(crate) fn get_object(self, key: [u8; KeyBytes]) -> Option { - assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key"); - - let (exists, key_index) = self.key_exists_impl(key); - let entry: JSONEntry = self.json_entries_packed[key_index].into(); - assert( - (entry.entry_type - END_OBJECT_TOKEN as Field) * exists as Field == 0, - "get_object: entry exists but is not an object!", - ); - - let result = self.update_json_object(entry, key_index); - - if exists { - Option::some(result) - } else { - Option::none() - } + self.get_object_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** @@ -48,15 +33,7 @@ impl(self, key: [u8; KeyBytes]) -> Self { - assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key"); - let (entry, key_index) = self.get_json_entry_unchecked_with_key_index(key); - let entry: JSONEntry = self.json_entries_packed[key_index].into(); - assert( - entry.entry_type == END_OBJECT_TOKEN as Field, - "get_object: entry exists but is not an object!", - ); - - self.update_json_object(entry, key_index) + self.get_object_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** diff --git a/src/get_string.nr b/src/get_string.nr index 89171a4..809d0c5 100644 --- a/src/get_string.nr +++ b/src/get_string.nr @@ -105,22 +105,7 @@ impl Option> { - let (exists, entry) = self.get_json_entry(key); - assert( - (entry.entry_type - STRING_TOKEN as Field) * exists as Field == 0, - "get_string: entry exists but is not a string!", - ); - let mut parsed_string: [u8; StringBytes] = self.extract_string_entry(entry); - - let parsed_string: BoundedVec = process_escape_sequences( - BoundedVec::from_parts_unchecked(parsed_string, entry.json_length as u32), - ); - - if exists { - Option::some(parsed_string) - } else { - Option::none() - } + self.get_string_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** @@ -132,16 +117,7 @@ impl BoundedVec { - let entry = self.get_json_entry_unchecked(key); - assert( - entry.entry_type == STRING_TOKEN as Field, - "get_string_unchecked: entry exists but is not a string!", - ); - let parsed_string = BoundedVec::from_parts_unchecked( - self.extract_string_entry(entry), - entry.json_length as u32, - ); - process_escape_sequences(parsed_string) + self.get_string_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** @@ -294,19 +270,7 @@ impl Option> { - let (exists, entry) = self.get_json_entry(key); - let mut parsed_string: [u8; StringBytes] = self.extract_string_entry(entry); - - let parsed_string: BoundedVec = - BoundedVec::from_parts_unchecked(parsed_string, entry.json_length as u32); - - if exists { - Option::some( - JSONValue { value: parsed_string, value_type: entry.entry_type }, - ) - } else { - Option::none() - } + self.get_value_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** @@ -318,14 +282,7 @@ impl JSONValue { - let entry = self.get_json_entry_unchecked(key); - JSONValue { - value: BoundedVec::from_parts_unchecked( - self.extract_string_entry(entry), - entry.json_length as u32, - ), - value_type: entry.entry_type, - } + self.get_value_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** diff --git a/src/getters.nr b/src/getters.nr index a1b6739..b72d232 100644 --- a/src/getters.nr +++ b/src/getters.nr @@ -31,13 +31,7 @@ impl (bool, JSONEntry) { - // let key_index = self.find_key_in_map(keyhash); - // assert(self.key_hashes[key_index] == keyhash); - assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key"); - - let (exists, key_index) = self.key_exists_impl(key); - let entry: JSONEntry = self.json_entries_packed[key_index].into(); - (exists, entry) + self.get_json_entry_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** @@ -48,21 +42,7 @@ impl JSONEntry { - assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key"); - - let hasher: ByteHasher = ByteHasher {}; - let keyhash = hasher.get_keyhash_var(key, 0, KeyBytes); - let two_pow_216 = 0x100000000000000000000000000000000000000000000000000000000; - - let keyhash = keyhash + self.root_id * two_pow_216; - - // Safety: The assertion below checks that the keyhash is stored in the the index returned by the unconstrained function - let key_index = unsafe { find_key_in_map::(self.key_hashes, keyhash) }; - - assert_eq(self.key_hashes[key_index], keyhash, "get_json_entry_unchecked: key not found"); - let entry: JSONEntry = self.json_entries_packed[key_index].into(); - - entry + self.get_json_entry_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /** @@ -112,21 +92,10 @@ impl (JSONEntry, u32) { - assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key"); - - let hasher: ByteHasher = ByteHasher {}; - let keyhash = hasher.get_keyhash_var(key, 0, KeyBytes); - let two_pow_216 = 0x100000000000000000000000000000000000000000000000000000000; - - let keyhash = keyhash + self.root_id * two_pow_216; - - // Safety: The assertion below checks that the keyhash is stored in the the index returned by the unconstrained function - let key_index = unsafe { find_key_in_map::(self.key_hashes, keyhash) }; - - assert_eq(self.key_hashes[key_index], keyhash, "get_json_entry_unchecked: key not found"); - let entry: JSONEntry = self.json_entries_packed[key_index].into(); - - (entry, key_index) + self.get_json_entry_unchecked_with_key_index_var(BoundedVec::from_parts_unchecked( + key, + KeyBytes, + )) } /** * @brief same as `get_json_entry_unchecked_var` but also returns the position of the JSONEntry in `self.json_entries_packed` @@ -187,57 +156,7 @@ impl(self, key: [u8; KeyBytes]) -> (bool, u32) { - /* - Option A: key exists - Option B: key does NOT exist - If key does NOT exist. 3 cases - case 1: keyhash < first entry - case 2: keyhash > last entry - case 3: entry A > keyhash > entryB - */ - let hasher: ByteHasher = ByteHasher {}; - let keyhash = hasher.get_keyhash_var(key, 0, KeyBytes); - - let HASH_MAXIMUM = 0x1000000000000000000000000000000000000000000000000000000000000 - 1; - let two_pow_216 = 0x100000000000000000000000000000000000000000000000000000000; - - let keyhash = keyhash + self.root_id * two_pow_216; - - // Safety: The assertion below checks that the keyhash is stored in the the index returned by the unconstrained function - let search_result = - unsafe { search_for_key_in_map::(self.key_hashes, keyhash) }; - if search_result.found { - assert_eq(search_result.lhs_index, search_result.rhs_index); - } - - let found = search_result.found as Field; - - let target_lt_smallest_entry = search_result.target_lt_smallest_entry as Field; - let target_gt_largest_entry = search_result.target_gt_largest_entry as Field; - - // only one of "found", "target_lt_smallest_entry", "target_gt_largest_entry" can be true - let exclusion_test = found + target_gt_largest_entry + target_lt_smallest_entry; - assert(exclusion_test * exclusion_test == exclusion_test); - - let mut lhs = self.key_hashes[search_result.lhs_index]; - let mut rhs = self.key_hashes[search_result.rhs_index]; - - // case where hash < self.key_hashes[0] - // 0 < hash < hashes[0] - lhs = lhs * (1 - target_lt_smallest_entry); - - // case where hash > self.key_hashes[last] - // largest < x < -1 - rhs = rhs * (1 - target_gt_largest_entry) + target_gt_largest_entry * HASH_MAXIMUM; - - // case where hash == self.key_hashes[found_index] - lhs = lhs - found; - rhs = rhs + found; - - assert_gt_240_bit(keyhash, lhs); - assert_lt_240_bit(keyhash, rhs); - - (search_result.found, search_result.lhs_index) + self.key_exists_impl_var(BoundedVec::from_parts_unchecked(key, KeyBytes)) } /**