From 465303cb99cb02fbd6fb81ef3ad6f7b43b4935b4 Mon Sep 17 00:00:00 2001 From: Thierry Treyer Date: Thu, 7 Sep 2023 12:07:14 -0700 Subject: [PATCH] Implement new container for F14ValueMap --- dev.oid.toml | 1 + test/ci.oid.toml | 1 + test/integration/folly_f14_value_map.toml | 78 ++++++++++++++ types/f14_value_map.toml | 124 ++++++++++++++++++++++ 4 files changed, 204 insertions(+) create mode 100644 test/integration/folly_f14_value_map.toml create mode 100644 types/f14_value_map.toml diff --git a/dev.oid.toml b/dev.oid.toml index 7bc40d8..1718a30 100644 --- a/dev.oid.toml +++ b/dev.oid.toml @@ -36,6 +36,7 @@ containers = [ "PWD/types/small_vec_type.toml", "PWD/types/f14_fast_map.toml", "PWD/types/f14_node_map.toml", + "PWD/types/f14_value_map.toml", "PWD/types/f14_vector_map.toml", "PWD/types/f14_fast_set.toml", "PWD/types/f14_node_set.toml", diff --git a/test/ci.oid.toml b/test/ci.oid.toml index 978a17b..f5b4287 100644 --- a/test/ci.oid.toml +++ b/test/ci.oid.toml @@ -32,6 +32,7 @@ containers = [ "../types/small_vec_type.toml", "../types/f14_fast_map.toml", "../types/f14_node_map.toml", + "../types/f14_value_map.toml", "../types/f14_vector_map.toml", "../types/f14_fast_set.toml", "../types/f14_node_set.toml", diff --git a/test/integration/folly_f14_value_map.toml b/test/integration/folly_f14_value_map.toml new file mode 100644 index 0000000..3c69703 --- /dev/null +++ b/test/integration/folly_f14_value_map.toml @@ -0,0 +1,78 @@ +includes = ["folly/container/F14Map.h"] +definitions = ''' + struct Bar { + float a, b; + }; + + struct Foo { + folly::F14ValueMap m1; + folly::F14ValueMap m2; + folly::F14ValueMap m3; + folly::F14ValueMap m4; + }; +''' + +[cases] + [cases.a] + param_types = ["const Foo&"] + setup = ''' + Foo foo; + + foo.m1.reserve(3); + for (int i = 0; i < 3; i++) { + foo.m1.emplace(i, i); + } + + foo.m2.reserve(5); + for (int i = 0; i < 5; i++) { + foo.m2.emplace(i, Bar{0.0f, 0.0f}); + } + + foo.m3.reserve(7); + for (int i = 0; i < 7; i++) { + foo.m3.emplace(i, i); + } + + foo.m4.reserve(9); + for (int i = 0; i < 9; i++) { + foo.m4.emplace(i, i); + } + + return {foo}; + ''' + expect_json = '''[{ + "staticSize":96, + "dynamicSize":304, + "members":[ + {"name":"m1", "staticSize":24, "dynamicSize":48, "length":3, "capacity":3, "elementStaticSize":8}, + { + "name":"m2", + "staticSize":24, + "dynamicSize":80, + "length":5, + "capacity":5, + "elementStaticSize":12, + "members":[ + {"staticSize": 4}, + {"staticSize":8, "members":[{"name":"a"}, {"name": "b"}]}, + {"staticSize": 4}, + {"staticSize":8, "members":[{"name":"a"}, {"name": "b"}]}, + {"staticSize": 4}, + {"staticSize":8, "members":[{"name":"a"}, {"name": "b"}]}, + {"staticSize": 4}, + {"staticSize":8, "members":[{"name":"a"}, {"name": "b"}]}, + {"staticSize": 4}, + {"staticSize":8, "members":[{"name":"a"}, {"name": "b"}]} + ]}, + {"name":"m3", "staticSize":24, "dynamicSize":80, "length":7, "capacity":7, "elementStaticSize":8}, + {"name":"m4", "staticSize":24, "dynamicSize":96, "length":9, "capacity":9, "elementStaticSize":8} + ]}]''' + expect_json_v2 = '''[{ + "staticSize":96, + "exclusiveSize": 0, + "members":[ + {"name":"m1", "staticSize":24, "exclusiveSize": 24, "length": 3, "capacity": 3}, + {"name":"m2", "staticSize":24, "exclusiveSize": 24, "length": 5, "capacity": 5}, + {"name":"m3", "staticSize":24, "exclusiveSize": 24, "length": 7, "capacity": 7}, + {"name":"m4", "staticSize":24, "exclusiveSize": 24, "length": 9, "capacity": 9} + ]}]''' diff --git a/types/f14_value_map.toml b/types/f14_value_map.toml new file mode 100644 index 0000000..bf8511c --- /dev/null +++ b/types/f14_value_map.toml @@ -0,0 +1,124 @@ +[info] +type_name = "folly::F14ValueMap" +stub_template_params = [2,3,4] +ctype = "F14_MAP" +header = "folly/container/F14Map.h" + +# Old: +typeName = "folly::F14ValueMap<" +ns = ["folly::F14ValueMap"] +numTemplateParams = 2 +replaceTemplateParamIndex = [2, 3] +allocatorIndex = 4 + +[codegen] +decl = """ +template +void getSizeType(const %1% &container, size_t& dataSegOffset); +""" + +func = """ +template +void getSizeType(const %1% &container, size_t& returnArg) +{ + size_t memorySize = container.getAllocatedMemorySize(); + SAVE_SIZE(sizeof(%1%) + memorySize); + + SAVE_DATA(memorySize); + SAVE_DATA(container.bucket_count()); + SAVE_DATA(container.size()); + + // The double ampersand is needed otherwise this loop doesn't work with vector + for (auto&& it: container) { + getSizeType(it.first, returnArg); + getSizeType(it.second, returnArg); + } +} +""" + +handler = """ +template +struct TypeHandler> { + using type = types::st::Pair, + types::st::Pair, + types::st::List::type, + typename TypeHandler::type>>>>; + + static types::st::Unit getSizeType( + const %1%& container, + typename TypeHandler>::type returnArg) { + size_t memorySize = container.getAllocatedMemorySize(); + auto tail = returnArg + .write(memorySize) + .write(container.bucket_count()) + .write(container.size()); + + for (auto &&entry: container) { + tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) { + auto next = ret.delegate([&key](typename TypeHandler::type ret) { + return OIInternal::getSizeType(key, ret); + }); + return OIInternal::getSizeType(value, next); + }); + } + + return tail.finish(); + } +}; +""" + +traversal_func = """ +// TODO: This implementation enables the traversal of the container, +// but doesn't report the memory footprint accurately. +// Revisit this implementation and fix memory footprint reporting. +auto tail = returnArg + .write((uintptr_t)&container) + .write(container.size()); + +for (auto &&entry: container) { + tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) { + auto next = ret.delegate([&key](typename TypeHandler::type ret) { + return OIInternal::getSizeType(key, ret); + }); + return OIInternal::getSizeType(value, next); + }); +} + +return tail.finish(); +""" + +[[codegen.processor]] +type = "types::st::VarInt" +func = "el.pointer = std::get(d.val).value;" + +[[codegen.processor]] +type = """ +types::st::List::type, + typename TypeHandler::type>> +""" +func = """ +auto list = std::get(d.val); +el.container_stats.emplace(result::Element::ContainerStats { + .capacity = list.length, + .length = list.length, +}); + +static constexpr std::array element_fields{ + make_field("key"), + make_field("value"), +}; + +static constexpr inst::Field element{ + 0, 0, "[]", + std::array{}, + element_fields, + std::array{}, +}; + +for (size_t i = 0; i < list.length; i++) + ins.emplace(element); +"""