From a070945bdfdd63cf52379614915d3d52913acdd9 Mon Sep 17 00:00:00 2001 From: Dmytro Sydorchenko Date: Sat, 29 Oct 2022 11:33:21 -0400 Subject: [PATCH 1/3] kv map proposal added --- kv/proposals/kv-map.md | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 kv/proposals/kv-map.md diff --git a/kv/proposals/kv-map.md b/kv/proposals/kv-map.md new file mode 100644 index 0000000..b9a31a6 --- /dev/null +++ b/kv/proposals/kv-map.md @@ -0,0 +1,49 @@ +# Proposal for new map data types for smart contract developers + +## Problem + +### Opportunity +Currently we do not have simple key value structure for managing database in smart contracts. At the moment this can be achieved with multi_index but with some level of verbocity. This proposal is to create new ordered and unordered map containers with interface similar to corresponding std containers. +### Target audience +- Contract developers +### Strategic alignment +There is a demand for simple key value structure in smart contracts. We can simplyfy smart contract code access to database mimicing std containers interface and step away from clanky lambdas that we need for setting values in multi_index + +## Solution + +### Solution name +Kv map +### Purpose +Set of map containers for managing chainbase database tables using standard std syntax +### Success definition +ordered and unordered map containers that implement basic std methods like begin/end, find, insert, square brackets operator, range based loop, etc. + +## Assumptions + +### Risks +We are going to implement from scratch map container and hash functions so need to have extensive unit tests and ensure performance is adequate + +## Functionality + +``` +using my_map_t = eosio::kv::unordered_map<"kvmap"_n, int, std::string>; + +my_map_t kvmap; +kvmap[1] = "str1"; +kvmap[2] = "str2"; +kvmap[3] = "str3"; + +assert(!kvmap.empty()); +assert(kvmap.size() == 3); +assert(kvmap.find(1)->value == "str1"); +assert(kvmap.find(2)->value == "str2"); +assert(kvmap.find(3)->value == "str3"); + +for (const auto& [key, value] : kvmap) { + eosio::print_f("% = %", k, v); +} + +kvmap.clear(); +assert(kvmap.empty()); + +``` \ No newline at end of file From fb786bd4fbefdb7c8dec7f8327f32fa2d44d3817 Mon Sep 17 00:00:00 2001 From: Dmytro Sydorchenko Date: Mon, 31 Oct 2022 12:37:42 -0400 Subject: [PATCH 2/3] proper code formatting added --- kv/proposals/kv-map.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kv/proposals/kv-map.md b/kv/proposals/kv-map.md index b9a31a6..0944237 100644 --- a/kv/proposals/kv-map.md +++ b/kv/proposals/kv-map.md @@ -25,7 +25,7 @@ We are going to implement from scratch map container and hash functions so need ## Functionality -``` +```c++ using my_map_t = eosio::kv::unordered_map<"kvmap"_n, int, std::string>; my_map_t kvmap; From 1f31d0ffce27a5bbb8ff3d31f2a0decf780fbad1 Mon Sep 17 00:00:00 2001 From: Dmytro Sydorchenko Date: Thu, 10 Nov 2022 14:11:18 -0500 Subject: [PATCH 3/3] implementation details added to kv map --- kv/proposals/kv-map.md | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/kv/proposals/kv-map.md b/kv/proposals/kv-map.md index 0944237..f4a517e 100644 --- a/kv/proposals/kv-map.md +++ b/kv/proposals/kv-map.md @@ -7,37 +7,40 @@ Currently we do not have simple key value structure for managing database in sma ### Target audience - Contract developers ### Strategic alignment -There is a demand for simple key value structure in smart contracts. We can simplyfy smart contract code access to database mimicing std containers interface and step away from clanky lambdas that we need for setting values in multi_index +There is a demand for simple key value structure in smart contracts. We can simplyfy smart contract code access to database mimicing std containers interface and step away from clanky lambdas that we need for setting values in `multi_index`. We also expect better performance for those new containers. ## Solution ### Solution name -Kv map +KV map ### Purpose -Set of map containers for managing chainbase database tables using standard std syntax +Set of map containers for managing chainbase database tables using standard std syntax and improved performance. ### Success definition -ordered and unordered map containers that implement basic std methods like begin/end, find, insert, square brackets operator, range based loop, etc. +Ordered and unordered map containers that implement basic std methods like begin/end, find, insert, square brackets operator, range based loop, etc. +### Implementation details +We are planning to use same database host functions as `multi_index` does (`db_store_i64`, `db_update_i64`, etc.). Internally `unordered_map` won't be traditional hash map but some hybrid of ordered and unordered maps. We are planning to use `uint64` hashes as a keys for entries. Hash will be cross platform solution for prospective usage in other than c++ languages. The purpose behind this is performance since `uint64` index is faster than byte array. There won't be buckets structure where traditional hash maps use more memory. For X enties there will be X table rows. No rehashes. Collision chance expected to be nearly zero since we will use origin 8 byte hashes that are not converted to array index. For ordered map we will introduce new host functions to use byte array as an index. Ordered map will have CPU tradeoff due to byte array index so unordered map is suggested to be used where order is not important. + ## Assumptions ### Risks -We are going to implement from scratch map container and hash functions so need to have extensive unit tests and ensure performance is adequate +We are going to implement from scratch map containers so need to have extensive unit tests and ensure performance is adequate ## Functionality ```c++ -using my_map_t = eosio::kv::unordered_map<"kvmap"_n, int, std::string>; +using my_map_t = eosio::unordered_map<"kvmap"_n, std::string, std::string>; my_map_t kvmap; -kvmap[1] = "str1"; -kvmap[2] = "str2"; -kvmap[3] = "str3"; +kvmap["key1"] = "val1"; +kvmap["key2"] = "val2"; +kvmap["key3"] = "val3"; assert(!kvmap.empty()); assert(kvmap.size() == 3); -assert(kvmap.find(1)->value == "str1"); -assert(kvmap.find(2)->value == "str2"); -assert(kvmap.find(3)->value == "str3"); +assert(kvmap.find("key1")->value == "val1"); +assert(kvmap.find("key2")->value == "val2"); +assert(kvmap.find("key3")->value == "val3"); for (const auto& [key, value] : kvmap) { eosio::print_f("% = %", k, v);