Crates.io | mapage |
lib.rs | mapage |
version | 0.2.0 |
source | src |
created_at | 2023-08-02 01:54:48.050148 |
updated_at | 2024-01-25 02:50:22.783437 |
description | In-memory type-namespaced key value storage with GraphQL |
homepage | https://coruscateor.com/projects/mapage |
repository | https://github.com/coruscateor/mapage |
max_upload_size | |
id | 932366 |
size | 842,369 |
Mapage is a type-namespaced key-value storage system which uses async-graphql for client interaction.
Basically what is meant by "type-namespaced" is each storable type gets its own hashmap and its own part of the API.
The namespaced-type design makes it reasonably straightforward to support different atomicity levels:
Level | Description |
---|---|
Store | Only one action (read or write) can be performed on the store per interaction. |
Namespace | Only one action can be performed on each individual namespace per interaction. |
Sub-Namespace | A section of the namespace is locked per interaction (buckets) |
Value | Each value is interacted with by each thread on an individual level and the namespace is seldom if ever locked |
In terms of features atomicity levels are divided into two broad categories:
Store level Feature |
---|
store_aml |
sub_store_aml |
With store_aml (store atomicity level) all the data is contained in a single synchronisation object e.g a Mutex or an Actor, but with the sub_store_aml (sub-store atomicity level) feature you have more discretion about how each namespace goes about handling user interaction.
store_aml is not implemented.
Once you've selected sub_store_aml you must select a default sore implementation feature:
Default Storage Implemtation Feature |
---|
scc_hashmap_namespaces |
dashmap_namespaces |
As you can probably sermise; when you select "scc_hashmap_namespaces" you get scc::Hashmap namespace implementations by default and when you select "dashmap_namespaces" you get Dashmap namespace implementations by default.
Select only one of these.
Feature | Description |
---|---|
store_aml | Store atomicity level |
sub_store_aml | Sub-store atomicity level |
scc_hashmap_namespaces | Use scc::Hashmap namespace implementations by default |
dashmap_namespaces | Use Dashmap namespace implementations by default |
all_types | All types |
char | char type |
f32 | f32 type |
f64 | f64 type |
i8 | i8 type |
i16 | i16 type |
i32 | i32 type |
i64 | Broken - incompatible with GraphQL/async-graphql |
i128 | Broken - incompatible with GraphQL/async-graphql |
isize | To be removed |
String | String type |
u8 | u8 type |
u16 | u16 type |
u32 | u32 type |
u64 | Broken - incompatible with GraphQL/async-graphql |
u128 | Broken - incompatible with GraphQL/async-graphql |
usize | To be removed |
Whatever | A GraphQL union of everything except SelectedType |
SelectedType | A GraphQL union of whatever else was selected except Whatever - To be removed |
Vec_bool | A std::vec::Vec of bools |
Vec_char | " chars |
Vec_f32 | " f32s |
Vec_f64 | " f64s |
Vec_i8 | " i8s |
Vec_i16 | " i16s |
Vec_i32 | " i32s |
Vec_i64 | Broken - incompatible with GraphQL/async-graphql |
Vec_i128 | Broken - incompatible with GraphQL/async-graphql |
Vec_isize | To be removed |
VecSelectedType | To be removed |
VecString | A std::vec::Vec of std::string::Strings |
Vec_u8 | " u8s |
Vec_u16 | " u16s |
Vec_u32 | " u32s |
Vec_u64 | Broken - incompatible with GraphQL/async-graphql |
Vec_u128 | Broken - incompatible with GraphQL/async-graphql |
Vec_usize | To be removed |
VecWhatever | A std::vec::Vec of Whatevers |
all_key_types_String | Use std::string::String keys by default |
all_key_types_Arc_String | Use std::sync::Arc containing std::string::String keys by default |
To be implemented
One with everything:
cargo build --features=sub_store_aml,scc_hashmap_namespaces,all_types,all_key_types_String
In the above build you have the "sub_store_aml" feature to indicate that each namespace handles synchronisation independently.
The "scc_hashmap_namespaces" feature indicates that you want the namespace implemtations to be scc::Hashmaps by default.
The "all_types" feature indicates that you want all the types that mappage supports to be inculded in the build.
Finally the "all_key_types_String" feature indicates that you want the keys for all the included types to be std::string::Strings by default.
Using the all_types feature, while convenient, will produce a mapage application with gigantic GraphQL API.
Why don't we try and be more a bit more selective:
cargo build --features=sub_store_aml,dashmap_namespaces,bool,char,i32,Whatever,all_key_types_String
Here instead of sub_store_aml, we have dashmap_namespaces for the namespace implementations.
And instead of all_types there are four individual types specified: bool, char, i32 and Whatever.
When you know what you want to store you'll avoid using space unnecessary and have a more consise API than you would've had selecting everything available.
To be explicit, in every build you need or should have specified:
Feature incompatabilty error conditions have not be implemented yet so you may have to do some reading if you get something wrong.
To be implemented
While you would implement the most optimal features for practical usage scenarios, sub-optimal features will also be added for curiositys sake.
Feature | Issue |
---|---|
i64 | Broken - incompatible with GraphQL/async-graphql |
i128 | Broken - incompatible with GraphQL/async-graphql |
isize | To be removed |
u64 | Broken - incompatible with GraphQL/async-graphql |
u128 | Broken - incompatible with GraphQL/async-graphql |
usize | To be removed |
SelectedType | A GraphQL union of whatever else was selected except Whatever - To be removed/disabled |
Vec_i64 | Broken - incompatible with GraphQL/async-graphql |
Vec_i128 | Broken - incompatible with GraphQL/async-graphql |
Vec_isize | To be removed |
VecSelectedType | To be removed/disabled |
Vec_u64 | Broken - incompatible with GraphQL/async-graphql |
Vec_u128 | Broken - incompatible with GraphQL/async-graphql |
Vec_usize | To be removed |
So GraphQL doesn't support intergers with sizes above 32 bits.
I'll implement a work around for this issue.
The isize and usize types are redundant.
SelectedType was implemented for an experiment in asynchronous queries.
I think I got to the trial implementation stage with this feature and I may revisit it so I'll remove SelectedType and VecSelectedType in the next version but keep the code in the repository.
In order to control the amount of work requred certain classes of type will and won't be implemented:
This project has come along way since its inception in mid-2022 as a Redis-like cache and it has a long way to go still. Please use with the understanding that this project is a work in progress.
The coding style of this project emphasises the use of white space over keeping the line and column counts low.
So this:
fn foo()
{
bar();
}
Not this:
fn foo()
{
bar();
}
Licensed under either of:
at your discretion
Please clone the repository and create an issue explaining what feature or features you'd like to add or bug or bugs you'd like to fix and perhaps how you intend to implement these additions or fixes. Try to include details though it doesn't need to be exhaustive and we'll take it from there (dependant on availability).
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.