Skip to content

Commit 2d90375

Browse files
chore: remove methods from implementation (#81)
Co-authored-by: Tom French <[email protected]>
1 parent 6d190ca commit 2d90375

File tree

3 files changed

+234
-211
lines changed

3 files changed

+234
-211
lines changed

src/getters.nr

Lines changed: 120 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::_comparison_tools::lt::{assert_gt_240_bit, assert_lt_240_bit, lt_fiel
22
use crate::_string_tools::string_chopper::slice_string;
33
use crate::enums::Layer::ARRAY_LAYER;
44
use crate::json::JSON;
5-
use crate::json_entry::JSONEntry;
5+
use crate::json_entry::{JSONEntry, JSONEntryPacked};
66
use crate::keyhash::ByteHasher;
77
use crate::keymap::KeyIndexData;
88
use crate::utils::cast_num_to_u32;
@@ -57,7 +57,7 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
5757
let keyhash = keyhash + self.root_id * two_pow_216;
5858

5959
// Safety: The assertion below checks that the keyhash is stored in the the index returned by the unconstrained function
60-
let key_index = unsafe { self.find_key_in_map(keyhash) };
60+
let key_index = unsafe { find_key_in_map::<MaxNumValues>(self.key_hashes, keyhash) };
6161

6262
assert_eq(self.key_hashes[key_index], keyhash, "get_json_entry_unchecked: key not found");
6363
let entry: JSONEntry = self.json_entries_packed[key_index].into();
@@ -97,7 +97,7 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
9797
let keyhash = keyhash + self.root_id * two_pow_216;
9898

9999
// Safety: The assertion below checks that the keyhash is stored in the the index returned by the unconstrained function
100-
let key_index = unsafe { self.find_key_in_map(keyhash) };
100+
let key_index = unsafe { find_key_in_map::<MaxNumValues>(self.key_hashes, keyhash) };
101101

102102
assert_eq(self.key_hashes[key_index], keyhash, "get_json_entry_unchecked: key not found");
103103
let entry: JSONEntry = self.json_entries_packed[key_index].into();
@@ -121,7 +121,7 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
121121
let keyhash = keyhash + self.root_id * two_pow_216;
122122

123123
// Safety: The assertion below checks that the keyhash is stored in the the index returned by the unconstrained function
124-
let key_index = unsafe { self.find_key_in_map(keyhash) };
124+
let key_index = unsafe { find_key_in_map::<MaxNumValues>(self.key_hashes, keyhash) };
125125

126126
assert_eq(self.key_hashes[key_index], keyhash, "get_json_entry_unchecked: key not found");
127127
let entry: JSONEntry = self.json_entries_packed[key_index].into();
@@ -144,7 +144,7 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
144144
let keyhash = keyhash + self.root_id * two_pow_216;
145145

146146
// Safety: The assertion below checks that the keyhash is stored in the the index returned by the unconstrained function
147-
let key_index = unsafe { self.find_key_in_map(keyhash) };
147+
let key_index = unsafe { find_key_in_map::<MaxNumValues>(self.key_hashes, keyhash) };
148148

149149
assert_eq(self.key_hashes[key_index], keyhash, "get_json_entry_unchecked: key not found");
150150
let entry: JSONEntry = self.json_entries_packed[key_index].into();
@@ -173,82 +173,6 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
173173
result
174174
}
175175

176-
pub(crate) unconstrained fn find_key_in_map(self, target: Field) -> u32 {
177-
let mut found_index: u32 = 0;
178-
let mut found: bool = false;
179-
for i in 0..MaxNumValues {
180-
let key_hash = self.key_hashes[i];
181-
if (key_hash == target) {
182-
found_index = i;
183-
found = true;
184-
break;
185-
}
186-
}
187-
assert(found, "find_key_in_map, key not found");
188-
found_index
189-
}
190-
191-
/**
192-
* @brief figures out if `target` exists as a key in `self.key_hashes`
193-
* @details if `target` does not exist, we return the two indicies of adjacent
194-
* entries in `self.key_hashes`, lhs_index, rhs_index, where
195-
* lhs_index < key_hash < rhs_index
196-
**/
197-
pub(crate) unconstrained fn search_for_key_in_map(self, target: Field) -> KeySearchResult {
198-
let mut found_index: Field = 0;
199-
let mut found: bool = false;
200-
201-
let mut lhs_maximum: Field = 0;
202-
let mut rhs_minimum: Field = -1;
203-
let mut lhs_maximum_index: Field = 0;
204-
let mut rhs_minimum_index: Field = 0;
205-
for i in 0..MaxNumValues {
206-
let key_hash = self.key_hashes[i];
207-
if (key_hash == target) {
208-
found_index = i as Field;
209-
found = true;
210-
break;
211-
} else {
212-
if key_hash.lt(target) & (lhs_maximum.lt(key_hash)) {
213-
lhs_maximum = key_hash;
214-
lhs_maximum_index = i as Field;
215-
}
216-
if (target.lt(key_hash)) & (key_hash.lt(rhs_minimum)) {
217-
rhs_minimum = key_hash;
218-
rhs_minimum_index = i as Field;
219-
}
220-
}
221-
}
222-
let target_lt_smallest_entry = target.lt(self.key_hashes[0]);
223-
let target_gt_largest_entry = self.key_hashes[MaxNumValues - 1].lt(target);
224-
225-
let result_not_first_or_last =
226-
!target_lt_smallest_entry & !target_gt_largest_entry & !found;
227-
228-
let mut lhs_index = result_not_first_or_last as Field * lhs_maximum_index;
229-
let mut rhs_index = result_not_first_or_last as Field * rhs_minimum_index;
230-
231-
// if target_lt_smallest_entry, rhs_index = 0
232-
// if target_gt_largest_entry, lhs_index = TranscriptEntries - 1
233-
rhs_index = rhs_index * (1 - target_lt_smallest_entry as Field);
234-
235-
// we rely here on the fact that target_gt_largest_entry and result_not_first_or_last are mutually exclusive
236-
lhs_index = lhs_index + target_gt_largest_entry as Field * (MaxNumValues as Field - 1);
237-
238-
// If target is FOUND, we want the following:
239-
// keyhash[target_index] - 1 < hash < keyhash[target_index] + 1
240-
lhs_index = lhs_index + found as Field * found_index;
241-
rhs_index = rhs_index + found as Field * found_index;
242-
243-
KeySearchResult {
244-
found,
245-
target_lt_smallest_entry,
246-
target_gt_largest_entry,
247-
lhs_index: lhs_index as u32,
248-
rhs_index: rhs_index as u32,
249-
}
250-
}
251-
252176
/**
253177
* @brief returns a bool that describes whether a given key exists at the root of the JSON
254178
**/
@@ -280,7 +204,8 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
280204
let keyhash = keyhash + self.root_id * two_pow_216;
281205

282206
// Safety: The assertion below checks that the keyhash is stored in the the index returned by the unconstrained function
283-
let search_result = unsafe { self.search_for_key_in_map(keyhash) };
207+
let search_result =
208+
unsafe { search_for_key_in_map::<MaxNumValues>(self.key_hashes, keyhash) };
284209
if search_result.found {
285210
assert_eq(search_result.lhs_index, search_result.rhs_index);
286211
}
@@ -342,7 +267,8 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
342267
let keyhash = keyhash + self.root_id * two_pow_216;
343268

344269
// Safety: the assertion (search_result.lhs_index - search_result.rhs_index) * found == 0 constraints this function
345-
let search_result = unsafe { self.search_for_key_in_map(keyhash) };
270+
let search_result =
271+
unsafe { search_for_key_in_map::<MaxNumValues>(self.key_hashes, keyhash) };
346272
if search_result.found {
347273
assert_eq(search_result.lhs_index, search_result.rhs_index);
348274
}
@@ -376,33 +302,20 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
376302
(search_result.found, search_result.lhs_index)
377303
}
378304

