-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: various helper functions and fixes for platform contested resources PR #307
Changes from 2 commits
c4201ed
a81de5e
8b09e18
a8f02d2
a62699d
2c0712b
9cd00f3
6af586b
9fd8410
1c7d13d
761d45a
1601625
a4c65ba
5f75f85
d23d181
44a357c
56b824c
17e9193
229b7f2
d7474f4
3e581c8
c3d78a3
ca40298
b297918
07a5a19
b2483a0
c66cb90
964809f
0b32606
8664b72
31b5d21
ea4bf6a
8886695
c46194e
cb03383
adb8fd1
d77bbf5
c0d810e
61dc98a
1696c2e
53642ed
36eb5a9
c44aec6
5fb76c0
27e9a67
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,12 +43,13 @@ use grovedb_merk::{ | |
#[cfg(feature = "full")] | ||
use integer_encoding::VarInt; | ||
|
||
#[cfg(any(feature = "full", feature = "verify"))] | ||
use crate::reference_path::{path_from_reference_path_type, ReferencePathType}; | ||
#[cfg(any(feature = "full", feature = "verify"))] | ||
use crate::{element::SUM_ITEM_COST_SIZE, Element, Error}; | ||
#[cfg(feature = "full")] | ||
use crate::{ | ||
element::{SUM_TREE_COST_SIZE, TREE_COST_SIZE}, | ||
reference_path::{path_from_reference_path_type, ReferencePathType}, | ||
ElementFlags, | ||
}; | ||
|
||
|
@@ -64,15 +65,41 @@ impl Element { | |
} | ||
|
||
#[cfg(any(feature = "full", feature = "verify"))] | ||
/// Decoded the integer value in the SumItem element type, returns 0 for | ||
/// everything else | ||
/// Decoded the integer value in the SumItem element type | ||
pub fn as_sum_item_value(&self) -> Result<i64, Error> { | ||
match self { | ||
Element::SumItem(value, _) => Ok(*value), | ||
_ => Err(Error::WrongElementType("expected a sum item")), | ||
} | ||
} | ||
|
||
#[cfg(any(feature = "full", feature = "verify"))] | ||
/// Decoded the integer value in the SumItem element type | ||
pub fn into_sum_item_value(self) -> Result<i64, Error> { | ||
match self { | ||
Element::SumItem(value, _) => Ok(value), | ||
_ => Err(Error::WrongElementType("expected a sum item")), | ||
} | ||
} | ||
|
||
#[cfg(any(feature = "full", feature = "verify"))] | ||
/// Decoded the integer value in the SumTree element type | ||
pub fn as_sum_tree_value(&self) -> Result<i64, Error> { | ||
match self { | ||
Element::SumTree(_, value, _) => Ok(*value), | ||
_ => Err(Error::WrongElementType("expected a sum tree")), | ||
} | ||
} | ||
|
||
#[cfg(any(feature = "full", feature = "verify"))] | ||
/// Decoded the integer value in the SumTree element type | ||
pub fn into_sum_tree_value(self) -> Result<i64, Error> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. |
||
match self { | ||
Element::SumTree(_, value, _) => Ok(value), | ||
_ => Err(Error::WrongElementType("expected a sum tree")), | ||
} | ||
} | ||
|
||
#[cfg(any(feature = "full", feature = "verify"))] | ||
/// Gives the item value in the Item element type | ||
pub fn as_item_bytes(&self) -> Result<&[u8], Error> { | ||
|
@@ -91,6 +118,15 @@ impl Element { | |
} | ||
} | ||
|
||
#[cfg(any(feature = "full", feature = "verify"))] | ||
/// Gives the reference path type in the Reference element type | ||
pub fn into_reference_path_type(self) -> Result<ReferencePathType, Error> { | ||
match self { | ||
Element::Reference(value, ..) => Ok(value), | ||
_ => Err(Error::WrongElementType("expected a reference")), | ||
} | ||
} | ||
|
||
#[cfg(any(feature = "full", feature = "verify"))] | ||
/// Check if the element is a sum tree | ||
pub fn is_sum_tree(&self) -> bool { | ||
|
@@ -103,6 +139,12 @@ impl Element { | |
matches!(self, Element::SumTree(..) | Element::Tree(..)) | ||
} | ||
|
||
#[cfg(any(feature = "full", feature = "verify"))] | ||
/// Check if the element is a reference | ||
pub fn is_reference(&self) -> bool { | ||
matches!(self, Element::Reference(..)) | ||
} | ||
|
||
#[cfg(any(feature = "full", feature = "verify"))] | ||
/// Check if the element is an item | ||
pub fn is_item(&self) -> bool { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,8 @@ use grovedb_costs::{ | |
#[cfg(feature = "full")] | ||
use integer_encoding::VarInt; | ||
|
||
#[cfg(feature = "full")] | ||
use crate::element::SumValue; | ||
use crate::{element::QueryOptions, query_result_type::PathKeyOptionalElementTrio}; | ||
#[cfg(feature = "full")] | ||
use crate::{ | ||
|
@@ -44,6 +46,16 @@ use crate::{ | |
Element, Error, GroveDb, PathQuery, TransactionArg, | ||
}; | ||
|
||
#[cfg(feature = "full")] | ||
#[derive(Debug, Eq, PartialEq, Clone)] | ||
/// A return type for query_item_value_or_sum | ||
pub enum QueryItemOrSumReturnType { | ||
/// an Item in serialized form | ||
ItemData(Vec<u8>), | ||
/// A sum item or a sum tree value | ||
SumValue(SumValue), | ||
} | ||
|
||
#[cfg(feature = "full")] | ||
impl GroveDb { | ||
/// Encoded query for multiple path queries | ||
|
@@ -190,10 +202,8 @@ where { | |
)), | ||
} | ||
} | ||
Element::Item(..) | Element::SumItem(..) => Ok(element), | ||
Element::Tree(..) | Element::SumTree(..) => Err(Error::InvalidQuery( | ||
"path_queries can only refer to items and references", | ||
)), | ||
Element::Item(..) | Element::SumItem(..) | Element::SumTree(..) => Ok(element), | ||
Element::Tree(..) => Err(Error::InvalidQuery("path_queries can not refer to trees")), | ||
} | ||
} | ||
|
||
|
@@ -309,6 +319,94 @@ where { | |
Ok((results, skipped)).wrap_with_cost(cost) | ||
} | ||
|
||
/// Queries the backing store and returns element items by their value, | ||
/// Sum Items are returned | ||
pub fn query_item_value_or_sum( | ||
&self, | ||
path_query: &PathQuery, | ||
allow_cache: bool, | ||
decrease_limit_on_range_with_no_sub_elements: bool, | ||
error_if_intermediate_path_tree_not_present: bool, | ||
transaction: TransactionArg, | ||
) -> CostResult<(Vec<QueryItemOrSumReturnType>, u16), Error> { | ||
let mut cost = OperationCost::default(); | ||
|
||
let (elements, skipped) = cost_return_on_error!( | ||
&mut cost, | ||
self.query_raw( | ||
path_query, | ||
allow_cache, | ||
decrease_limit_on_range_with_no_sub_elements, | ||
error_if_intermediate_path_tree_not_present, | ||
QueryResultType::QueryElementResultType, | ||
transaction | ||
) | ||
); | ||
|
||
let results_wrapped = elements | ||
.into_iterator() | ||
.map(|result_item| match result_item { | ||
QueryResultElement::ElementResultItem(element) => { | ||
match element { | ||
Element::Reference(reference_path, ..) => { | ||
match reference_path { | ||
ReferencePathType::AbsolutePathReference(absolute_path) => { | ||
// While `map` on iterator is lazy, we should accumulate costs | ||
// even if `collect` will | ||
// end in `Err`, so we'll use | ||
// external costs accumulator instead of | ||
// returning costs from `map` call. | ||
let maybe_item = self | ||
.follow_reference( | ||
absolute_path.as_slice().into(), | ||
allow_cache, | ||
transaction, | ||
) | ||
.unwrap_add_cost(&mut cost)?; | ||
|
||
match maybe_item { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think we shall stop with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't understand this comment. |
||
Element::Item(item, _) => { | ||
Ok(QueryItemOrSumReturnType::ItemData(item)) | ||
} | ||
Element::SumItem(sum_value, _) => { | ||
Ok(QueryItemOrSumReturnType::SumValue(sum_value)) | ||
} | ||
Element::SumTree(_, sum_value, _) => { | ||
Ok(QueryItemOrSumReturnType::SumValue(sum_value)) | ||
} | ||
_ => Err(Error::InvalidQuery( | ||
"the reference must result in an item", | ||
)), | ||
} | ||
} | ||
_ => Err(Error::CorruptedCodeExecution( | ||
"reference after query must have absolute paths", | ||
)), | ||
} | ||
} | ||
Element::Item(item, _) => Ok(QueryItemOrSumReturnType::ItemData(item)), | ||
Element::SumItem(sum_value, _) => { | ||
Ok(QueryItemOrSumReturnType::SumValue(sum_value)) | ||
} | ||
Element::SumTree(_, sum_value, _) => { | ||
Ok(QueryItemOrSumReturnType::SumValue(sum_value)) | ||
} | ||
Element::Tree(..) => Err(Error::InvalidQuery( | ||
"path_queries can only refer to items, sum items, references and sum \ | ||
trees", | ||
)), | ||
} | ||
} | ||
_ => Err(Error::CorruptedCodeExecution( | ||
"query returned incorrect result type", | ||
)), | ||
}) | ||
.collect::<Result<Vec<QueryItemOrSumReturnType>, Error>>(); | ||
|
||
let results = cost_return_on_error_no_add!(&cost, results_wrapped); | ||
Ok((results, skipped)).wrap_with_cost(cost) | ||
} | ||
|
||
/// Retrieves only SumItem elements that match a path query | ||
pub fn query_sums( | ||
&self, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the purpose of this method?
as_sum_item_value
is just fine because i64 isCopy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still should be faster right as you are not copying memory. I agree it's not very important though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It returns from the function so the stack frame is cleared and memory will be copied from there anyways, we're not avoiding memory copies by using
self
unless we doing so to avoid doing explicit cloningsThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look, it really doesn't matter, we have a lot of into and as. While I could remove this, I just don't think it matters, so I prefer to keep it.