Skip to content

Commit 33bf554

Browse files
authored
chore: strip out duplicate implementations of fixed and variable length keys (#84)
1 parent 51574b7 commit 33bf554

File tree

6 files changed

+29
-231
lines changed

6 files changed

+29
-231
lines changed

src/get_array.nr

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,34 +36,15 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
3636
* @description returns an Option<JSON> where, if the array exists, the JSON object will have the requested array as its root value
3737
**/
3838
pub(crate) fn get_array<let KeyBytes: u32>(self, key: [u8; KeyBytes]) -> Option<Self> {
39-
assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key");
40-
let (exists, key_index) = self.key_exists_impl(key);
41-
let entry: JSONEntry = self.json_entries_packed[key_index].into();
42-
assert(
43-
(entry.entry_type - END_ARRAY_TOKEN as Field) * exists as Field == 0,
44-
"key does not describe an object",
45-
);
46-
47-
let result = self.update_json_array(entry, key_index);
48-
49-
if exists {
50-
Option::some(result)
51-
} else {
52-
Option::none()
53-
}
39+
self.get_array_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
5440
}
5541

5642
/**
5743
* @brief if the root JSON is an object, extract an array given by `key`
5844
* @description will revert if the array does not exist
5945
**/
6046
pub(crate) fn get_array_unchecked<let KeyBytes: u32>(self, key: [u8; KeyBytes]) -> Self {
61-
assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key");
62-
63-
let (entry, key_index) = self.get_json_entry_unchecked_with_key_index(key);
64-
assert(entry.entry_type == END_ARRAY_TOKEN as Field, "key does not describe an object");
65-
66-
self.update_json_array(entry, key_index)
47+
self.get_array_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
6748
}
6849

6950
/**

src/get_literal.nr

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -74,45 +74,21 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
7474
* @description returns an Option<JSONLiteral> which will be null if the literal does not exist
7575
**/
7676
pub(crate) fn get_literal<let KeyBytes: u32>(self, key: [u8; KeyBytes]) -> Option<JSONLiteral> {
77-
assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key");
78-
79-
let (exists, entry) = self.get_json_entry(key);
80-
assert(
81-
(entry.entry_type - LITERAL_TOKEN as Field) * exists as Field == 0,
82-
"get_literal: entry exists but is not a literal!",
83-
);
84-
let mut parsed_string: [u8; MAX_LITERAL_LENGTH_AS_STRING] =
85-
self.extract_string_entry(entry);
86-
87-
if exists {
88-
Option::some(extract_literal_from_array(parsed_string, entry.json_length))
89-
} else {
90-
Option::none()
91-
}
77+
self.get_literal_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
9278
}
9379

9480
/**
9581
* @brief if the root JSON is an object, extract a literal value given by `key`
9682
* @description will revert if the literal does not exist
9783
**/
9884
fn get_literal_unchecked<let KeyBytes: u32>(self, key: [u8; KeyBytes]) -> JSONLiteral {
99-
assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key");
100-
101-
let entry = self.get_json_entry_unchecked(key);
102-
assert(
103-
entry.entry_type == LITERAL_TOKEN as Field,
104-
"get_literal_unchecked_var: entry exists but is not a literal!",
105-
);
106-
let mut parsed_string: [u8; MAX_LITERAL_LENGTH_AS_STRING] =
107-
self.extract_string_entry(entry);
108-
109-
extract_literal_from_array(parsed_string, entry.json_length)
85+
self.get_literal_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
11086
}
11187

11288
/**
11389
* @brief same as `get_literal` for where the key length may be less than KeyBytes
11490
**/
115-
fn get_literal_var<let KeyBytes: u32>(
91+
pub(crate) fn get_literal_var<let KeyBytes: u32>(
11692
self,
11793
key: BoundedVec<u8, KeyBytes>,
11894
) -> Option<JSONLiteral> {
@@ -136,7 +112,7 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
136112
/**
137113
* @brief same as `get_literal_unchecked` for where the key length may be less than KeyBytes
138114
**/
139-
fn get_literal_unchecked_var<let KeyBytes: u32>(
115+
pub(crate) fn get_literal_unchecked_var<let KeyBytes: u32>(
140116
self,
141117
key: BoundedVec<u8, KeyBytes>,
142118
) -> JSONLiteral {

src/get_number.nr

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -55,39 +55,24 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
5555
* @description returns an Option<u64> which will be null if the key does not exist
5656
**/
5757
pub(crate) fn get_number<let KeyBytes: u32>(self, key: [u8; KeyBytes]) -> Option<u64> {
58-
let (exists, entry) = self.get_json_entry(key);
59-
assert(
60-
(entry.entry_type - NUMERIC_TOKEN as Field) * exists as Field == 0,
61-
"get_number: entry exists but is not a number!",
62-
);
63-
let mut parsed_string: [u8; U64_LENGTH_AS_BASE10_STRING] = self.extract_string_entry(entry);
64-
65-
if exists {
66-
Option::some(extract_number_from_array(parsed_string, entry.json_length))
67-
} else {
68-
Option::none()
69-
}
58+
self.get_number_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
7059
}
7160

7261
/**
7362
* @brief if the root JSON is an object, extract a u64 value given by `key`
7463
* @description will revert if the number does not exist
7564
**/
7665
fn get_number_unchecked<let KeyBytes: u32>(self, key: [u8; KeyBytes]) -> u64 {
77-
let entry = self.get_json_entry_unchecked(key);
78-
assert(
79-
entry.entry_type == NUMERIC_TOKEN as Field,
80-
"get_number_unchecked: entry exists but is not a number!",
81-
);
82-
let mut parsed_string: [u8; U64_LENGTH_AS_BASE10_STRING] = self.extract_string_entry(entry);
83-
84-
extract_number_from_array(parsed_string, entry.json_length)
66+
self.get_number_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
8567
}
8668

8769
/**
8870
* @brief same as `get_number` for where the key length may be less than KeyBytes
8971
**/
90-
fn get_number_var<let KeyBytes: u32>(self, key: BoundedVec<u8, KeyBytes>) -> Option<u64> {
72+
pub(crate) fn get_number_var<let KeyBytes: u32>(
73+
self,
74+
key: BoundedVec<u8, KeyBytes>,
75+
) -> Option<u64> {
9176
let (exists, entry) = self.get_json_entry_var(key);
9277
assert(
9378
(entry.entry_type - NUMERIC_TOKEN as Field) * exists as Field == 0,
@@ -105,7 +90,10 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
10590
/**
10691
* @brief same as `get_number_unchecked` for where the key length may be less than KeyBytes
10792
**/
108-
fn get_number_unchecked_var<let KeyBytes: u32>(self, key: BoundedVec<u8, KeyBytes>) -> u64 {
93+
pub(crate) fn get_number_unchecked_var<let KeyBytes: u32>(
94+
self,
95+
key: BoundedVec<u8, KeyBytes>,
96+
) -> u64 {
10997
let entry = self.get_json_entry_unchecked_var(key);
11098
assert(
11199
entry.entry_type == NUMERIC_TOKEN as Field,

src/get_object.nr

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,38 +25,15 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
2525
* @description returns an Option<JSON> where, if the object exists, the JSON object will have the requested object as its root value
2626
**/
2727
pub(crate) fn get_object<let KeyBytes: u32>(self, key: [u8; KeyBytes]) -> Option<Self> {
28-
assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key");
29-
30-
let (exists, key_index) = self.key_exists_impl(key);
31-
let entry: JSONEntry = self.json_entries_packed[key_index].into();
32-
assert(
33-
(entry.entry_type - END_OBJECT_TOKEN as Field) * exists as Field == 0,
34-
"get_object: entry exists but is not an object!",
35-
);
36-
37-
let result = self.update_json_object(entry, key_index);
38-
39-
if exists {
40-
Option::some(result)
41-
} else {
42-
Option::none()
43-
}
28+
self.get_object_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
4429
}
4530

4631
/**
4732
* @brief if the root JSON is an object, extract a child object given by `key`
4833
* @description will revert if the requested object does not exist
4934
**/
5035
pub(crate) fn get_object_unchecked<let KeyBytes: u32>(self, key: [u8; KeyBytes]) -> Self {
51-
assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key");
52-
let (entry, key_index) = self.get_json_entry_unchecked_with_key_index(key);
53-
let entry: JSONEntry = self.json_entries_packed[key_index].into();
54-
assert(
55-
entry.entry_type == END_OBJECT_TOKEN as Field,
56-
"get_object: entry exists but is not an object!",
57-
);
58-
59-
self.update_json_object(entry, key_index)
36+
self.get_object_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
6037
}
6138

6239
/**

src/get_string.nr

Lines changed: 4 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -105,22 +105,7 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
105105
self,
106106
key: [u8; KeyBytes],
107107
) -> Option<BoundedVec<u8, StringBytes>> {
108-
let (exists, entry) = self.get_json_entry(key);
109-
assert(
110-
(entry.entry_type - STRING_TOKEN as Field) * exists as Field == 0,
111-
"get_string: entry exists but is not a string!",
112-
);
113-
let mut parsed_string: [u8; StringBytes] = self.extract_string_entry(entry);
114-
115-
let parsed_string: BoundedVec<u8, StringBytes> = process_escape_sequences(
116-
BoundedVec::from_parts_unchecked(parsed_string, entry.json_length as u32),
117-
);
118-
119-
if exists {
120-
Option::some(parsed_string)
121-
} else {
122-
Option::none()
123-
}
108+
self.get_string_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
124109
}
125110

126111
/**
@@ -132,16 +117,7 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
132117
self,
133118
key: [u8; KeyBytes],
134119
) -> BoundedVec<u8, StringBytes> {
135-
let entry = self.get_json_entry_unchecked(key);
136-
assert(
137-
entry.entry_type == STRING_TOKEN as Field,
138-
"get_string_unchecked: entry exists but is not a string!",
139-
);
140-
let parsed_string = BoundedVec::from_parts_unchecked(
141-
self.extract_string_entry(entry),
142-
entry.json_length as u32,
143-
);
144-
process_escape_sequences(parsed_string)
120+
self.get_string_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
145121
}
146122

147123
/**
@@ -301,19 +277,7 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
301277
self,
302278
key: [u8; KeyBytes],
303279
) -> Option<JSONValue<StringBytes>> {
304-
let (exists, entry) = self.get_json_entry(key);
305-
let mut parsed_string: [u8; StringBytes] = self.extract_string_entry(entry);
306-
307-
let parsed_string: BoundedVec<u8, StringBytes> =
308-
BoundedVec::from_parts_unchecked(parsed_string, entry.json_length as u32);
309-
310-
if exists {
311-
Option::some(
312-
JSONValue { value: parsed_string, value_type: entry.entry_type },
313-
)
314-
} else {
315-
Option::none()
316-
}
280+
self.get_value_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
317281
}
318282

319283
/**
@@ -325,14 +289,7 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
325289
self,
326290
key: [u8; KeyBytes],
327291
) -> JSONValue<StringBytes> {
328-
let entry = self.get_json_entry_unchecked(key);
329-
JSONValue {
330-
value: BoundedVec::from_parts_unchecked(
331-
self.extract_string_entry(entry),
332-
entry.json_length as u32,
333-
),
334-
value_type: entry.entry_type,
335-
}
292+
self.get_value_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
336293
}
337294

338295
/**

src/getters.nr

Lines changed: 7 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,7 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
3131
self,
3232
key: [u8; KeyBytes],
3333
) -> (bool, JSONEntry) {
34-
// let key_index = self.find_key_in_map(keyhash);
35-
// assert(self.key_hashes[key_index] == keyhash);
36-
assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key");
37-
38-
let (exists, key_index) = self.key_exists_impl(key);
39-
let entry: JSONEntry = self.json_entries_packed[key_index].into();
40-
(exists, entry)
34+
self.get_json_entry_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
4135
}
4236

4337
/**
@@ -48,21 +42,7 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
4842
self,
4943
key: [u8; KeyBytes],
5044
) -> JSONEntry {
51-
assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key");
52-
53-
let hasher: ByteHasher<MaxKeyFields> = ByteHasher {};
54-
let keyhash = hasher.get_keyhash_var(key, 0, KeyBytes);
55-
let two_pow_216 = 0x100000000000000000000000000000000000000000000000000000000;
56-
57-
let keyhash = keyhash + self.root_id * two_pow_216;
58-
59-
// Safety: The assertion below checks that the keyhash is stored in the the index returned by the unconstrained function
60-
let key_index = unsafe { find_key_in_map::<MaxNumValues>(self.key_hashes, keyhash) };
61-
62-
assert_eq(self.key_hashes[key_index], keyhash, "get_json_entry_unchecked: key not found");
63-
let entry: JSONEntry = self.json_entries_packed[key_index].into();
64-
65-
entry
45+
self.get_json_entry_unchecked_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
6646
}
6747

6848
/**
@@ -112,21 +92,10 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
11292
self,
11393
key: [u8; KeyBytes],
11494
) -> (JSONEntry, u32) {
115-
assert(self.layer_type_of_root != ARRAY_LAYER, "cannot extract array elements via a key");
116-
117-
let hasher: ByteHasher<MaxKeyFields> = ByteHasher {};
118-
let keyhash = hasher.get_keyhash_var(key, 0, KeyBytes);
119-
let two_pow_216 = 0x100000000000000000000000000000000000000000000000000000000;
120-
121-
let keyhash = keyhash + self.root_id * two_pow_216;
122-
123-
// Safety: The assertion below checks that the keyhash is stored in the the index returned by the unconstrained function
124-
let key_index = unsafe { find_key_in_map::<MaxNumValues>(self.key_hashes, keyhash) };
125-
126-
assert_eq(self.key_hashes[key_index], keyhash, "get_json_entry_unchecked: key not found");
127-
let entry: JSONEntry = self.json_entries_packed[key_index].into();
128-
129-
(entry, key_index)
95+
self.get_json_entry_unchecked_with_key_index_var(BoundedVec::from_parts_unchecked(
96+
key,
97+
KeyBytes,
98+
))
13099
}
131100
/**
132101
* @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<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
187156
* If it does *not* exist, we can find two adjacent entries in `key_hashes` where `key_hashes[i]` < target_key_hash < `key_hashes[i+1]`
188157
**/
189158
pub(crate) fn key_exists_impl<let KeyBytes: u32>(self, key: [u8; KeyBytes]) -> (bool, u32) {
190-
/*
191-
Option A: key exists
192-
Option B: key does NOT exist
193-
If key does NOT exist. 3 cases
194-
case 1: keyhash < first entry
195-
case 2: keyhash > last entry
196-
case 3: entry A > keyhash > entryB
197-
*/
198-
let hasher: ByteHasher<MaxKeyFields> = ByteHasher {};
199-
let keyhash = hasher.get_keyhash_var(key, 0, KeyBytes);
200-
201-
let HASH_MAXIMUM = 0x1000000000000000000000000000000000000000000000000000000000000 - 1;
202-
let two_pow_216 = 0x100000000000000000000000000000000000000000000000000000000;
203-
204-
let keyhash = keyhash + self.root_id * two_pow_216;
205-
206-
// Safety: The assertion below checks that the keyhash is stored in the the index returned by the unconstrained function
207-
let search_result =
208-
unsafe { search_for_key_in_map::<MaxNumValues>(self.key_hashes, keyhash) };
209-
if search_result.found {
210-
assert_eq(search_result.lhs_index, search_result.rhs_index);
211-
}
212-
213-
let found = search_result.found as Field;
214-
215-
let target_lt_smallest_entry = search_result.target_lt_smallest_entry as Field;
216-
let target_gt_largest_entry = search_result.target_gt_largest_entry as Field;
217-
218-
// only one of "found", "target_lt_smallest_entry", "target_gt_largest_entry" can be true
219-
let exclusion_test = found + target_gt_largest_entry + target_lt_smallest_entry;
220-
assert(exclusion_test * exclusion_test == exclusion_test);
221-
222-
let mut lhs = self.key_hashes[search_result.lhs_index];
223-
let mut rhs = self.key_hashes[search_result.rhs_index];
224-
225-
// case where hash < self.key_hashes[0]
226-
// 0 < hash < hashes[0]
227-
lhs = lhs * (1 - target_lt_smallest_entry);
228-
229-
// case where hash > self.key_hashes[last]
230-
// largest < x < -1
231-
rhs = rhs * (1 - target_gt_largest_entry) + target_gt_largest_entry * HASH_MAXIMUM;
232-
233-
// case where hash == self.key_hashes[found_index]
234-
lhs = lhs - found;
235-
rhs = rhs + found;
236-
237-
assert_gt_240_bit(keyhash, lhs);
238-
assert_lt_240_bit(keyhash, rhs);
239-
240-
(search_result.found, search_result.lhs_index)
159+
self.key_exists_impl_var(BoundedVec::from_parts_unchecked(key, KeyBytes))
241160
}
242161

243162
/**

0 commit comments

Comments
 (0)