379-
pub(crate) unconstrained fn __get_keys_at_root<let MaxNumKeys: u32>(
380-
self,
381-
) -> BoundedVec<Field, MaxNumKeys> {
382-
let root_object: JSONEntry =
383-
JSONEntry::from(self.json_entries_packed[self.root_index_in_transcript]);
384-
385-
let mut result_ptr = 0;
386-
let mut result: [Field; MaxNumKeys] = [0; MaxNumKeys];
387-
for i in 0..MaxNumValues {
388-
let target_entry: JSONEntry = JSONEntry::from(self.unsorted_json_entries_packed[i]);
389-
if (target_entry.parent_index == self.root_id) {
390-
result[result_ptr] = i as Field;
391-
result_ptr += 1;
392-
}
393-
}
394-
assert_eq(result_ptr as Field, root_object.num_children);
395-
396-
BoundedVec::from_parts_unchecked(result, result_ptr as u32)
397-
}
398-
399305
pub(crate) fn get_keys_at_root<let MaxNumKeys: u32, let MaxKeyBytes: u32>(
400306
self,
401307
) -> BoundedVec<BoundedVec<u8, MaxKeyBytes>, MaxNumKeys> {
402308
let root_object: JSONEntry =
403309
JSONEntry::from(self.json_entries_packed[self.root_index_in_transcript]);
404310
// Safety: the length of the index is constrained later.
405-
let key_indices: BoundedVec<Field, MaxNumKeys> = unsafe { self.__get_keys_at_root() };
311+
let key_indices: BoundedVec<Field, MaxNumKeys> = unsafe {
312+
__get_keys_at_root::<MaxNumKeys, MaxNumValues>(
313+
self.root_id,
314+
self.root_index_in_transcript,
315+
self.json_entries_packed,
316+
self.unsorted_json_entries_packed,
317+
)
318+
};
406319

407320
assert(key_indices.len() as Field == root_object.num_children);
408321

@@ -424,6 +337,109 @@ impl<let NumBytes: u32, let NumPackedFields: u32, let MaxNumTokens: u32, let Max
424337
}
425338
}
426339

