feat(nano): implement fields module [part 5]#1280
Conversation
ccbd984 to
646105d
Compare
Codecov ReportAttention: Patch coverage is
❌ Your project status has failed because the head coverage (80.91%) is below the target coverage (82.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## master #1280 +/- ##
==========================================
- Coverage 81.57% 80.91% -0.66%
==========================================
Files 373 382 +9
Lines 26697 27231 +534
Branches 4060 4155 +95
==========================================
+ Hits 21778 22035 +257
- Misses 4188 4453 +265
- Partials 731 743 +12 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
646105d to
5a6ca04
Compare
5a6ca04 to
ded9471
Compare
72d6938 to
d2eaf78
Compare
| class TypeMap(NamedTuple): | ||
| alias_map: TypeAliasMap | ||
| nc_types_map: TypeToNCTypeMap | ||
| fields_map: TypeToFieldMap |
There was a problem hiding this comment.
I think these attributes need documentation.
| def __check_name_and_type__(cls, name: str, type_: type[Sequence[T]]) -> None: | ||
| if not name.isidentifier(): | ||
| raise TypeError('field name must be a valid identifier') | ||
| origin_type: type[Sequence[T]] = get_origin(type_) or type_ | ||
| if not issubclass(origin_type, Sequence): | ||
| raise TypeError('expected Sequence type') | ||
| args = get_args(type_) | ||
| if not args or len(args) != 1: | ||
| raise TypeError(f'expected {type_.__name__}[<item type>]') |
There was a problem hiding this comment.
Check that item type is serializable?
There was a problem hiding this comment.
I'm not sure we need to check this here, because this method is only called during creation of a Field instance, which is already only called when a field is serializable (that is, supported by our system). But maybe we indeed do for the type args of containers. Confirm this.
| def __to_db_key(self, index: SupportsIndex) -> bytes: | ||
| return f'{self.__name}{KEY_SEPARATOR}'.encode() + _INDEX_NC_TYPE.to_bytes(index.__index__()) |
There was a problem hiding this comment.
Why not int instead of SupportsIndex? It's more specific, and the _INDEX_NC_TYPE expects an int.
There was a problem hiding this comment.
Or maybe just assert int if we need this signature to satisfy mypy.
There was a problem hiding this comment.
The generic typing of deque and also other indexable container, use SupportsIndex for describing what types can be used, I've let this spill a bit into some methods (instead of immediately using index.__index__() to get an int) to simplify some implementations, but I guess it's fine to do the opposite and mostly use int and expose SupportsIndex only at the outer surfaces.
| self.__update_metadata(new_metadata) | ||
| return item | ||
|
|
||
| def __to_internal_index(self, *, index: SupportsIndex) -> int: |
There was a problem hiding this comment.
Same here (use int?).
| # XXX: what to do with this: | ||
| # __hash__: ClassVar[None] # type: ignore[assignment] |
There was a problem hiding this comment.
In the Deque field, it's uncommented.
|
| Branch | feat/nano/fields |
| Testbed | ubuntu-22.04 |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result minutes (m) (Result Δ%) | Lower Boundary minutes (m) (Limit %) | Upper Boundary minutes (m) (Limit %) |
|---|---|---|---|---|
| sync-v2 (up to 20000 blocks) | 📈 view plot 🚷 view threshold | 1.60 m(-1.72%)Baseline: 1.63 m | 1.47 m (91.57%) | 1.79 m (89.35%) |
jansegre
left a comment
There was a problem hiding this comment.
Currently I have changes that touch on all of the container fields, I will look at these comments to already implement at least the trivial fixes.
|
|
||
| DEFAULT_TYPE_TO_FIELD_MAP: TypeToFieldMap = { | ||
| dict: DictField, | ||
| list: DequeField, # XXX: we should really make a ListField, a deque is different from a list |
There was a problem hiding this comment.
I think we should do this. At least the "backend" implementation (how it maps the exposed interface to the storage) can be exactly the same, but Deque is not just the implementation it is the exposed interface, which IMO should be different when only a list (and not a deque), is requested.
| def __to_db_key(self, index: SupportsIndex) -> bytes: | ||
| return f'{self.__name}{KEY_SEPARATOR}'.encode() + _INDEX_NC_TYPE.to_bytes(index.__index__()) |
There was a problem hiding this comment.
The generic typing of deque and also other indexable container, use SupportsIndex for describing what types can be used, I've let this spill a bit into some methods (instead of immediately using index.__index__() to get an int) to simplify some implementations, but I guess it's fine to do the opposite and mostly use int and expose SupportsIndex only at the outer surfaces.
There was a problem hiding this comment.
For all container fields, review which methods we want to provide. See #1280 (comment)
|
LGTM ✅ |
Co-authored-by: Marcelo Salhab Brogliato <msbrogli@gmail.com> Co-authored-by: Jan Segre <jan@hathor.network>
Motivation
Implement Blueprint and fields module.
Acceptance Criteria
Implement Blueprint and fields module.
Checklist
master, confirm this code is production-ready and can be included in future releases as soon as it gets merged