340+
unconstrained fn find_key_in_map<let MaxNumValues: u32>(
341+
key_hashes: [Field; MaxNumValues],
342+
target: Field,
343+
) -> u32 {
344+
let mut found_index: u32 = 0;
345+
let mut found: bool = false;
346+
for i in 0..MaxNumValues {
347+
let key_hash = key_hashes[i];
348+
if (key_hash == target) {
349+
found_index = i;
350+
found = true;
351+
break;
352+
}
353+
}
354+
assert(found, "find_key_in_map, key not found");
355+
found_index
356+
}
357+
358+
/**
359+
* @brief figures out if `target` exists as a key in `self.key_hashes`
360+
* @details if `target` does not exist, we return the two indicies of adjacent
361+
* entries in `self.key_hashes`, lhs_index, rhs_index, where
362+
* lhs_index < key_hash < rhs_index
363+
**/
364+
unconstrained fn search_for_key_in_map<let MaxNumValues: u32>(
365+
key_hashes: [Field; MaxNumValues],
366+
target: Field,
367+
) -> KeySearchResult {
368+
let mut found_index: Field = 0;
369+
let mut found: bool = false;
370+
371+
let mut lhs_maximum: Field = 0;
372+
let mut rhs_minimum: Field = -1;
373+
let mut lhs_maximum_index: Field = 0;
374+
let mut rhs_minimum_index: Field = 0;
375+
for i in 0..MaxNumValues {
376+
let key_hash = key_hashes[i];
377+
if (key_hash == target) {
378+
found_index = i as Field;
379+
found = true;
380+
break;
381+
} else {
382+
if key_hash.lt(target) & (lhs_maximum.lt(key_hash)) {
383+
lhs_maximum = key_hash;
384+
lhs_maximum_index = i as Field;
385+
}
386+
if (target.lt(key_hash)) & (key_hash.lt(rhs_minimum)) {
387+
rhs_minimum = key_hash;
388+
rhs_minimum_index = i as Field;
389+
}
390+
}
391+
}
392+
let target_lt_smallest_entry = target.lt(key_hashes[0]);
393+
let target_gt_largest_entry = key_hashes[MaxNumValues - 1].lt(target);
394+
395+
let result_not_first_or_last = !target_lt_smallest_entry & !target_gt_largest_entry & !found;
396+
397+
let mut lhs_index = result_not_first_or_last as Field * lhs_maximum_index;
398+
let mut rhs_index = result_not_first_or_last as Field * rhs_minimum_index;
399+
400+
// if target_lt_smallest_entry, rhs_index = 0
401+
// if target_gt_largest_entry, lhs_index = TranscriptEntries - 1
402+
rhs_index = rhs_index * (1 - target_lt_smallest_entry as Field);
403+
404+
// we rely here on the fact that target_gt_largest_entry and result_not_first_or_last are mutually exclusive
405+
lhs_index = lhs_index + target_gt_largest_entry as Field * (MaxNumValues as Field - 1);
406+
407+
// If target is FOUND, we want the following:
408+
// keyhash[target_index] - 1 < hash < keyhash[target_index] + 1
409+
lhs_index = lhs_index + found as Field * found_index;
410+
rhs_index = rhs_index + found as Field * found_index;
411+
412+
KeySearchResult {
413+
found,
414+
target_lt_smallest_entry,
415+
target_gt_largest_entry,
416+
lhs_index: lhs_index as u32,
417+
rhs_index: rhs_index as u32,
418+
}
419+
}
420+
421+
unconstrained fn __get_keys_at_root<let MaxNumKeys: u32, let MaxNumValues: u32>(
422+
root_id: Field,
423+
root_index_in_transcript: u32,
424+
json_entries_packed: [JSONEntryPacked; MaxNumValues],
425+
unsorted_json_entries_packed: [JSONEntryPacked; MaxNumValues],
426+
) -> BoundedVec<Field, MaxNumKeys> {
427+
let root_object: JSONEntry = JSONEntry::from(json_entries_packed[root_index_in_transcript]);
428+
429+
let mut result_ptr = 0;
430+
let mut result: [Field; MaxNumKeys] = [0; MaxNumKeys];
431+
for i in 0..MaxNumValues {
432+
let target_entry: JSONEntry = JSONEntry::from(unsorted_json_entries_packed[i]);
433+
if (target_entry.parent_index == root_id) {
434+
result[result_ptr] = i as Field;
435+
result_ptr += 1;
436+
}
437+
}
438+
assert_eq(result_ptr as Field, root_object.num_children);
439+
440+
BoundedVec::from_parts_unchecked(result, result_ptr as u32)
441+
}
442+
427443
#[test]
428444
fn test_get_keys_at_root() {
429445
let s = "{ \"A\": 1, \"foo\": false, \"bar\": { \"one\" : \"A\", \"two\" : \"B\"}, \"baz\": \"12345\" }";

0 commit comments

Comments
 (0)