diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..443add7a4 --- /dev/null +++ b/.clang-format @@ -0,0 +1,102 @@ +--- +# clang-format configuration for linksplatform/Data.Doublets C++ code +Language: Cpp +BasedOnStyle: LLVM + +# Basic formatting options +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +ColumnLimit: 120 +MaxEmptyLinesToKeep: 2 + +# Indentation +AccessModifierOffset: -4 +IndentAccessModifiers: false +IndentCaseLabels: true +IndentWrappedFunctionNames: false +IndentPPDirectives: None +NamespaceIndentation: None + +# Alignment +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true + +# Allow/breaking rules +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes + +# Binary operators +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon + +# Braces +BreakBeforeBraces: Allman +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false + +# Constructor initializers +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 + +# Includes +IncludeBlocks: Preserve +SortIncludes: true + +# Penalties (for line breaking decisions) +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 + +# Pointers and references +PointerAlignment: Left +DerivePointerAlignment: false + +# Spaces +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false + +# Standard +Standard: c++17 \ No newline at end of file diff --git a/c/ffi.h b/c/ffi.h index be321585d..0883259b1 100644 --- a/c/ffi.h +++ b/c/ffi.h @@ -5,48 +5,53 @@ #include #include -typedef struct Link_u8 { +typedef struct Link_u8 +{ uint8_t index; uint8_t source; uint8_t target; } Link_u8; -typedef uint8_t (* CUDCallback_u8)(struct Link_u8 before, struct Link_u8 after); +typedef uint8_t (*CUDCallback_u8)(struct Link_u8 before, struct Link_u8 after); -typedef struct Link_u16 { +typedef struct Link_u16 +{ uint16_t index; uint16_t source; uint16_t target; } Link_u16; -typedef uint16_t (* CUDCallback_u16)(struct Link_u16 before, struct Link_u16 after); +typedef uint16_t (*CUDCallback_u16)(struct Link_u16 before, struct Link_u16 after); -typedef struct Link_u32 { +typedef struct Link_u32 +{ uint32_t index; uint32_t source; uint32_t target; } Link_u32; -typedef uint32_t (* CUDCallback_u32)(struct Link_u32 before, struct Link_u32 after); +typedef uint32_t (*CUDCallback_u32)(struct Link_u32 before, struct Link_u32 after); -typedef struct Link_u64 { +typedef struct Link_u64 +{ uint64_t index; uint64_t source; uint64_t target; } Link_u64; -typedef uint64_t (* CUDCallback_u64)(struct Link_u64 before, struct Link_u64 after); +typedef uint64_t (*CUDCallback_u64)(struct Link_u64 before, struct Link_u64 after); -typedef uint8_t (* EachCallback_u8)(struct Link_u8); +typedef uint8_t (*EachCallback_u8)(struct Link_u8); -typedef uint16_t (* EachCallback_u16)(struct Link_u16); +typedef uint16_t (*EachCallback_u16)(struct Link_u16); -typedef uint32_t (* EachCallback_u32)(struct Link_u32); +typedef uint32_t (*EachCallback_u32)(struct Link_u32); -typedef uint64_t (* EachCallback_u64)(struct Link_u64); +typedef uint64_t (*EachCallback_u64)(struct Link_u64); -typedef struct SharedLogger { - void (* formatter)(const Record*); +typedef struct SharedLogger +{ + void (*formatter)(const Record*); } SharedLogger; void* ByteUnitedMemoryLinks_New(const char* path); @@ -65,45 +70,21 @@ void UInt32UnitedMemoryLinks_Drop(void* this_); void UInt64UnitedMemoryLinks_Drop(void* this_); -uint8_t ByteUnitedMemoryLinks_Create(void* this_, - const uint8_t* query, - uintptr_t len, - CUDCallback_u8 callback); - -uint16_t UInt16UnitedMemoryLinks_Create(void* this_, - const uint16_t* query, - uintptr_t len, - CUDCallback_u16 callback); - -uint32_t UInt32UnitedMemoryLinks_Create(void* this_, - const uint32_t* query, - uintptr_t len, - CUDCallback_u32 callback); - -uint64_t UInt64UnitedMemoryLinks_Create(void* this_, - const uint64_t* query, - uintptr_t len, - CUDCallback_u64 callback); - -uint8_t ByteUnitedMemoryLinks_Each(void* this_, - const uint8_t* query, - uintptr_t len, - EachCallback_u8 callback); - -uint16_t UInt16UnitedMemoryLinks_Each(void* this_, - const uint16_t* query, - uintptr_t len, - EachCallback_u16 callback); - -uint32_t UInt32UnitedMemoryLinks_Each(void* this_, - const uint32_t* query, - uintptr_t len, - EachCallback_u32 callback); - -uint64_t UInt64UnitedMemoryLinks_Each(void* this_, - const uint64_t* query, - uintptr_t len, - EachCallback_u64 callback); +uint8_t ByteUnitedMemoryLinks_Create(void* this_, const uint8_t* query, uintptr_t len, CUDCallback_u8 callback); + +uint16_t UInt16UnitedMemoryLinks_Create(void* this_, const uint16_t* query, uintptr_t len, CUDCallback_u16 callback); + +uint32_t UInt32UnitedMemoryLinks_Create(void* this_, const uint32_t* query, uintptr_t len, CUDCallback_u32 callback); + +uint64_t UInt64UnitedMemoryLinks_Create(void* this_, const uint64_t* query, uintptr_t len, CUDCallback_u64 callback); + +uint8_t ByteUnitedMemoryLinks_Each(void* this_, const uint8_t* query, uintptr_t len, EachCallback_u8 callback); + +uint16_t UInt16UnitedMemoryLinks_Each(void* this_, const uint16_t* query, uintptr_t len, EachCallback_u16 callback); + +uint32_t UInt32UnitedMemoryLinks_Each(void* this_, const uint32_t* query, uintptr_t len, EachCallback_u32 callback); + +uint64_t UInt64UnitedMemoryLinks_Each(void* this_, const uint64_t* query, uintptr_t len, EachCallback_u64 callback); uint8_t ByteUnitedMemoryLinks_Count(void* this_, const uint8_t* query, uintptr_t len); @@ -113,53 +94,25 @@ uint32_t UInt32UnitedMemoryLinks_Count(void* this_, const uint32_t* query, uintp uint64_t UInt64UnitedMemoryLinks_Count(void* this_, const uint64_t* query, uintptr_t len); -uint8_t ByteUnitedMemoryLinks_Update(void* this_, - const uint8_t* query, - uintptr_t len_q, - const uint8_t* replacement, - uintptr_t len_r, - CUDCallback_u8 callback); - -uint16_t UInt16UnitedMemoryLinks_Update(void* this_, - const uint16_t* query, - uintptr_t len_q, - const uint16_t* replacement, - uintptr_t len_r, - CUDCallback_u16 callback); - -uint32_t UInt32UnitedMemoryLinks_Update(void* this_, - const uint32_t* query, - uintptr_t len_q, - const uint32_t* replacement, - uintptr_t len_r, - CUDCallback_u32 callback); - -uint64_t UInt64UnitedMemoryLinks_Update(void* this_, - const uint64_t* query, - uintptr_t len_q, - const uint64_t* replacement, - uintptr_t len_r, - CUDCallback_u64 callback); - -uint8_t ByteUnitedMemoryLinks_Delete(void* this_, - const uint8_t* query, - uintptr_t len, - CUDCallback_u8 callback); - -uint16_t UInt16UnitedMemoryLinks_Delete(void* this_, - const uint16_t* query, - uintptr_t len, - CUDCallback_u16 callback); - -uint32_t UInt32UnitedMemoryLinks_Delete(void* this_, - const uint32_t* query, - uintptr_t len, - CUDCallback_u32 callback); - -uint64_t UInt64UnitedMemoryLinks_Delete(void* this_, - const uint64_t* query, - uintptr_t len, - CUDCallback_u64 callback); +uint8_t ByteUnitedMemoryLinks_Update(void* this_, const uint8_t* query, uintptr_t len_q, const uint8_t* replacement, + uintptr_t len_r, CUDCallback_u8 callback); + +uint16_t UInt16UnitedMemoryLinks_Update(void* this_, const uint16_t* query, uintptr_t len_q, + const uint16_t* replacement, uintptr_t len_r, CUDCallback_u16 callback); + +uint32_t UInt32UnitedMemoryLinks_Update(void* this_, const uint32_t* query, uintptr_t len_q, + const uint32_t* replacement, uintptr_t len_r, CUDCallback_u32 callback); + +uint64_t UInt64UnitedMemoryLinks_Update(void* this_, const uint64_t* query, uintptr_t len_q, + const uint64_t* replacement, uintptr_t len_r, CUDCallback_u64 callback); + +uint8_t ByteUnitedMemoryLinks_Delete(void* this_, const uint8_t* query, uintptr_t len, CUDCallback_u8 callback); + +uint16_t UInt16UnitedMemoryLinks_Delete(void* this_, const uint16_t* query, uintptr_t len, CUDCallback_u16 callback); + +uint32_t UInt32UnitedMemoryLinks_Delete(void* this_, const uint32_t* query, uintptr_t len, CUDCallback_u32 callback); + +uint64_t UInt64UnitedMemoryLinks_Delete(void* this_, const uint64_t* query, uintptr_t len, CUDCallback_u64 callback); void setup_shared_logger(struct SharedLogger logger); diff --git a/cpp/Platform.Data.Doublets.Benchmarks/AllBenchmarks.cpp b/cpp/Platform.Data.Doublets.Benchmarks/AllBenchmarks.cpp index 13f3c9c2e..19f6d40ad 100644 --- a/cpp/Platform.Data.Doublets.Benchmarks/AllBenchmarks.cpp +++ b/cpp/Platform.Data.Doublets.Benchmarks/AllBenchmarks.cpp @@ -1,7 +1,7 @@ -#include -#include -//#include "MemoryBenchmarks.cpp" -#include "CreateMillionPointsBenchmarks.cpp" +#include +#include +// #include "MemoryBenchmarks.cpp" #include "CheckDefaultHandlerOrJustCallBenchmarks.cpp" +#include "CreateMillionPointsBenchmarks.cpp" BENCHMARK_MAIN(); diff --git a/cpp/Platform.Data.Doublets.Benchmarks/CheckDefaultHandlerOrJustCallBenchmarks.cpp b/cpp/Platform.Data.Doublets.Benchmarks/CheckDefaultHandlerOrJustCallBenchmarks.cpp index e2053f887..aaf7718a3 100644 --- a/cpp/Platform.Data.Doublets.Benchmarks/CheckDefaultHandlerOrJustCallBenchmarks.cpp +++ b/cpp/Platform.Data.Doublets.Benchmarks/CheckDefaultHandlerOrJustCallBenchmarks.cpp @@ -1,72 +1,75 @@ namespace Platform::Data::Doublets::Benchmarks { - using TLinkAddress = std::uint64_t; - constexpr auto DefaultHandler = [](TLinkAddress source, TLinkAddress target){return 1;}; +using TLinkAddress = std::uint64_t; +constexpr auto DefaultHandler = [](TLinkAddress source, TLinkAddress target) { return 1; }; - TLinkAddress CheckDefaultHandlerAndCallHandler(TLinkAddress source, TLinkAddress target, auto&& handler) +TLinkAddress CheckDefaultHandlerAndCallHandler(TLinkAddress source, TLinkAddress target, auto&& handler) +{ + if (DefaultHandler == handler) { - if(DefaultHandler == handler) - { - return 1; - } - else - { - return handler(source, target); - } + return 1; } - - TLinkAddress CallHandler(TLinkAddress source, TLinkAddress target, auto&& handler) + else { return handler(source, target); } +} + +TLinkAddress CallHandler(TLinkAddress source, TLinkAddress target, auto&& handler) +{ + return handler(source, target); +} - static void BM_CheckDefaultHandlerAndSumWithoutOptimization(benchmark::State& state) +static void BM_CheckDefaultHandlerAndSumWithoutOptimization(benchmark::State& state) +{ + for (auto _ : state) { - for(auto _ : state) + for (auto i = 0; i < state.range(0); ++i) { - for(auto i = 0; i < state.range(0); ++i) - { - benchmark::DoNotOptimize(CheckDefaultHandlerAndCallHandler(TLinkAddress{10}, TLinkAddress{10}, [](TLinkAddress source, TLinkAddress target ){return 1;})); - } + benchmark::DoNotOptimize(CheckDefaultHandlerAndCallHandler( + TLinkAddress{10}, TLinkAddress{10}, [](TLinkAddress source, TLinkAddress target) { return 1; })); } } +} - static void BM_JustCallHandlerWithoutOptimization(benchmark::State& state) +static void BM_JustCallHandlerWithoutOptimization(benchmark::State& state) +{ + for (auto _ : state) { - for(auto _ : state) + for (auto i = 0; i < state.range(0); ++i) { - for(auto i = 0; i < state.range(0); ++i) - { - benchmark::DoNotOptimize(CallHandler(TLinkAddress{10}, TLinkAddress{10}, [](TLinkAddress source, TLinkAddress target ){return 1;})); - } + benchmark::DoNotOptimize(CallHandler(TLinkAddress{10}, TLinkAddress{10}, + [](TLinkAddress source, TLinkAddress target) { return 1; })); } } +} - static void BM_CheckDefaultHandlerAndSum(benchmark::State& state) +static void BM_CheckDefaultHandlerAndSum(benchmark::State& state) +{ + for (auto _ : state) { - for(auto _ : state) + for (auto i = 0; i < state.range(0); ++i) { - for(auto i = 0; i < state.range(0); ++i) - { - CheckDefaultHandlerAndCallHandler(TLinkAddress{10}, TLinkAddress{10}, [](TLinkAddress source, TLinkAddress target ){return 1;}); - } + CheckDefaultHandlerAndCallHandler(TLinkAddress{10}, TLinkAddress{10}, + [](TLinkAddress source, TLinkAddress target) { return 1; }); } } +} - static void BM_JustCallHandler(benchmark::State& state) +static void BM_JustCallHandler(benchmark::State& state) +{ + for (auto _ : state) { - for(auto _ : state) + for (auto i = 0; i < state.range(0); ++i) { - for(auto i = 0; i < state.range(0); ++i) - { - CallHandler(TLinkAddress{10}, TLinkAddress{10}, [](TLinkAddress source, TLinkAddress target ){return 1;}); - } + CallHandler(TLinkAddress{10}, TLinkAddress{10}, [](TLinkAddress source, TLinkAddress target) { return 1; }); } } +} - BENCHMARK(BM_CheckDefaultHandlerAndSumWithoutOptimization)->Arg(1000000); - BENCHMARK(BM_JustCallHandlerWithoutOptimization)->Arg(1000000); - BENCHMARK(BM_CheckDefaultHandlerAndSum)->Arg(1000000); - BENCHMARK(BM_JustCallHandler)->Arg(1000000); +BENCHMARK(BM_CheckDefaultHandlerAndSumWithoutOptimization)->Arg(1000000); +BENCHMARK(BM_JustCallHandlerWithoutOptimization)->Arg(1000000); +BENCHMARK(BM_CheckDefaultHandlerAndSum)->Arg(1000000); +BENCHMARK(BM_JustCallHandler)->Arg(1000000); -} +} // namespace Platform::Data::Doublets::Benchmarks diff --git a/cpp/Platform.Data.Doublets.Benchmarks/CreateMillionPointsBenchmarks.cpp b/cpp/Platform.Data.Doublets.Benchmarks/CreateMillionPointsBenchmarks.cpp index d0d3d8520..80f24a5e1 100644 --- a/cpp/Platform.Data.Doublets.Benchmarks/CreateMillionPointsBenchmarks.cpp +++ b/cpp/Platform.Data.Doublets.Benchmarks/CreateMillionPointsBenchmarks.cpp @@ -1,84 +1,87 @@ namespace Platform::Data::Doublets::Benchmarks { - using TLinkAddress = std::uint64_t; +using TLinkAddress = std::uint64_t; - // static void BM_CreateMillionPointsFfi(benchmark::State& state) - // { - // using namespace Platform::Memory; - // using namespace Platform::Data::Doublets::Ffi; - // for (auto _ : state) - // { - // std::string memoryFilePath{ std::tmpnam(nullptr) }; - // Expects(!Collections::IsWhiteSpace(memoryFilePath)); - // try - // { - // Links> ffiStorage{memoryFilePath}; - // for (std::size_t i = 0; i < state.range(0); ++i) - // { - // CreatePoint(ffiStorage); - // } - // } - // catch (...) - // { - // std::remove(memoryFilePath.c_str()); - // throw; - // } - // std::remove(memoryFilePath.c_str()); - // } - // } +// static void BM_CreateMillionPointsFfi(benchmark::State& state) +// { +// using namespace Platform::Memory; +// using namespace Platform::Data::Doublets::Ffi; +// for (auto _ : state) +// { +// std::string memoryFilePath{ std::tmpnam(nullptr) }; +// Expects(!Collections::IsWhiteSpace(memoryFilePath)); +// try +// { +// Links> ffiStorage{memoryFilePath}; +// for (std::size_t i = 0; i < state.range(0); ++i) +// { +// CreatePoint(ffiStorage); +// } +// } +// catch (...) +// { +// std::remove(memoryFilePath.c_str()); +// throw; +// } +// std::remove(memoryFilePath.c_str()); +// } +// } - static void BM_CreateMillionPointsUnitedMemory(benchmark::State& state) +static void BM_CreateMillionPointsUnitedMemory(benchmark::State& state) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + for (auto _ : state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - for (auto _ : state) + std::string memoryFilePath{std::tmpnam(nullptr)}; + Expects(!Collections::IsWhiteSpace(memoryFilePath)); + try { - std::string memoryFilePath{ std::tmpnam(nullptr) }; - Expects(!Collections::IsWhiteSpace(memoryFilePath)); - try - { - UnitedMemoryLinks, FileMappedResizableDirectMemory> storage{FileMappedResizableDirectMemory{memoryFilePath}}; - for (std::size_t i = 0; i < state.range(0); ++i) - { - CreatePoint(storage); - } - } - catch (...) + UnitedMemoryLinks, FileMappedResizableDirectMemory> storage{ + FileMappedResizableDirectMemory{memoryFilePath}}; + for (std::size_t i = 0; i < state.range(0); ++i) { - std::remove(memoryFilePath.c_str()); - throw; + CreatePoint(storage); } + } + catch (...) + { std::remove(memoryFilePath.c_str()); + throw; } + std::remove(memoryFilePath.c_str()); } +} - static void BM_CreateMillionPointsSplitMemory(benchmark::State& state) +static void BM_CreateMillionPointsSplitMemory(benchmark::State& state) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + for (auto _ : state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - for (auto _ : state) + std::string dataMemoryFilePath{std::tmpnam(nullptr)}; + std::string indexMemoryFilePath{std::tmpnam(nullptr)}; + Expects(!Collections::IsWhiteSpace(dataMemoryFilePath)); + try { - std::string dataMemoryFilePath{ std::tmpnam(nullptr) }; - std::string indexMemoryFilePath{ std::tmpnam(nullptr) }; - Expects(!Collections::IsWhiteSpace(dataMemoryFilePath)); - try + SplitMemoryLinks, FileMappedResizableDirectMemory> storage{ + FileMappedResizableDirectMemory{dataMemoryFilePath}, + FileMappedResizableDirectMemory{indexMemoryFilePath}}; + for (std::size_t i = 0; i < state.range(0); ++i) { - SplitMemoryLinks, FileMappedResizableDirectMemory> storage{FileMappedResizableDirectMemory{dataMemoryFilePath}, FileMappedResizableDirectMemory{indexMemoryFilePath}}; - for (std::size_t i = 0; i < state.range(0); ++i) - { - CreatePoint(storage); - } - } - catch (...) - { - std::remove(dataMemoryFilePath.c_str()); - throw; + CreatePoint(storage); } + } + catch (...) + { std::remove(dataMemoryFilePath.c_str()); + throw; } + std::remove(dataMemoryFilePath.c_str()); } - - //BENCHMARK(BM_CreateMillionPointsFfi)->Arg(1000000); - BENCHMARK(BM_CreateMillionPointsUnitedMemory)->Arg(1000000); - BENCHMARK(BM_CreateMillionPointsSplitMemory)->Arg(1000000); } + +// BENCHMARK(BM_CreateMillionPointsFfi)->Arg(1000000); +BENCHMARK(BM_CreateMillionPointsUnitedMemory)->Arg(1000000); +BENCHMARK(BM_CreateMillionPointsSplitMemory)->Arg(1000000); +} // namespace Platform::Data::Doublets::Benchmarks diff --git a/cpp/Platform.Data.Doublets.Benchmarks/MemoryBenchmarks.cpp b/cpp/Platform.Data.Doublets.Benchmarks/MemoryBenchmarks.cpp index e22f3d980..d44a2ce4a 100644 --- a/cpp/Platform.Data.Doublets.Benchmarks/MemoryBenchmarks.cpp +++ b/cpp/Platform.Data.Doublets.Benchmarks/MemoryBenchmarks.cpp @@ -1,38 +1,38 @@ -//namespace Platform::Data::Doublets::Benchmarks +// namespace Platform::Data::Doublets::Benchmarks //{ -// class MemoryBenchmarks -// { -// private: static SplitMemoryLinks _splitMemory; -// private: static ILinks *_splitMemoryLinks; -// private: static UnitedMemoryLinks _unitedMemory; -// private: static ILinks *_unitedMemoryLinks; +// class MemoryBenchmarks +// { +// private: static SplitMemoryLinks _splitMemory; +// private: static ILinks *_splitMemoryLinks; +// private: static UnitedMemoryLinks _unitedMemory; +// private: static ILinks *_unitedMemoryLinks; // -// public: static void Setup() -// { -// auto dataMemory = HeapResizableDirectMemory(); -// auto indexMemory = HeapResizableDirectMemory(); -// _splitMemory = SplitMemoryLinks(dataMemory, indexMemory); -// _splitMemoryLinks = _splitMemory.DecorateWithAutomaticUniquenessAndUsagesResolution(); +// public: static void Setup() +// { +// auto dataMemory = HeapResizableDirectMemory(); +// auto indexMemory = HeapResizableDirectMemory(); +// _splitMemory = SplitMemoryLinks(dataMemory, indexMemory); +// _splitMemoryLinks = _splitMemory.DecorateWithAutomaticUniquenessAndUsagesResolution(); // -// auto memory = HeapResizableDirectMemory(); -// _unitedMemory = UnitedMemoryLinks(memory); -// _unitedMemoryLinks = _unitedMemory.DecorateWithAutomaticUniquenessAndUsagesResolution(); -// } +// auto memory = HeapResizableDirectMemory(); +// _unitedMemory = UnitedMemoryLinks(memory); +// _unitedMemoryLinks = _unitedMemory.DecorateWithAutomaticUniquenessAndUsagesResolution(); +// } // -// public: static void Cleanup() -// { -// _splitMemory.Dispose(); -// _unitedMemory.Dispose(); -// } +// public: static void Cleanup() +// { +// _splitMemory.Dispose(); +// _unitedMemory.Dispose(); +// } // -// public: void Split() -// { -// _TestExtensions::TestMultipleRandomCreationsAndDeletions(splitMemoryLinks, 1000); -// } +// public: void Split() +// { +// _TestExtensions::TestMultipleRandomCreationsAndDeletions(splitMemoryLinks, 1000); +// } // -// public: void United() -// { -// _TestExtensions::TestMultipleRandomCreationsAndDeletions(unitedMemoryLinks, 1000); -// } -// }; -//} +// public: void United() +// { +// _TestExtensions::TestMultipleRandomCreationsAndDeletions(unitedMemoryLinks, 1000); +// } +// }; +// } diff --git a/cpp/Platform.Data.Doublets.Profiling/AllProfilings.cpp b/cpp/Platform.Data.Doublets.Profiling/AllProfilings.cpp index f7cdca463..176bd2b94 100644 --- a/cpp/Platform.Data.Doublets.Profiling/AllProfilings.cpp +++ b/cpp/Platform.Data.Doublets.Profiling/AllProfilings.cpp @@ -7,4 +7,3 @@ int main() using namespace Platform::Data::Doublets::Profiling; CreatePoints(); } - diff --git a/cpp/Platform.Data.Doublets.Profiling/CreatePointsProfiling.h b/cpp/Platform.Data.Doublets.Profiling/CreatePointsProfiling.h index a3a3ef157..742d4413a 100644 --- a/cpp/Platform.Data.Doublets.Profiling/CreatePointsProfiling.h +++ b/cpp/Platform.Data.Doublets.Profiling/CreatePointsProfiling.h @@ -1,31 +1,32 @@ namespace Platform::Data::Doublets::Profiling { - using TLinkAddress = std::uint64_t; +using TLinkAddress = std::uint64_t; - constexpr std::size_t pointsNumberToCreate = 1000000; +constexpr std::size_t pointsNumberToCreate = 1000000; - void CreatePoints() +void CreatePoints() +{ + using namespace Platform; + using namespace Platform::Memory; + using namespace Platform::Data; + using namespace Platform::Data::Doublets; + using namespace Platform::Data::Doublets::Memory::United::Generic; + std::string tempFilePath{std::tmpnam(nullptr)}; + Expects(!Collections::IsWhiteSpace(tempFilePath)); + try { - using namespace Platform; - using namespace Platform::Memory; - using namespace Platform::Data; - using namespace Platform::Data::Doublets; - using namespace Platform::Data::Doublets::Memory::United::Generic; - std::string tempFilePath { std::tmpnam(nullptr) }; - Expects(!Collections::IsWhiteSpace(tempFilePath)); - try - { - UnitedMemoryLinks, FileMappedResizableDirectMemory> storage{FileMappedResizableDirectMemory{tempFilePath}}; - for (std::size_t i = 0; i < pointsNumberToCreate; ++i) - { - CreatePoint(storage); - } - } - catch (...) + UnitedMemoryLinks, FileMappedResizableDirectMemory> storage{ + FileMappedResizableDirectMemory{tempFilePath}}; + for (std::size_t i = 0; i < pointsNumberToCreate; ++i) { - std::remove(tempFilePath.c_str()); - throw; + CreatePoint(storage); } + } + catch (...) + { std::remove(tempFilePath.c_str()); + throw; } + std::remove(tempFilePath.c_str()); } +} // namespace Platform::Data::Doublets::Profiling diff --git a/cpp/Platform.Data.Doublets.Tests/AllTests.cpp b/cpp/Platform.Data.Doublets.Tests/AllTests.cpp index 54a020ab0..f54726469 100644 --- a/cpp/Platform.Data.Doublets.Tests/AllTests.cpp +++ b/cpp/Platform.Data.Doublets.Tests/AllTests.cpp @@ -1,10 +1,10 @@ -#include -#include #include "ILinksTestExtensions.h" +#include +#include +#include "Dynamic/GenericLinksTests.cpp" +#include "Dynamic/SplitMemoryGenericLinksTests.cpp" #include "LinksConstantsTests.cpp" #include "ResizableDirectMemoryLinksTests.cpp" #include "Static/GenericLinksTests.cpp" #include "Static/SplitMemoryGenericLinksTests.cpp" -#include "Dynamic/GenericLinksTests.cpp" -#include "Dynamic/SplitMemoryGenericLinksTests.cpp" diff --git a/cpp/Platform.Data.Doublets.Tests/Dynamic/GenericLinksTests.cpp b/cpp/Platform.Data.Doublets.Tests/Dynamic/GenericLinksTests.cpp index feb13b48b..66cb69aa2 100644 --- a/cpp/Platform.Data.Doublets.Tests/Dynamic/GenericLinksTests.cpp +++ b/cpp/Platform.Data.Doublets.Tests/Dynamic/GenericLinksTests.cpp @@ -1,203 +1,211 @@ namespace Platform::Data::Doublets::Tests::Dynamic::GenericLinksTests { - template - static void UsingStorage(auto&& action) - { - using namespace Platform::Memory; - TStorage storage{ HeapResizableDirectMemory{ } }; - Platform::Data::ILinks& upcastedStorage = storage; - action(storage); - } +template +static void UsingStorage(auto&& action) +{ + using namespace Platform::Memory; + TStorage storage{HeapResizableDirectMemory{}}; + Platform::Data::ILinks& upcastedStorage = storage; + action(storage); +} + +template +static void UsingStorageWithExternalReferencesWithSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using LinksOptionsType = LinksOptions; + using StorageType = + UnitedMemoryLinks, + LinksTargetsSizeBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + StorageType storage{HeapResizableDirectMemory{}}; + UsingStorage(action); +} - template - static void UsingStorageWithExternalReferencesWithSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsSizeBalancedTreeMethods, - UnusedLinksListMethods, - Platform::Data::ILinks>; - StorageType storage{ HeapResizableDirectMemory{ } }; - UsingStorage(action); - } +template +static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using namespace Platform::Data::Doublets::Decorators; + using LinksOptionsType = LinksOptions; + using StorageType = + UnitedMemoryLinks, + LinksTargetsSizeBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; + DecoratedStorageType storage{HeapResizableDirectMemory{}}; + UsingStorage(action); +} - template - static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using namespace Platform::Data::Doublets::Decorators; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsSizeBalancedTreeMethods, - UnusedLinksListMethods, - Platform::Data::ILinks>; - using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; - DecoratedStorageType storage { HeapResizableDirectMemory{ } }; - UsingStorage(action); - } +template +static void UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using LinksOptionsType = LinksOptions; + using StorageType = + UnitedMemoryLinks, + LinksTargetsRecursionlessSizeBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + StorageType storage{HeapResizableDirectMemory{}}; + UsingStorage(action); +} - template - static void UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsRecursionlessSizeBalancedTreeMethods, - UnusedLinksListMethods, - Platform::Data::ILinks>; - StorageType storage{ HeapResizableDirectMemory{ } }; - UsingStorage(action); - } +template +static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using namespace Platform::Data::Doublets::Decorators; + using LinksOptionsType = LinksOptions; + using StorageType = + UnitedMemoryLinks, + LinksTargetsRecursionlessSizeBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; + DecoratedStorageType storage{HeapResizableDirectMemory{}}; + UsingStorage(action); +} - template - static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using namespace Platform::Data::Doublets::Decorators; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsRecursionlessSizeBalancedTreeMethods, - UnusedLinksListMethods, - Platform::Data::ILinks>; - using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; - DecoratedStorageType storage { HeapResizableDirectMemory{ } }; - UsingStorage(action); - } +template +static void UsingStorageWithExternalReferencesWithAvlTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using LinksOptionsType = LinksOptions; + using StorageType = + UnitedMemoryLinks, + LinksTargetsAvlBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + StorageType storage{HeapResizableDirectMemory{}}; + UsingStorage(action); +} - template - static void UsingStorageWithExternalReferencesWithAvlTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsAvlBalancedTreeMethods, - UnusedLinksListMethods, - Platform::Data::ILinks>; - StorageType storage{ HeapResizableDirectMemory{ } }; - UsingStorage(action); - } +template +static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using namespace Platform::Data::Doublets::Decorators; + using LinksOptionsType = LinksOptions; + using StorageType = + UnitedMemoryLinks, + LinksTargetsAvlBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; + DecoratedStorageType storage{HeapResizableDirectMemory{}}; + UsingStorage(action); +} - template - static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using namespace Platform::Data::Doublets::Decorators; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsAvlBalancedTreeMethods, - UnusedLinksListMethods, - Platform::Data::ILinks>; - using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; - DecoratedStorageType storage { HeapResizableDirectMemory{ } }; - UsingStorage(action); - } +TEST(DynamicGenericLinksTests, CrudTestWithSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); +} - TEST(DynamicGenericLinksTests, CrudTestWithSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - } +TEST(DynamicGenericLinksTests, RawNumbersCrudTestWithSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); +} - TEST(DynamicGenericLinksTests, RawNumbersCrudTestWithSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - } +TEST(DynamicGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithSizeBalancedTrees) +{ + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 16); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); +} - TEST(DynamicGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithSizeBalancedTrees) - { - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,16); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - } +TEST(DynamicGenericLinksTests, CrudTestWithRecursionlessSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestCrudOperations(storage); }); +} - TEST(DynamicGenericLinksTests, CrudTestWithRecursionlessSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - } +TEST(DynamicGenericLinksTests, RawNumbersCrudTestWithRecursionlessSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestRawNumbersCrudOperations(storage); }); +} - TEST(DynamicGenericLinksTests, RawNumbersCrudTestWithRecursionlessSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - } +TEST(DynamicGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithRecursionlessSizeBalancedTrees) +{ + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 16); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); +} - TEST(DynamicGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithRecursionlessSizeBalancedTrees) - { - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,16); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - } - - TEST(DynamicGenericLinksTests, CrudTestWithAvlTrees) - { - UsingStorageWithExternalReferencesWithAvlTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - } +TEST(DynamicGenericLinksTests, CrudTestWithAvlTrees) +{ + UsingStorageWithExternalReferencesWithAvlTrees([](auto&& storage) { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlTrees([](auto&& storage) { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlTrees([](auto&& storage) { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlTrees([](auto&& storage) { TestCrudOperations(storage); }); +} - TEST(DynamicGenericLinksTests, RawNumbersCrudTestWithAvlTrees) - { - UsingStorageWithExternalReferencesWithAvlTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - } +TEST(DynamicGenericLinksTests, RawNumbersCrudTestWithAvlTrees) +{ + UsingStorageWithExternalReferencesWithAvlTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); +} - TEST(DynamicGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithAvlBalancedTrees) - { - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,16); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - } +TEST(DynamicGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithAvlBalancedTrees) +{ + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 16); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); } +} // namespace Platform::Data::Doublets::Tests::Dynamic::GenericLinksTests diff --git a/cpp/Platform.Data.Doublets.Tests/Dynamic/SplitMemoryGenericLinksTests.cpp b/cpp/Platform.Data.Doublets.Tests/Dynamic/SplitMemoryGenericLinksTests.cpp index acd807a11..f2927a5be 100644 --- a/cpp/Platform.Data.Doublets.Tests/Dynamic/SplitMemoryGenericLinksTests.cpp +++ b/cpp/Platform.Data.Doublets.Tests/Dynamic/SplitMemoryGenericLinksTests.cpp @@ -1,149 +1,191 @@ namespace Platform::Data::Doublets::Tests::Dynamic::SplitMemoryGenericLinksTests { - template - static void UsingStorage(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - TStorage storage{ HeapResizableDirectMemory{ }, HeapResizableDirectMemory{ } }; - Data::ILinks& dynamicStorage = storage; - action(dynamicStorage); - // action(storage); - } +template +static void UsingStorage(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + TStorage storage{HeapResizableDirectMemory{}, HeapResizableDirectMemory{}}; + Data::ILinks& dynamicStorage = storage; + action(dynamicStorage); + // action(storage); +} - template - static void UsingStorageWithoutExternalReferencesWithSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using LinksOptionsType = LinksOptions{false}>; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsSizeBalancedTreeMethods, ExternalLinksSourcesSizeBalancedTreeMethods, ExternalLinksTargetsSizeBalancedTreeMethods, UnusedLinksListMethods,Platform::Data::ILinks>; - UsingStorage(action); - } +template +static void UsingStorageWithoutExternalReferencesWithSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using LinksOptionsType = LinksOptions{false}>; + using StorageType = + SplitMemoryLinks, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsSizeBalancedTreeMethods, + ExternalLinksSourcesSizeBalancedTreeMethods, + ExternalLinksTargetsSizeBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + UsingStorage(action); +} - template - static void UsingStorageWithExternalReferencesWithSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using LinksOptionsType = LinksOptions; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsSizeBalancedTreeMethods, ExternalLinksSourcesSizeBalancedTreeMethods, ExternalLinksTargetsSizeBalancedTreeMethods, UnusedLinksListMethods,Platform::Data::ILinks>; - UsingStorage(action); - } +template +static void UsingStorageWithExternalReferencesWithSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using LinksOptionsType = LinksOptions; + using StorageType = + SplitMemoryLinks, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsSizeBalancedTreeMethods, + ExternalLinksSourcesSizeBalancedTreeMethods, + ExternalLinksTargetsSizeBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + UsingStorage(action); +} - template - static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using namespace Platform::Data::Doublets::Decorators; - using LinksOptionsType = LinksOptions{false}>; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsSizeBalancedTreeMethods, ExternalLinksSourcesSizeBalancedTreeMethods, ExternalLinksTargetsSizeBalancedTreeMethods, UnusedLinksListMethods, Platform::Data::ILinks>; - using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; - UsingStorage(action); - } +template +static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using namespace Platform::Data::Doublets::Decorators; + using LinksOptionsType = LinksOptions{false}>; + using StorageType = + SplitMemoryLinks, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsSizeBalancedTreeMethods, + ExternalLinksSourcesSizeBalancedTreeMethods, + ExternalLinksTargetsSizeBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; + UsingStorage(action); +} - template - static void UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using LinksOptionsType = LinksOptions{false}>; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, UnusedLinksListMethods,Platform::Data::ILinks>; - UsingStorage(action); - } +template +static void UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using LinksOptionsType = LinksOptions{false}>; + using StorageType = + SplitMemoryLinks, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, + ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + UsingStorage(action); +} - template - static void UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using LinksOptionsType = LinksOptions; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, UnusedLinksListMethods,Platform::Data::ILinks>; - UsingStorage(action); - } +template +static void UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using LinksOptionsType = LinksOptions; + using StorageType = + SplitMemoryLinks, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, + ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + UsingStorage(action); +} - template - static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using namespace Platform::Data::Doublets::Decorators; - using LinksOptionsType = LinksOptions{false}>; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, UnusedLinksListMethods, Platform::Data::ILinks>; - using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; - UsingStorage(action); - } +template +static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using namespace Platform::Data::Doublets::Decorators; + using LinksOptionsType = LinksOptions{false}>; + using StorageType = + SplitMemoryLinks, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, + ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + UnusedLinksListMethods, Platform::Data::ILinks>; + using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; + UsingStorage(action); +} - TEST(DynamicSplitMemoryGenericLinksTests, CrudTestWithSizeBalancedTrees) - { - UsingStorageWithoutExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - } +TEST(DynamicSplitMemoryGenericLinksTests, CrudTestWithSizeBalancedTrees) +{ + UsingStorageWithoutExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { return TestCrudOperations(storage); }); +} - TEST(DynamicSplitMemoryGenericLinksTests, RawNumbersCrudTestWithSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - } +TEST(DynamicSplitMemoryGenericLinksTests, RawNumbersCrudTestWithSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); +} - TEST(DynamicSplitMemoryGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithSizeBalancedTrees) - { - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,16); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - } +TEST(DynamicSplitMemoryGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithSizeBalancedTrees) +{ + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 16); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); +} - TEST(DynamicSplitMemoryGenericLinksTests, CrudTestWithRecursionlessSizeBalancedTrees) - { - UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - } +TEST(DynamicSplitMemoryGenericLinksTests, CrudTestWithRecursionlessSizeBalancedTrees) +{ + UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestCrudOperations(storage); }); +} - TEST(DynamicSplitMemoryGenericLinksTests, RawNumbersCrudTestWithRecursionlessSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - } +TEST(DynamicSplitMemoryGenericLinksTests, RawNumbersCrudTestWithRecursionlessSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); +} - TEST(DynamicSplitMemoryGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithRecursionlessSizeBalancedTrees) - { - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,16); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - } +TEST(DynamicSplitMemoryGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithRecursionlessSizeBalancedTrees) +{ + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 16); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); } +} // namespace Platform::Data::Doublets::Tests::Dynamic::SplitMemoryGenericLinksTests diff --git a/cpp/Platform.Data.Doublets.Tests/ILinksTestExtensions.h b/cpp/Platform.Data.Doublets.Tests/ILinksTestExtensions.h index c161a6ed5..04929d473 100644 --- a/cpp/Platform.Data.Doublets.Tests/ILinksTestExtensions.h +++ b/cpp/Platform.Data.Doublets.Tests/ILinksTestExtensions.h @@ -1,234 +1,248 @@ namespace Platform::Data::Doublets::Tests { - class CrudOperationsTester +class CrudOperationsTester +{ +public: + template + static typename TStorage::LinkAddressType TestCreate(TStorage& storage) { - public: - template - static typename TStorage::LinkAddressType TestCreate(TStorage& storage) - { - using namespace Platform::Interfaces; - auto constants { storage.Constants }; - auto _continue = constants.Continue; - Link linkStruct; - storage.Each(typename TStorage::LinkType{constants.Any, constants.Any, constants.Any} , [&linkStruct, _continue](const typename TStorage::LinkType& link) { - linkStruct = Link(link); - return _continue; - }); - Expects(constants.Null == linkStruct.Index); - auto linkAddress { Create(storage) }; - linkStruct = { GetLink(storage, linkAddress) }; - Expects(3 == linkStruct.size()); - Expects(linkAddress == linkStruct.Index); - Expects(constants.Null == linkStruct.Source); - Expects(constants.Null == linkStruct.Target); - Expects(1 == Count(storage)); - return linkAddress; - } - - template - static typename TStorage::LinkAddressType GetFirstLink(TStorage& storage, typename TStorage::LinkAddressType linkAddress) - { - using namespace Platform::Interfaces; - auto constants { storage.Constants }; - auto _continue { constants.Continue }; - typename TStorage::LinkAddressType linkAddressFromEach {}; - storage.Each(typename TStorage::LinkType{constants.Any, constants.Any, constants.Any}, [_continue, &linkAddressFromEach](const typename TStorage::LinkType& link) { - linkAddressFromEach = link[0]; - return _continue; - }); - Expects(linkAddress == linkAddressFromEach); - return linkAddressFromEach; - } - - template - static typename TStorage::LinkAddressType TestUpdateLinkToReferenceItself(TStorage& storage, typename TStorage::LinkAddressType linkAddress) - { - auto constants { storage.Constants }; - auto updatedLinkAddress { Update(storage, linkAddress, linkAddress, linkAddress) }; - Link link { GetLink(storage, updatedLinkAddress) }; - Expects(link.Index == link.Source); - Expects(link.Index == link.Target); - return link.Index; - } + using namespace Platform::Interfaces; + auto constants{storage.Constants}; + auto _continue = constants.Continue; + Link linkStruct; + storage.Each(typename TStorage::LinkType{constants.Any, constants.Any, constants.Any}, + [&linkStruct, _continue](const typename TStorage::LinkType& link) + { + linkStruct = Link(link); + return _continue; + }); + Expects(constants.Null == linkStruct.Index); + auto linkAddress{Create(storage)}; + linkStruct = {GetLink(storage, linkAddress)}; + Expects(3 == linkStruct.size()); + Expects(linkAddress == linkStruct.Index); + Expects(constants.Null == linkStruct.Source); + Expects(constants.Null == linkStruct.Target); + Expects(1 == Count(storage)); + return linkAddress; + } - template - static typename TStorage::LinkAddressType TestUpdateLinkToReferenceNull(TStorage& storage, typename TStorage::LinkAddressType linkAddress) - { - auto constants { storage.Constants }; - auto updatedLinkAddress { Update(storage, linkAddress, constants.Null, constants.Null) }; - Link linkStruct { GetLink(storage, updatedLinkAddress) }; - Expects(constants.Null == linkStruct.Source); - Expects(constants.Null == linkStruct.Target); - return linkStruct.Index; - } + template + static typename TStorage::LinkAddressType GetFirstLink(TStorage& storage, + typename TStorage::LinkAddressType linkAddress) + { + using namespace Platform::Interfaces; + auto constants{storage.Constants}; + auto _continue{constants.Continue}; + typename TStorage::LinkAddressType linkAddressFromEach{}; + storage.Each(typename TStorage::LinkType{constants.Any, constants.Any, constants.Any}, + [_continue, &linkAddressFromEach](const typename TStorage::LinkType& link) + { + linkAddressFromEach = link[0]; + return _continue; + }); + Expects(linkAddress == linkAddressFromEach); + return linkAddressFromEach; + } - template - static void TestDelete(TStorage& storage, typename TStorage::LinkAddressType linkAddress) - { - using namespace Platform::Interfaces; - auto constants { storage.Constants }; - auto _continue = constants.Continue; - auto updatedLinkAddress { Update(storage, linkAddress, linkAddress, linkAddress) }; - Link linkStruct { GetLink(storage, updatedLinkAddress) }; - Data::Delete(storage, linkAddress); - Expects(0 == Count(storage)); - typename TStorage::LinkAddressType deletedLinkAddress {}; - storage.Each(typename TStorage::LinkType{constants.Any, constants.Any, constants.Any}, [_continue, &deletedLinkAddress](const typename TStorage::LinkType& link) { - deletedLinkAddress = link[0]; - return _continue; - }); - Expects(constants.Null == deletedLinkAddress); - } - }; + template + static typename TStorage::LinkAddressType + TestUpdateLinkToReferenceItself(TStorage& storage, typename TStorage::LinkAddressType linkAddress) + { + auto constants{storage.Constants}; + auto updatedLinkAddress{Update(storage, linkAddress, linkAddress, linkAddress)}; + Link link{GetLink(storage, updatedLinkAddress)}; + Expects(link.Index == link.Source); + Expects(link.Index == link.Target); + return link.Index; + } - - template - static void TestCrudOperations(TStorage& storage) + template + static typename TStorage::LinkAddressType + TestUpdateLinkToReferenceNull(TStorage& storage, typename TStorage::LinkAddressType linkAddress) { - constexpr auto constants = storage.Constants; - Expects(0 == Platform::Data::Count(storage)); - // Create link - auto linkAddress { CrudOperationsTester::TestCreate(storage) }; - // Get first link - linkAddress = { CrudOperationsTester::GetFirstLink(storage, linkAddress) }; - // Update link to reference itself - linkAddress = { CrudOperationsTester::TestUpdateLinkToReferenceItself(storage, linkAddress) }; - // Update link to reference null (prepare for delete) - linkAddress = { CrudOperationsTester::TestUpdateLinkToReferenceNull(storage, linkAddress) }; - // Delete link - CrudOperationsTester::TestDelete(storage, linkAddress); + auto constants{storage.Constants}; + auto updatedLinkAddress{Update(storage, linkAddress, constants.Null, constants.Null)}; + Link linkStruct{GetLink(storage, updatedLinkAddress)}; + Expects(constants.Null == linkStruct.Source); + Expects(constants.Null == linkStruct.Target); + return linkStruct.Index; } - template - static void TestRawNumbersCrudOperations(TStorage& storage) + template + static void TestDelete(TStorage& storage, typename TStorage::LinkAddressType linkAddress) { - // Constants - constexpr auto constants = storage.Constants; + using namespace Platform::Interfaces; + auto constants{storage.Constants}; auto _continue = constants.Continue; - auto any = constants.Any; - Hybrid h106E {106, true}; - Hybrid h107E {107, true}; - Hybrid h108E {108, true}; - Expects(106L == h106E.AbsoluteValue()); - Expects(107L == h107E.AbsoluteValue()); - Expects(108L == h108E.AbsoluteValue()); - // Create link (External -> External) - auto linkAddress1 = Create(storage); - Update(storage, linkAddress1, h106E.Value, h108E.Value); - Link link1 { GetLink(storage, linkAddress1) }; - Expects(h106E.Value == link1.Source); - Expects(h108E.Value == link1.Target); - // Create link (Internal -> External) - auto linkAddress2 { Create(storage) }; - Update(storage, linkAddress2, linkAddress1, h108E.Value); - Link link2 { GetLink(storage, linkAddress2) }; - Expects(linkAddress1 == link2.Source); - Expects(h108E.Value == link2.Target); - // Create link (Internal -> Internal) - auto linkAddress3 { Create(storage) }; - Update(storage,linkAddress3, linkAddress1, linkAddress2); - Link link3 { GetLink(storage, linkAddress3) }; - Expects(linkAddress1 == link3.Source); - Expects(linkAddress2 == link3.Target); - // Search for created link - typename TStorage::LinkAddressType searchedLinkAddress {}; - storage.Each(typename TStorage::LinkType{any, h106E.Value, h108E.Value}, [&searchedLinkAddress, _continue](const typename TStorage::LinkType& link) { - searchedLinkAddress = link[0]; - return _continue; - }); - auto aaa = GetLink(storage, linkAddress1); - Expects(linkAddress1 == searchedLinkAddress); - // Search for nonexistent link -// typename TStorage::LinkAddressType searchedNonExistentypename TStorage::LinkAddressType {}; -// storage.Each(typename TStorage::LinkType{any, h106E.Value, h108E.Value}, [&searchedNonExistentypename TStorage::LinkAddressType, _continue](const typename TStorage::LinkType& link) { -// searchedNonExistentypename TStorage::LinkAddressType = link[0]; -// return _continue; -// }); -// Expects(constants.Null == searchedNonExistentypename TStorage::LinkAddressType); - // Update link to reference null (prepare for delete) - auto updatedLinkAddress { Update(storage, linkAddress3, constants.Null, constants.Null) }; - Expects(linkAddress3 == updatedLinkAddress); - link3 = { GetLink(storage, linkAddress3) }; - Expects(constants.Null == link3.Source); - Expects(constants.Null == link3.Target); - // Delete link - Data::Delete(storage, linkAddress3); - Expects(2 == Count(storage)); - typename TStorage::LinkAddressType deletedLinkAddress {}; - storage.Each(typename TStorage::LinkType{any, any, any}, [&deletedLinkAddress, _continue](const typename TStorage::LinkType& link) { - deletedLinkAddress = link[0]; - return _continue; - }); - Expects(linkAddress2 == deletedLinkAddress); + auto updatedLinkAddress{Update(storage, linkAddress, linkAddress, linkAddress)}; + Link linkStruct{GetLink(storage, updatedLinkAddress)}; + Data::Delete(storage, linkAddress); + Expects(0 == Count(storage)); + typename TStorage::LinkAddressType deletedLinkAddress{}; + storage.Each(typename TStorage::LinkType{constants.Any, constants.Any, constants.Any}, + [_continue, &deletedLinkAddress](const typename TStorage::LinkType& link) + { + deletedLinkAddress = link[0]; + return _continue; + }); + Expects(constants.Null == deletedLinkAddress); } +}; + - template - static void TestMultipleCreationsAndDeletions(TStorage& storage, int numberOfOperations) +template +static void TestCrudOperations(TStorage& storage) +{ + constexpr auto constants = storage.Constants; + Expects(0 == Platform::Data::Count(storage)); + // Create link + auto linkAddress{CrudOperationsTester::TestCreate(storage)}; + // Get first link + linkAddress = {CrudOperationsTester::GetFirstLink(storage, linkAddress)}; + // Update link to reference itself + linkAddress = {CrudOperationsTester::TestUpdateLinkToReferenceItself(storage, linkAddress)}; + // Update link to reference null (prepare for delete) + linkAddress = {CrudOperationsTester::TestUpdateLinkToReferenceNull(storage, linkAddress)}; + // Delete link + CrudOperationsTester::TestDelete(storage, linkAddress); +} + +template +static void TestRawNumbersCrudOperations(TStorage& storage) +{ + // Constants + constexpr auto constants = storage.Constants; + auto _continue = constants.Continue; + auto any = constants.Any; + Hybrid h106E{106, true}; + Hybrid h107E{107, true}; + Hybrid h108E{108, true}; + Expects(106L == h106E.AbsoluteValue()); + Expects(107L == h107E.AbsoluteValue()); + Expects(108L == h108E.AbsoluteValue()); + // Create link (External -> External) + auto linkAddress1 = Create(storage); + Update(storage, linkAddress1, h106E.Value, h108E.Value); + Link link1{GetLink(storage, linkAddress1)}; + Expects(h106E.Value == link1.Source); + Expects(h108E.Value == link1.Target); + // Create link (Internal -> External) + auto linkAddress2{Create(storage)}; + Update(storage, linkAddress2, linkAddress1, h108E.Value); + Link link2{GetLink(storage, linkAddress2)}; + Expects(linkAddress1 == link2.Source); + Expects(h108E.Value == link2.Target); + // Create link (Internal -> Internal) + auto linkAddress3{Create(storage)}; + Update(storage, linkAddress3, linkAddress1, linkAddress2); + Link link3{GetLink(storage, linkAddress3)}; + Expects(linkAddress1 == link3.Source); + Expects(linkAddress2 == link3.Target); + // Search for created link + typename TStorage::LinkAddressType searchedLinkAddress{}; + storage.Each(typename TStorage::LinkType{any, h106E.Value, h108E.Value}, + [&searchedLinkAddress, _continue](const typename TStorage::LinkType& link) + { + searchedLinkAddress = link[0]; + return _continue; + }); + auto aaa = GetLink(storage, linkAddress1); + Expects(linkAddress1 == searchedLinkAddress); + // Search for nonexistent link + // typename TStorage::LinkAddressType searchedNonExistentypename TStorage::LinkAddressType {}; + // storage.Each(typename TStorage::LinkType{any, h106E.Value, h108E.Value}, [&searchedNonExistentypename + // TStorage::LinkAddressType, _continue](const typename TStorage::LinkType& link) { + // searchedNonExistentypename TStorage::LinkAddressType = link[0]; + // return _continue; + // }); + // Expects(constants.Null == searchedNonExistentypename TStorage::LinkAddressType); + // Update link to reference null (prepare for delete) + auto updatedLinkAddress{Update(storage, linkAddress3, constants.Null, constants.Null)}; + Expects(linkAddress3 == updatedLinkAddress); + link3 = {GetLink(storage, linkAddress3)}; + Expects(constants.Null == link3.Source); + Expects(constants.Null == link3.Target); + // Delete link + Data::Delete(storage, linkAddress3); + Expects(2 == Count(storage)); + typename TStorage::LinkAddressType deletedLinkAddress{}; + storage.Each(typename TStorage::LinkType{any, any, any}, + [&deletedLinkAddress, _continue](const typename TStorage::LinkType& link) + { + deletedLinkAddress = link[0]; + return _continue; + }); + Expects(linkAddress2 == deletedLinkAddress); +} + +template +static void TestMultipleCreationsAndDeletions(TStorage& storage, int numberOfOperations) +{ + for (int i = 0; i < numberOfOperations; i++) { - for (int i = 0; i < numberOfOperations; i++) - { - Create(storage); - } - for (int i = 0; i < numberOfOperations; i++) - { - storage.Delete(Count(storage)); - } + Create(storage); + } + for (int i = 0; i < numberOfOperations; i++) + { + storage.Delete(Count(storage)); } +} - template - static void TestMultipleRandomCreationsAndDeletions(TStorage& storage, int maximumOperationsPerCycle) +template +static void TestMultipleRandomCreationsAndDeletions(TStorage& storage, int maximumOperationsPerCycle) +{ + using namespace Platform::Random; + using namespace Platform::Data; + for (auto N{1}; N < maximumOperationsPerCycle; ++N) { - using namespace Platform::Random; - using namespace Platform::Data; - for (auto N { 1 }; N < maximumOperationsPerCycle; ++N) + std::srand(N); + auto& randomGen64{RandomHelpers::Default}; + auto created{0UL}; + auto deleted{0UL}; + for (auto i{0}; i < N; ++i) { - std::srand(N); - auto& randomGen64 { RandomHelpers::Default }; - auto created { 0UL }; - auto deleted { 0UL }; - for (auto i { 0 }; i < N; ++i) + auto linksCount{Count(storage)}; + auto createPoint{Random::NextBoolean(randomGen64)}; + if (linksCount >= 2 && createPoint) { - auto linksCount { Count(storage) }; - auto createPoint { Random::NextBoolean(randomGen64) }; - if (linksCount >= 2 && createPoint) + Ranges::Range linksAddressRange{1, linksCount}; + auto source{Random::NextUInt64(randomGen64, linksAddressRange)}; + auto target{Random::NextUInt64(randomGen64, linksAddressRange)}; //-V3086 + auto resultLink{GetOrCreate(storage, source, target)}; + auto linksCountAfterGetOrCreate{Count(storage)}; + if (resultLink > linksCount) { - Ranges::Range linksAddressRange { 1, linksCount }; - auto source { Random::NextUInt64(randomGen64, linksAddressRange) }; - auto target { Random::NextUInt64(randomGen64, linksAddressRange) }; //-V3086 - auto resultLink { GetOrCreate(storage, source, target) }; - auto linksCountAfterGetOrCreate { Count(storage) }; - if (resultLink > linksCount) - { - ++created; - } - } - else - { - Create(storage); ++created; } } - std::vector allLinks { All(storage) }; - for(auto link : allLinks) + else { + Create(storage); + ++created; } + } + std::vector allLinks{All(storage)}; + for (auto link : allLinks) + { + } - Expects(Count(storage) == created); - for (auto i { 0 }; i < N; ++i) + Expects(Count(storage) == created); + for (auto i{0}; i < N; ++i) + { + typename TStorage::LinkAddressType linkAddress = i + 1; + if (Exists(storage, linkAddress)) { - typename TStorage::LinkAddressType linkAddress = i + 1; - if (Exists(storage, linkAddress)) - { - Delete(storage, linkAddress); - ++deleted; - allLinks = { All(storage)}; - for(auto link : allLinks) - { - } + Delete(storage, linkAddress); + ++deleted; + allLinks = {All(storage)}; + for (auto link : allLinks) + { } } - Expects(0 == Count(storage)); } + Expects(0 == Count(storage)); } } +} // namespace Platform::Data::Doublets::Tests diff --git a/cpp/Platform.Data.Doublets.Tests/LinksConstantsTests.cpp b/cpp/Platform.Data.Doublets.Tests/LinksConstantsTests.cpp index 7cffbee02..0ce11d780 100644 --- a/cpp/Platform.Data.Doublets.Tests/LinksConstantsTests.cpp +++ b/cpp/Platform.Data.Doublets.Tests/LinksConstantsTests.cpp @@ -1,18 +1,19 @@ namespace Platform::Data::Doublets::Tests { - using TLinkAddress = std::uint64_t; - TEST(LinksConstantsTests, ExternalReferencesTest) - { - using namespace Platform::Ranges; - constexpr Ranges::Range possibleInternalReferencesRange {1, std::numeric_limits::max()}; - constexpr Ranges::Range possibleExternalReferencesRange {std::numeric_limits::max() + 1UL, std::numeric_limits::max()}; - constexpr LinksConstants constants {possibleInternalReferencesRange, possibleExternalReferencesRange}; - auto isExternal {true}; - Hybrid minimum {1, isExternal}; - Hybrid maximum {std::numeric_limits::max(), true}; - bool isMinimumExternalReference = IsExternalReference(minimum.Value); - bool isMaximumExternalReference = IsExternalReference(minimum.Value); - ASSERT_TRUE(isMinimumExternalReference); - ASSERT_TRUE(isMaximumExternalReference); - }; -} +using TLinkAddress = std::uint64_t; +TEST(LinksConstantsTests, ExternalReferencesTest) +{ + using namespace Platform::Ranges; + constexpr Ranges::Range possibleInternalReferencesRange{1, std::numeric_limits::max()}; + constexpr Ranges::Range possibleExternalReferencesRange{std::numeric_limits::max() + 1UL, + std::numeric_limits::max()}; + constexpr LinksConstants constants{possibleInternalReferencesRange, possibleExternalReferencesRange}; + auto isExternal{true}; + Hybrid minimum{1, isExternal}; + Hybrid maximum{std::numeric_limits::max(), true}; + bool isMinimumExternalReference = IsExternalReference(minimum.Value); + bool isMaximumExternalReference = IsExternalReference(minimum.Value); + ASSERT_TRUE(isMinimumExternalReference); + ASSERT_TRUE(isMaximumExternalReference); +}; +} // namespace Platform::Data::Doublets::Tests diff --git a/cpp/Platform.Data.Doublets.Tests/ResizableDirectMemoryLinksTests.cpp b/cpp/Platform.Data.Doublets.Tests/ResizableDirectMemoryLinksTests.cpp index 8b6b13405..93c0b69cf 100644 --- a/cpp/Platform.Data.Doublets.Tests/ResizableDirectMemoryLinksTests.cpp +++ b/cpp/Platform.Data.Doublets.Tests/ResizableDirectMemoryLinksTests.cpp @@ -1,69 +1,74 @@ namespace Platform::Data::Doublets::Tests { - using TLinkAddress = uint64_t; +using TLinkAddress = uint64_t; - template - static void TestNonexistentReferences(TStorage& storage) - { - using namespace Platform::Interfaces; - constexpr auto constants = storage.Constants; - auto $break = constants.Break; - auto linkAddress = Create(storage); - Update(storage, linkAddress, std::numeric_limits::max(), std::numeric_limits::max()); - TLinkAddress resultLinkAddress{constants.Null}; - storage.Each(typename TStorage::LinkType{constants.Any, std::numeric_limits::max(), std::numeric_limits::max()}, [&resultLinkAddress, $break] (typename TStorage::LinkType foundLink) { - resultLinkAddress = foundLink[constants.IndexPart]; - return $break; - }); - Expects(resultLinkAddress == linkAddress); - Expects(0 == Count(storage, std::numeric_limits::max())); - Delete(storage, linkAddress); - } - - template - static void TestBasicMemoryOperations(TStorage& storage) - { - auto linkAddress {Create(storage)}; - Delete(storage, linkAddress); - } +template +static void TestNonexistentReferences(TStorage& storage) +{ + using namespace Platform::Interfaces; + constexpr auto constants = storage.Constants; + auto $break = constants.Break; + auto linkAddress = Create(storage); + Update(storage, linkAddress, std::numeric_limits::max(), std::numeric_limits::max()); + TLinkAddress resultLinkAddress{constants.Null}; + storage.Each(typename TStorage::LinkType{constants.Any, std::numeric_limits::max(), + std::numeric_limits::max()}, + [&resultLinkAddress, $break](typename TStorage::LinkType foundLink) + { + resultLinkAddress = foundLink[constants.IndexPart]; + return $break; + }); + Expects(resultLinkAddress == linkAddress); + Expects(0 == Count(storage, std::numeric_limits::max())); + Delete(storage, linkAddress); +} - TEST(ResizableDirectMemoryLinksTests, BasicFileMappedMemoryTest) - { - using namespace Platform::Data::Doublets::Memory::United::Generic; - using namespace Platform::Memory; - using LinksOptionsType = LinksOptions; - auto tempName {std::tmpnam(nullptr)}; - try - { - FileMappedResizableDirectMemory memory { tempName }; - UnitedMemoryLinks storage {std::move(memory)}; - TestBasicMemoryOperations(storage); - } - catch (...) - { - std::remove(tempName); - throw; - } - std::remove(tempName); - }; +template +static void TestBasicMemoryOperations(TStorage& storage) +{ + auto linkAddress{Create(storage)}; + Delete(storage, linkAddress); +} - TEST(ResizableDirectMemoryLinksTests, BasicHeapMemoryTest) +TEST(ResizableDirectMemoryLinksTests, BasicFileMappedMemoryTest) +{ + using namespace Platform::Data::Doublets::Memory::United::Generic; + using namespace Platform::Memory; + using LinksOptionsType = LinksOptions; + auto tempName{std::tmpnam(nullptr)}; + try { - using namespace Platform::Data::Doublets::Memory::United::Generic; - using namespace Platform::Memory; - using LinksOptionsType = LinksOptions; - HeapResizableDirectMemory memory {UnitedMemoryLinks::DefaultLinksSizeStep}; - UnitedMemoryLinks storage {std::move(memory), UnitedMemoryLinks::DefaultLinksSizeStep}; + FileMappedResizableDirectMemory memory{tempName}; + UnitedMemoryLinks storage{std::move(memory)}; TestBasicMemoryOperations(storage); } - - TEST(ResizableDirectMemoryLinksTests, NonexistentReferencesHeapMemoryTest) + catch (...) { - using namespace Platform::Data::Doublets::Memory::United::Generic; - using namespace Platform::Memory; - using LinksOptionsType = LinksOptions; - HeapResizableDirectMemory memory {UnitedMemoryLinks::DefaultLinksSizeStep}; - UnitedMemoryLinks storage {std::move(memory), UnitedMemoryLinks::DefaultLinksSizeStep}; - TestNonexistentReferences(storage); + std::remove(tempName); + throw; } + std::remove(tempName); +}; + +TEST(ResizableDirectMemoryLinksTests, BasicHeapMemoryTest) +{ + using namespace Platform::Data::Doublets::Memory::United::Generic; + using namespace Platform::Memory; + using LinksOptionsType = LinksOptions; + HeapResizableDirectMemory memory{UnitedMemoryLinks::DefaultLinksSizeStep}; + UnitedMemoryLinks storage{ + std::move(memory), UnitedMemoryLinks::DefaultLinksSizeStep}; + TestBasicMemoryOperations(storage); +} + +TEST(ResizableDirectMemoryLinksTests, NonexistentReferencesHeapMemoryTest) +{ + using namespace Platform::Data::Doublets::Memory::United::Generic; + using namespace Platform::Memory; + using LinksOptionsType = LinksOptions; + HeapResizableDirectMemory memory{UnitedMemoryLinks::DefaultLinksSizeStep}; + UnitedMemoryLinks storage{ + std::move(memory), UnitedMemoryLinks::DefaultLinksSizeStep}; + TestNonexistentReferences(storage); } +} // namespace Platform::Data::Doublets::Tests diff --git a/cpp/Platform.Data.Doublets.Tests/Static/GenericLinksTests.cpp b/cpp/Platform.Data.Doublets.Tests/Static/GenericLinksTests.cpp index 7571902d0..c440c4a93 100644 --- a/cpp/Platform.Data.Doublets.Tests/Static/GenericLinksTests.cpp +++ b/cpp/Platform.Data.Doublets.Tests/Static/GenericLinksTests.cpp @@ -1,191 +1,197 @@ namespace Platform::Data::Doublets::Tests::Static::GenericLinksTests { - template - static void UsingStorage(auto&& action) - { - using namespace Platform::Memory; - TStorage storage{ HeapResizableDirectMemory{ } }; - action(storage); - } - - template - static void UsingStorageWithExternalReferencesWithSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsSizeBalancedTreeMethods, - UnusedLinksListMethods>; - UsingStorage(action); - } - - template - static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using namespace Platform::Data::Doublets::Decorators; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsSizeBalancedTreeMethods, - UnusedLinksListMethods>; - using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; - UsingStorage(action); - } - - template - static void UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsRecursionlessSizeBalancedTreeMethods, - UnusedLinksListMethods>; - UsingStorage(action); - } - - template - static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using namespace Platform::Data::Doublets::Decorators; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsRecursionlessSizeBalancedTreeMethods, - UnusedLinksListMethods>; - using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; - UsingStorage(action); - } - - template - static void UsingStorageWithExternalReferencesWithAvlBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsAvlBalancedTreeMethods, - UnusedLinksListMethods>; - UsingStorage(action); - } - - template - static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::United::Generic; - using namespace Platform::Data::Doublets::Decorators; - using LinksOptionsType = LinksOptions; - using StorageType = UnitedMemoryLinks, - LinksTargetsAvlBalancedTreeMethods, - UnusedLinksListMethods>; - using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; - UsingStorage(action); - } - - TEST(StaticGenericLinksTests, CrudTestWithSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - } - - TEST(StaticGenericLinksTests, RawNumbersCrudTestWithSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - } - - TEST(StaticGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithSizeBalancedTrees) - { - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,16); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - } - - TEST(StaticGenericLinksTests, CrudTestWithRecursionlessSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - } - - TEST(StaticGenericLinksTests, RawNumbersCrudTestWithRecursionlessSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - } - - TEST(StaticGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithRecursionlessSizeBalancedTrees) - { - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,16); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - } - - TEST(StaticGenericLinksTests, CrudTestWithAvlBalancedTrees) - { - UsingStorageWithExternalReferencesWithAvlBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlBalancedTrees( - [](auto &&storage) { TestCrudOperations(storage); }); - } - - TEST(StaticGenericLinksTests, RawNumbersCrudTestWithAvlBalancedTrees) - { - UsingStorageWithExternalReferencesWithAvlBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - UsingStorageWithExternalReferencesWithAvlBalancedTrees( - [](auto &&storage) { TestRawNumbersCrudOperations(storage); }); - } - - TEST(StaticGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithAvlBalancedTrees) - { - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,16); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - } +template +static void UsingStorage(auto&& action) +{ + using namespace Platform::Memory; + TStorage storage{HeapResizableDirectMemory{}}; + action(storage); +} + +template +static void UsingStorageWithExternalReferencesWithSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using LinksOptionsType = LinksOptions; + using StorageType = UnitedMemoryLinks< + LinksOptionsType, HeapResizableDirectMemory, LinksSourcesSizeBalancedTreeMethods, + LinksTargetsSizeBalancedTreeMethods, UnusedLinksListMethods>; + UsingStorage(action); +} + +template +static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using namespace Platform::Data::Doublets::Decorators; + using LinksOptionsType = LinksOptions; + using StorageType = UnitedMemoryLinks< + LinksOptionsType, HeapResizableDirectMemory, LinksSourcesSizeBalancedTreeMethods, + LinksTargetsSizeBalancedTreeMethods, UnusedLinksListMethods>; + using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; + UsingStorage(action); +} + +template +static void UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using LinksOptionsType = LinksOptions; + using StorageType = UnitedMemoryLinks< + LinksOptionsType, HeapResizableDirectMemory, LinksSourcesRecursionlessSizeBalancedTreeMethods, + LinksTargetsRecursionlessSizeBalancedTreeMethods, UnusedLinksListMethods>; + UsingStorage(action); +} + +template +static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using namespace Platform::Data::Doublets::Decorators; + using LinksOptionsType = LinksOptions; + using StorageType = UnitedMemoryLinks< + LinksOptionsType, HeapResizableDirectMemory, LinksSourcesRecursionlessSizeBalancedTreeMethods, + LinksTargetsRecursionlessSizeBalancedTreeMethods, UnusedLinksListMethods>; + using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; + UsingStorage(action); +} + +template +static void UsingStorageWithExternalReferencesWithAvlBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using LinksOptionsType = LinksOptions; + using StorageType = UnitedMemoryLinks< + LinksOptionsType, HeapResizableDirectMemory, LinksSourcesAvlBalancedTreeMethods, + LinksTargetsAvlBalancedTreeMethods, UnusedLinksListMethods>; + UsingStorage(action); +} + +template +static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::United::Generic; + using namespace Platform::Data::Doublets::Decorators; + using LinksOptionsType = LinksOptions; + using StorageType = UnitedMemoryLinks< + LinksOptionsType, HeapResizableDirectMemory, LinksSourcesAvlBalancedTreeMethods, + LinksTargetsAvlBalancedTreeMethods, UnusedLinksListMethods>; + using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; + UsingStorage(action); +} + +TEST(StaticGenericLinksTests, CrudTestWithSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); +} + +TEST(StaticGenericLinksTests, RawNumbersCrudTestWithSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); +} + +TEST(StaticGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithSizeBalancedTrees) +{ + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 16); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); +} + +TEST(StaticGenericLinksTests, CrudTestWithRecursionlessSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestCrudOperations(storage); }); +} + +TEST(StaticGenericLinksTests, RawNumbersCrudTestWithRecursionlessSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { TestRawNumbersCrudOperations(storage); }); +} + +TEST(StaticGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithRecursionlessSizeBalancedTrees) +{ + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 16); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); +} + +TEST(StaticGenericLinksTests, CrudTestWithAvlBalancedTrees) +{ + UsingStorageWithExternalReferencesWithAvlBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlBalancedTrees([](auto&& storage) + { TestCrudOperations(storage); }); +} + +TEST(StaticGenericLinksTests, RawNumbersCrudTestWithAvlBalancedTrees) +{ + UsingStorageWithExternalReferencesWithAvlBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithAvlBalancedTrees([](auto&& storage) + { TestRawNumbersCrudOperations(storage); }); +} + +TEST(StaticGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithAvlBalancedTrees) +{ + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 16); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithAvlBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); } +} // namespace Platform::Data::Doublets::Tests::Static::GenericLinksTests diff --git a/cpp/Platform.Data.Doublets.Tests/Static/SplitMemoryGenericLinksTests.cpp b/cpp/Platform.Data.Doublets.Tests/Static/SplitMemoryGenericLinksTests.cpp index 7acbd9de8..2c91439e2 100644 --- a/cpp/Platform.Data.Doublets.Tests/Static/SplitMemoryGenericLinksTests.cpp +++ b/cpp/Platform.Data.Doublets.Tests/Static/SplitMemoryGenericLinksTests.cpp @@ -1,147 +1,180 @@ namespace Platform::Data::Doublets::Tests::Static::SplitMemoryGenericLinksTests { - template - static void UsingStorage(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - TStorage storage{ HeapResizableDirectMemory{ }, HeapResizableDirectMemory{ } }; - action(storage); - } +template +static void UsingStorage(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + TStorage storage{HeapResizableDirectMemory{}, HeapResizableDirectMemory{}}; + action(storage); +} - template - static void UsingStorageWithoutExternalReferencesWithSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using LinksOptionsType = LinksOptions{false}>; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsSizeBalancedTreeMethods, ExternalLinksSourcesSizeBalancedTreeMethods, ExternalLinksTargetsSizeBalancedTreeMethods, UnusedLinksListMethods>; - UsingStorage(action); - } +template +static void UsingStorageWithoutExternalReferencesWithSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using LinksOptionsType = LinksOptions{false}>; + using StorageType = SplitMemoryLinks< + LinksOptionsType, HeapResizableDirectMemory, InternalLinksSourcesSizeBalancedTreeMethods, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsSizeBalancedTreeMethods, + ExternalLinksSourcesSizeBalancedTreeMethods, + ExternalLinksTargetsSizeBalancedTreeMethods, UnusedLinksListMethods>; + UsingStorage(action); +} - template - static void UsingStorageWithExternalReferencesWithSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using LinksOptionsType = LinksOptions; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsSizeBalancedTreeMethods, ExternalLinksSourcesSizeBalancedTreeMethods, ExternalLinksTargetsSizeBalancedTreeMethods, UnusedLinksListMethods>; - UsingStorage(action); - } +template +static void UsingStorageWithExternalReferencesWithSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using LinksOptionsType = LinksOptions; + using StorageType = SplitMemoryLinks< + LinksOptionsType, HeapResizableDirectMemory, InternalLinksSourcesSizeBalancedTreeMethods, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsSizeBalancedTreeMethods, + ExternalLinksSourcesSizeBalancedTreeMethods, + ExternalLinksTargetsSizeBalancedTreeMethods, UnusedLinksListMethods>; + UsingStorage(action); +} - template - static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using namespace Platform::Data::Doublets::Decorators; - using LinksOptionsType = LinksOptions{false}>; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsSizeBalancedTreeMethods, ExternalLinksSourcesSizeBalancedTreeMethods, ExternalLinksTargetsSizeBalancedTreeMethods, UnusedLinksListMethods>; - using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; - UsingStorage(action); - } +template +static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using namespace Platform::Data::Doublets::Decorators; + using LinksOptionsType = LinksOptions{false}>; + using StorageType = SplitMemoryLinks< + LinksOptionsType, HeapResizableDirectMemory, InternalLinksSourcesSizeBalancedTreeMethods, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsSizeBalancedTreeMethods, + ExternalLinksSourcesSizeBalancedTreeMethods, + ExternalLinksTargetsSizeBalancedTreeMethods, UnusedLinksListMethods>; + using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; + UsingStorage(action); +} - template - static void UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using LinksOptionsType = LinksOptions{false}>; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, UnusedLinksListMethods>; - UsingStorage(action); - } +template +static void UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using LinksOptionsType = LinksOptions{false}>; + using StorageType = SplitMemoryLinks, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, + ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + UnusedLinksListMethods>; + UsingStorage(action); +} - template - static void UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using LinksOptionsType = LinksOptions; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, UnusedLinksListMethods>; - UsingStorage(action); - } +template +static void UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using LinksOptionsType = LinksOptions; + using StorageType = SplitMemoryLinks, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, + ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + UnusedLinksListMethods>; + UsingStorage(action); +} - template - static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees(auto&& action) - { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets::Memory::Split::Generic; - using namespace Platform::Data::Doublets::Decorators; - using LinksOptionsType = LinksOptions{false}>; - using StorageType = SplitMemoryLinks, InternalLinksSourcesLinkedListMethods, InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, UnusedLinksListMethods>; - using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; - UsingStorage(action); - } +template +static void UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees(auto&& action) +{ + using namespace Platform::Memory; + using namespace Platform::Data::Doublets::Memory::Split::Generic; + using namespace Platform::Data::Doublets::Decorators; + using LinksOptionsType = LinksOptions{false}>; + using StorageType = SplitMemoryLinks, + InternalLinksSourcesLinkedListMethods, + InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, + ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, + UnusedLinksListMethods>; + using DecoratedStorageType = LinksDecoratedWithAutomaticUniquenessAndUsagesResolution; + UsingStorage(action); +} - TEST(StaticSplitMemoryGenericLinksTests, CrudTestWithSizeBalancedTrees) - { - UsingStorageWithoutExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - } +TEST(StaticSplitMemoryGenericLinksTests, CrudTestWithSizeBalancedTrees) +{ + UsingStorageWithoutExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithSizeBalancedTrees([](auto&& storage) + { return TestCrudOperations(storage); }); +} - TEST(StaticSplitMemoryGenericLinksTests, RawNumbersCrudTestWithSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - } +TEST(StaticSplitMemoryGenericLinksTests, RawNumbersCrudTestWithSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); +} - TEST(StaticSplitMemoryGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithSizeBalancedTrees) - { - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,16); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - } +TEST(StaticSplitMemoryGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithSizeBalancedTrees) +{ + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 16); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); +} - TEST(StaticSplitMemoryGenericLinksTests, CrudTestWithRecursionlessSizeBalancedTrees) - { - UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( - [](auto &&storage) { return TestCrudOperations(storage); }); - } +TEST(StaticSplitMemoryGenericLinksTests, CrudTestWithRecursionlessSizeBalancedTrees) +{ + UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestCrudOperations(storage); }); + UsingStorageWithoutExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestCrudOperations(storage); }); +} - TEST(StaticSplitMemoryGenericLinksTests, RawNumbersCrudTestWithRecursionlessSizeBalancedTrees) - { - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees([](auto &&storage) { - return TestRawNumbersCrudOperations(storage); - }); - } +TEST(StaticSplitMemoryGenericLinksTests, RawNumbersCrudTestWithRecursionlessSizeBalancedTrees) +{ + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); + UsingStorageWithExternalReferencesWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestRawNumbersCrudOperations(storage); }); +} - TEST(StaticSplitMemoryGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithRecursionlessSizeBalancedTrees) - { - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,16); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees([] (auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage,100); }); - } +TEST(StaticSplitMemoryGenericLinksTests, MultipleRandomCreationsAndDeletionsTestWithRecursionlessSizeBalancedTrees) +{ + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 16); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); + UsingDecoratedWithAutomaticUniquenessAndUsagesResolutionWithRecursionlessSizeBalancedTrees( + [](auto&& storage) { return TestMultipleRandomCreationsAndDeletions(storage, 100); }); } +} // namespace Platform::Data::Doublets::Tests::Static::SplitMemoryGenericLinksTests diff --git a/cpp/Platform.Data.Doublets/CriterionMatchers/TargetMatcher.h b/cpp/Platform.Data.Doublets/CriterionMatchers/TargetMatcher.h index 53f98cad4..4670f7cab 100644 --- a/cpp/Platform.Data.Doublets/CriterionMatchers/TargetMatcher.h +++ b/cpp/Platform.Data.Doublets/CriterionMatchers/TargetMatcher.h @@ -1,12 +1,20 @@ namespace Platform::Data::Doublets::CriterionMatchers { - template class TargetMatcher; - template class TargetMatcher : public LinksOperatorBase, ICriterionMatcher - { - private: TLinkAddress _targetToMatch = 0; +template +class TargetMatcher; +template +class TargetMatcher : public LinksOperatorBase, ICriterionMatcher +{ +private: + TLinkAddress _targetToMatch = 0; - public: TargetMatcher(ILinks &storage, TLinkAddress targetToMatch) : base(storage) { return _targetToMatch = targetToMatch; } +public: + TargetMatcher(ILinks& storage, TLinkAddress targetToMatch) : base(storage) + { + return _targetToMatch = targetToMatch; + } - public: bool IsMatched(TLinkAddress link) { return _links.GetTarget(link) == _targetToMatch; } - }; -} +public: + bool IsMatched(TLinkAddress link) { return _links.GetTarget(link) == _targetToMatch; } +}; +} // namespace Platform::Data::Doublets::CriterionMatchers diff --git a/cpp/Platform.Data.Doublets/Decorators/Decorators.h b/cpp/Platform.Data.Doublets/Decorators/Decorators.h index c05dd243d..4658d30c5 100644 --- a/cpp/Platform.Data.Doublets/Decorators/Decorators.h +++ b/cpp/Platform.Data.Doublets/Decorators/Decorators.h @@ -2,6 +2,8 @@ using namespace Platform::Interfaces; using namespace Platform::Data::Doublets::Decorators; namespace Platform::Data::Doublets::Decorators { - template - using LinksDecoratedWithAutomaticUniquenessAndUsagesResolution = Platform::Interfaces::Decorated; +template +using LinksDecoratedWithAutomaticUniquenessAndUsagesResolution = + Platform::Interfaces::Decorated; } diff --git a/cpp/Platform.Data.Doublets/Decorators/LinksCascadeUniquenessAndUsagesResolver.h b/cpp/Platform.Data.Doublets/Decorators/LinksCascadeUniquenessAndUsagesResolver.h index 1b46dcd1e..9e4809e59 100644 --- a/cpp/Platform.Data.Doublets/Decorators/LinksCascadeUniquenessAndUsagesResolver.h +++ b/cpp/Platform.Data.Doublets/Decorators/LinksCascadeUniquenessAndUsagesResolver.h @@ -1,22 +1,24 @@ namespace Platform::Data::Doublets::Decorators { - template - struct LinksCascadeUniquenessAndUsagesResolver : public LinksUniquenessResolver - { - public: +template +struct LinksCascadeUniquenessAndUsagesResolver : public LinksUniquenessResolver +{ +public: using base = LinksUniquenessResolver; + using base::Constants; using typename base::LinkAddressType; using typename base::LinkType; - using typename base::WriteHandlerType; using typename base::ReadHandlerType; - using base::Constants; - public: - USE_ALL_BASE_CONSTRUCTORS(LinksCascadeUniquenessAndUsagesResolver, base); + using typename base::WriteHandlerType; - public: LinkAddressType ResolveAddressChangeConflict(LinkAddressType oldLinkAddress, LinkAddressType newLinkAddress) - { - this->facade().TFacade::MergeUsages(oldLinkAddress, newLinkAddress); - return base::ResolveAddressChangeConflict(oldLinkAddress, newLinkAddress); - } - }; -} +public: + USE_ALL_BASE_CONSTRUCTORS(LinksCascadeUniquenessAndUsagesResolver, base); + +public: + LinkAddressType ResolveAddressChangeConflict(LinkAddressType oldLinkAddress, LinkAddressType newLinkAddress) + { + this->facade().TFacade::MergeUsages(oldLinkAddress, newLinkAddress); + return base::ResolveAddressChangeConflict(oldLinkAddress, newLinkAddress); + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/LinksCascadeUsagesResolver.h b/cpp/Platform.Data.Doublets/Decorators/LinksCascadeUsagesResolver.h index 16ef52fff..2e9975334 100644 --- a/cpp/Platform.Data.Doublets/Decorators/LinksCascadeUsagesResolver.h +++ b/cpp/Platform.Data.Doublets/Decorators/LinksCascadeUsagesResolver.h @@ -1,25 +1,27 @@ namespace Platform::Data::Doublets::Decorators { - template - struct LinksCascadeUsagesResolver : DecoratorBase - { - public: - using base = DecoratorBase; - using typename base::LinkAddressType; - using typename base::LinkType; - using typename base::WriteHandlerType; - using typename base::ReadHandlerType; - using base::Constants; - public: - USE_ALL_BASE_CONSTRUCTORS(LinksCascadeUsagesResolver, base); +template +struct LinksCascadeUsagesResolver : DecoratorBase +{ +public: + using base = DecoratorBase; + using base::Constants; + using typename base::LinkAddressType; + using typename base::LinkType; + using typename base::ReadHandlerType; + using typename base::WriteHandlerType; - public: LinkAddressType Delete( const LinkType& restriction, const WriteHandlerType& handler) - { - auto $continue {Constants.Continue}; - auto linkIndex = restriction[Constants.IndexPart]; - WriteHandlerState handlerState {Constants.Continue, Constants.Break, handler}; - handlerState.Apply(DeleteAllUsages(this->facade(), linkIndex, handlerState.Handler)); - return handlerState.Apply(this->decorated().TDecorated::Delete(LinkType{linkIndex}, handlerState.Handler)); - } - }; -} +public: + USE_ALL_BASE_CONSTRUCTORS(LinksCascadeUsagesResolver, base); + +public: + LinkAddressType Delete(const LinkType& restriction, const WriteHandlerType& handler) + { + auto $continue{Constants.Continue}; + auto linkIndex = restriction[Constants.IndexPart]; + WriteHandlerState handlerState{Constants.Continue, Constants.Break, handler}; + handlerState.Apply(DeleteAllUsages(this->facade(), linkIndex, handlerState.Handler)); + return handlerState.Apply(this->decorated().TDecorated::Delete(LinkType{linkIndex}, handlerState.Handler)); + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/LinksDisposableDecoratorBase.h b/cpp/Platform.Data.Doublets/Decorators/LinksDisposableDecoratorBase.h index 990809014..2121ceb3d 100644 --- a/cpp/Platform.Data.Doublets/Decorators/LinksDisposableDecoratorBase.h +++ b/cpp/Platform.Data.Doublets/Decorators/LinksDisposableDecoratorBase.h @@ -1,32 +1,40 @@ namespace Platform::Data::Doublets::Decorators { - template class LinksDisposableDecoratorBase; - template class LinksDisposableDecoratorBase : public DecoratorBase, ILinks, System::IDisposable +template +class LinksDisposableDecoratorBase; +template +class LinksDisposableDecoratorBase + : public DecoratorBase, ILinks, System::IDisposable +{ + class DisposableWithMultipleCallsAllowed : public Disposable { - class DisposableWithMultipleCallsAllowed : public Disposable - { - public: DisposableWithMultipleCallsAllowed(std::function disposal) : base(disposal) { } + public: + DisposableWithMultipleCallsAllowed(std::function disposal) : base(disposal) {} - public: bool AllowMultipleDisposeCalls - { - get => true; - } - } + public: + bool AllowMultipleDisposeCalls { get = > true; } + } - public: DisposableWithMultipleCallsAllowed Disposable = 0; + public : DisposableWithMultipleCallsAllowed Disposable = 0; - public: LinksDisposableDecoratorBase(ILinks &storage) : base(storage) { return Disposable = DisposableWithMultipleCallsAllowed(Dispose); } +public: + LinksDisposableDecoratorBase(ILinks& storage) : base(storage) + { + return Disposable = DisposableWithMultipleCallsAllowed(Dispose); + } - ~LinksDisposableDecoratorBase() { Disposable.Destruct(); } + ~LinksDisposableDecoratorBase() { Disposable.Destruct(); } - public: void Dispose() { Disposable.Dispose(); } +public: + void Dispose() { Disposable.Dispose(); } - public: virtual void Dispose(bool manual, bool wasDisposed) +public: + virtual void Dispose(bool manual, bool wasDisposed) + { + if (!wasDisposed) { - if (!wasDisposed) - { - this->decorated().TDecorated::DisposeIfPossible(); - } + this->decorated().TDecorated::DisposeIfPossible(); } - }; -} + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/LinksInnerReferenceExistenceValidator.h b/cpp/Platform.Data.Doublets/Decorators/LinksInnerReferenceExistenceValidator.h index 340491cc6..27f699ad0 100644 --- a/cpp/Platform.Data.Doublets/Decorators/LinksInnerReferenceExistenceValidator.h +++ b/cpp/Platform.Data.Doublets/Decorators/LinksInnerReferenceExistenceValidator.h @@ -1,28 +1,34 @@ namespace Platform::Data::Doublets::Decorators { - template class LinksInnerReferenceExistenceValidator; - template class LinksInnerReferenceExistenceValidator : public DecoratorBase - { - public: LinksInnerReferenceExistenceValidator(ILinks &storage) : DecoratorBase(storage) { } +template +class LinksInnerReferenceExistenceValidator; +template +class LinksInnerReferenceExistenceValidator : public DecoratorBase +{ +public: + LinksInnerReferenceExistenceValidator(ILinks& storage) : DecoratorBase(storage) {} - public: TLinkAddress Each(Func, TLinkAddress> handler, const LinkType& restriction) - { - storage.EnsureInnerReferenceExists(restriction, "restriction"); - return storage.Each(restriction, handler); - } +public: + TLinkAddress Each(Func, TLinkAddress> handler, const LinkType& restriction) + { + storage.EnsureInnerReferenceExists(restriction, "restriction"); + return storage.Each(restriction, handler); + } - public: TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) - { - storage.EnsureInnerReferenceExists(restriction, "restriction"); - storage.EnsureInnerReferenceExists(substitution, "substitution"); - return storage.Update(restriction, substitution); - } +public: + TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) + { + storage.EnsureInnerReferenceExists(restriction, "restriction"); + storage.EnsureInnerReferenceExists(substitution, "substitution"); + return storage.Update(restriction, substitution); + } - public: void Delete(const LinkType& restriction) - { - auto link = restriction[_constants.IndexPart]; - storage.EnsureLinkExists(link, "link"); - storage.Delete(link); - } - }; -} +public: + void Delete(const LinkType& restriction) + { + auto link = restriction[_constants.IndexPart]; + storage.EnsureLinkExists(link, "link"); + storage.Delete(link); + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/LinksItselfConstantToSelfReferenceResolver.h b/cpp/Platform.Data.Doublets/Decorators/LinksItselfConstantToSelfReferenceResolver.h index 13278c38b..b175fb5bb 100644 --- a/cpp/Platform.Data.Doublets/Decorators/LinksItselfConstantToSelfReferenceResolver.h +++ b/cpp/Platform.Data.Doublets/Decorators/LinksItselfConstantToSelfReferenceResolver.h @@ -1,21 +1,31 @@ namespace Platform::Data::Doublets::Decorators { - template class LinksItselfConstantToSelfReferenceResolver; - template class LinksItselfConstantToSelfReferenceResolver : public DecoratorBase - { - public: LinksItselfConstantToSelfReferenceResolver(ILinks &storage) : DecoratorBase(storage) { } +template +class LinksItselfConstantToSelfReferenceResolver; +template +class LinksItselfConstantToSelfReferenceResolver : public DecoratorBase +{ +public: + LinksItselfConstantToSelfReferenceResolver(ILinks& storage) : DecoratorBase(storage) {} - public: TLinkAddress Each(Func, TLinkAddress> handler, const LinkType& restriction) +public: + TLinkAddress Each(Func, TLinkAddress> handler, const LinkType& restriction) + { + auto constants = _constants; + auto itselfConstant = constants.Itself; + if (!constants.Any == itselfConstant && restriction.Contains(itselfConstant)) { - auto constants = _constants; - auto itselfConstant = constants.Itself; - if (!constants.Any == itselfConstant && restriction.Contains(itselfConstant)) - { - return constants.Continue; - } - return this->decorated().TDecorated::Each(restriction, handler); + return constants.Continue; } + return this->decorated().TDecorated::Each(restriction, handler); + } - public: TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) { return this->decorated().TDecorated::Update(restriction, this->decorated().TDecorated::ResolveConstantAsSelfReference(_constants.Itself, restriction, substitution)); } - }; -} +public: + TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) + { + return this->decorated().TDecorated::Update( + restriction, + this->decorated().TDecorated::ResolveConstantAsSelfReference(_constants.Itself, restriction, substitution)); + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/LinksNonExistentDependenciesCreator.h b/cpp/Platform.Data.Doublets/Decorators/LinksNonExistentDependenciesCreator.h index 15e7d4bb2..09e3f0a4a 100644 --- a/cpp/Platform.Data.Doublets/Decorators/LinksNonExistentDependenciesCreator.h +++ b/cpp/Platform.Data.Doublets/Decorators/LinksNonExistentDependenciesCreator.h @@ -1,15 +1,19 @@ namespace Platform::Data::Doublets::Decorators { - template class LinksNonExistentDependenciesCreator; - template class LinksNonExistentDependenciesCreator : public DecoratorBase - { - public: LinksNonExistentDependenciesCreator(ILinks &storage) : DecoratorBase(storage) { } +template +class LinksNonExistentDependenciesCreator; +template +class LinksNonExistentDependenciesCreator : public DecoratorBase +{ +public: + LinksNonExistentDependenciesCreator(ILinks& storage) : DecoratorBase(storage) {} - public: TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) - { - auto constants = _constants; - storage.EnsureCreated(substitution[constants.SourcePart], substitution[constants.TargetPart]); - return storage.Update(restriction, substitution); - } - }; -} +public: + TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) + { + auto constants = _constants; + storage.EnsureCreated(substitution[constants.SourcePart], substitution[constants.TargetPart]); + return storage.Update(restriction, substitution); + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/LinksNullConstantToSelfReferenceResolver.h b/cpp/Platform.Data.Doublets/Decorators/LinksNullConstantToSelfReferenceResolver.h index 17fc8936f..2348371c4 100644 --- a/cpp/Platform.Data.Doublets/Decorators/LinksNullConstantToSelfReferenceResolver.h +++ b/cpp/Platform.Data.Doublets/Decorators/LinksNullConstantToSelfReferenceResolver.h @@ -1,12 +1,22 @@ namespace Platform::Data::Doublets::Decorators { - template class LinksNullConstantToSelfReferenceResolver; - template class LinksNullConstantToSelfReferenceResolver : public DecoratorBase - { - public: LinksNullConstantToSelfReferenceResolver(ILinks &storage) : DecoratorBase(storage) { } +template +class LinksNullConstantToSelfReferenceResolver; +template +class LinksNullConstantToSelfReferenceResolver : public DecoratorBase +{ +public: + LinksNullConstantToSelfReferenceResolver(ILinks& storage) : DecoratorBase(storage) {} - public: TLinkAddress Create(const LinkType& restriction) { return this->decorated().TDecorated::CreatePoint(); } +public: + TLinkAddress Create(const LinkType& restriction) { return this->decorated().TDecorated::CreatePoint(); } - public: TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) { return this->decorated().TDecorated::Update(restriction, this->decorated().TDecorated::ResolveConstantAsSelfReference(_constants.Null, restriction, substitution)); } - }; -} +public: + TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) + { + return this->decorated().TDecorated::Update( + restriction, + this->decorated().TDecorated::ResolveConstantAsSelfReference(_constants.Null, restriction, substitution)); + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/LinksUniquenessResolver.h b/cpp/Platform.Data.Doublets/Decorators/LinksUniquenessResolver.h index 770e5c90f..606e3fa98 100644 --- a/cpp/Platform.Data.Doublets/Decorators/LinksUniquenessResolver.h +++ b/cpp/Platform.Data.Doublets/Decorators/LinksUniquenessResolver.h @@ -1,35 +1,40 @@ namespace Platform::Data::Doublets::Decorators { - template - struct LinksUniquenessResolver : DecoratorBase - { - public: - using base = DecoratorBase; - using typename base::LinkAddressType; - using typename base::LinkType; - using typename base::WriteHandlerType; - using typename base::ReadHandlerType; - using base::Constants; - public: - USE_ALL_BASE_CONSTRUCTORS(LinksUniquenessResolver, base); +template +struct LinksUniquenessResolver : DecoratorBase +{ +public: + using base = DecoratorBase; + using base::Constants; + using typename base::LinkAddressType; + using typename base::LinkType; + using typename base::ReadHandlerType; + using typename base::WriteHandlerType; + +public: + USE_ALL_BASE_CONSTRUCTORS(LinksUniquenessResolver, base); - public: LinkAddressType Update( const LinkType& restriction, const LinkType& substitution, const WriteHandlerType& handler) +public: + LinkAddressType Update(const LinkType& restriction, const LinkType& substitution, const WriteHandlerType& handler) + { + auto newLinkAddress = + SearchOrDefault(this->decorated(), substitution[Constants.SourcePart], substitution[Constants.TargetPart]); + if (newLinkAddress == LinkAddressType{}) { - auto newLinkAddress = SearchOrDefault(this->decorated(), substitution[Constants.SourcePart], substitution[Constants.TargetPart]); - if (newLinkAddress == LinkAddressType{}) - { - return this->decorated().TDecorated::Update(restriction, substitution, handler); - } - return this->ResolveAddressChangeConflict(restriction[Constants.IndexPart], newLinkAddress, handler); + return this->decorated().TDecorated::Update(restriction, substitution, handler); } + return this->ResolveAddressChangeConflict(restriction[Constants.IndexPart], newLinkAddress, handler); + } - public: LinkAddressType ResolveAddressChangeConflict(LinkAddressType oldLinkAddress, LinkAddressType newLinkAddress, const WriteHandlerType& handler) +public: + LinkAddressType ResolveAddressChangeConflict(LinkAddressType oldLinkAddress, LinkAddressType newLinkAddress, + const WriteHandlerType& handler) + { + if (oldLinkAddress != newLinkAddress && Exists(this->decorated(), oldLinkAddress)) { - if (oldLinkAddress != newLinkAddress && Exists(this->decorated(), oldLinkAddress)) - { - this->facade().Delete(LinkType{oldLinkAddress}, handler); - } - return Constants.Continue; + this->facade().Delete(LinkType{oldLinkAddress}, handler); } - }; -} + return Constants.Continue; + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/LinksUniquenessValidator.h b/cpp/Platform.Data.Doublets/Decorators/LinksUniquenessValidator.h index b9c3dc763..c2995bb28 100644 --- a/cpp/Platform.Data.Doublets/Decorators/LinksUniquenessValidator.h +++ b/cpp/Platform.Data.Doublets/Decorators/LinksUniquenessValidator.h @@ -1,15 +1,19 @@ namespace Platform::Data::Doublets::Decorators { - template class LinksUniquenessValidator; - template class LinksUniquenessValidator : public DecoratorBase - { - public: LinksUniquenessValidator(ILinks &storage) : DecoratorBase(storage) { } +template +class LinksUniquenessValidator; +template +class LinksUniquenessValidator : public DecoratorBase +{ +public: + LinksUniquenessValidator(ILinks& storage) : DecoratorBase(storage) {} - public: TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) - { - auto constants = _constants; - storage.EnsureDoesNotExists(substitution[constants.SourcePart], substitution[constants.TargetPart]); - return storage.Update(restriction, substitution); - } - }; -} +public: + TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) + { + auto constants = _constants; + storage.EnsureDoesNotExists(substitution[constants.SourcePart], substitution[constants.TargetPart]); + return storage.Update(restriction, substitution); + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/LinksUsagesValidator.h b/cpp/Platform.Data.Doublets/Decorators/LinksUsagesValidator.h index be3011905..2815133e4 100644 --- a/cpp/Platform.Data.Doublets/Decorators/LinksUsagesValidator.h +++ b/cpp/Platform.Data.Doublets/Decorators/LinksUsagesValidator.h @@ -1,21 +1,26 @@ namespace Platform::Data::Doublets::Decorators { - template class LinksUsagesValidator; - template class LinksUsagesValidator : public DecoratorBase - { - public: LinksUsagesValidator(ILinks &storage) : DecoratorBase(storage) { } +template +class LinksUsagesValidator; +template +class LinksUsagesValidator : public DecoratorBase +{ +public: + LinksUsagesValidator(ILinks& storage) : DecoratorBase(storage) {} - public: TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) - { - storage.EnsureNoUsages(restriction[_constants.IndexPart]); - return storage.Update(restriction, substitution); - } +public: + TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) + { + storage.EnsureNoUsages(restriction[_constants.IndexPart]); + return storage.Update(restriction, substitution); + } - public: void Delete(const LinkType& restriction) - { - auto link = restriction[_constants.IndexPart]; - storage.EnsureNoUsages(link); - storage.Delete(link); - } - }; -} +public: + void Delete(const LinkType& restriction) + { + auto link = restriction[_constants.IndexPart]; + storage.EnsureNoUsages(link); + storage.Delete(link); + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/NonNullContentsLinkDeletionResolver.h b/cpp/Platform.Data.Doublets/Decorators/NonNullContentsLinkDeletionResolver.h index 35f6ebd27..58d0a4668 100644 --- a/cpp/Platform.Data.Doublets/Decorators/NonNullContentsLinkDeletionResolver.h +++ b/cpp/Platform.Data.Doublets/Decorators/NonNullContentsLinkDeletionResolver.h @@ -1,25 +1,27 @@ namespace Platform::Data::Doublets::Decorators { - template - struct NonNullContentsLinkDeletionResolver : public DecoratorBase - { - public: - using base = DecoratorBase; - using typename base::LinkAddressType; - using typename base::LinkType; - using typename base::WriteHandlerType; - using typename base::ReadHandlerType; - using base::Constants; - public: - USE_ALL_BASE_CONSTRUCTORS(NonNullContentsLinkDeletionResolver, base); +template +struct NonNullContentsLinkDeletionResolver : public DecoratorBase +{ +public: + using base = DecoratorBase; + using base::Constants; + using typename base::LinkAddressType; + using typename base::LinkType; + using typename base::ReadHandlerType; + using typename base::WriteHandlerType; - public: LinkAddressType Delete( const LinkType& restriction, const WriteHandlerType& handler) - { - auto $break = Constants.Break; - auto linkIndex = restriction[Constants.IndexPart]; - WriteHandlerState handlerState {Constants.Continue, Constants.Break, handler}; - handlerState.Apply(EnforceResetValues(this->decorated(), linkIndex, handlerState.Handler)); - return handlerState.Apply(this->decorated().TDecorated::Delete(LinkType{linkIndex}, handlerState.Handler)); - } - }; -} +public: + USE_ALL_BASE_CONSTRUCTORS(NonNullContentsLinkDeletionResolver, base); + +public: + LinkAddressType Delete(const LinkType& restriction, const WriteHandlerType& handler) + { + auto $break = Constants.Break; + auto linkIndex = restriction[Constants.IndexPart]; + WriteHandlerState handlerState{Constants.Continue, Constants.Break, handler}; + handlerState.Apply(EnforceResetValues(this->decorated(), linkIndex, handlerState.Handler)); + return handlerState.Apply(this->decorated().TDecorated::Delete(LinkType{linkIndex}, handlerState.Handler)); + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/UInt32Links.h b/cpp/Platform.Data.Doublets/Decorators/UInt32Links.h index f4279b31f..a47e0b403 100644 --- a/cpp/Platform.Data.Doublets/Decorators/UInt32Links.h +++ b/cpp/Platform.Data.Doublets/Decorators/UInt32Links.h @@ -4,50 +4,54 @@ using TLinkAddress = std::uint32_t; namespace Platform::Data::Doublets::Decorators { - class UInt32Links : public LinksDisposableDecoratorBase - { - public: UInt32Links(ILinks &storage) : base(storage) { } +class UInt32Links : public LinksDisposableDecoratorBase +{ +public: + UInt32Links(ILinks& storage) : base(storage) {} - public: TLinkAddress Create(const LinkType& restriction) { return this->decorated().TDecorated::CreatePoint(); } +public: + TLinkAddress Create(const LinkType& restriction) { return this->decorated().TDecorated::CreatePoint(); } - public: TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) +public: + TLinkAddress Update(const LinkType& restriction, const LinkType& substitution) + { + auto constants = _constants; + auto indexPartConstant = constants.IndexPart; + auto sourcePartConstant = constants.SourcePart; + auto targetPartConstant = constants.TargetPart; + auto nullConstant = constants.Null; + auto itselfConstant = constants.Itself; + auto existedLink = nullConstant; + auto updatedLink = restriction[indexPartConstant]; + auto newSource = substitution[sourcePartConstant]; + auto newTarget = substitution[targetPartConstant]; + if (newSource != itselfConstant && newTarget != itselfConstant) { - auto constants = _constants; - auto indexPartConstant = constants.IndexPart; - auto sourcePartConstant = constants.SourcePart; - auto targetPartConstant = constants.TargetPart; - auto nullConstant = constants.Null; - auto itselfConstant = constants.Itself; - auto existedLink = nullConstant; - auto updatedLink = restriction[indexPartConstant]; - auto newSource = substitution[sourcePartConstant]; - auto newTarget = substitution[targetPartConstant]; - if (newSource != itselfConstant && newTarget != itselfConstant) - { - existedLink = storage.SearchOrDefault(newSource, newTarget); - } - if (existedLink == nullConstant) - { - auto before = storage.GetLink(updatedLink); - if (before[sourcePartConstant] != newSource || before[targetPartConstant] != newTarget) - { - storage.Update(updatedLink, newSource == itselfConstant ? updatedLink : newSource, - newTarget == itselfConstant ? updatedLink : newTarget); - } - return updatedLink; - } - else + existedLink = storage.SearchOrDefault(newSource, newTarget); + } + if (existedLink == nullConstant) + { + auto before = storage.GetLink(updatedLink); + if (before[sourcePartConstant] != newSource || before[targetPartConstant] != newTarget) { - return this->facade().TFacade::MergeAndDelete(updatedLink, existedLink); + storage.Update(updatedLink, newSource == itselfConstant ? updatedLink : newSource, + newTarget == itselfConstant ? updatedLink : newTarget); } + return updatedLink; } - - public: void Delete(const LinkType& restriction) + else { - auto linkIndex = restriction[_constants.IndexPart]; - storage.EnforceResetValues(linkIndex); - this->facade().TFacade::DeleteAllUsages(linkIndex); - storage.Delete(linkIndex); + return this->facade().TFacade::MergeAndDelete(updatedLink, existedLink); } - }; -} + } + +public: + void Delete(const LinkType& restriction) + { + auto linkIndex = restriction[_constants.IndexPart]; + storage.EnforceResetValues(linkIndex); + this->facade().TFacade::DeleteAllUsages(linkIndex); + storage.Delete(linkIndex); + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/UInt64Links.h b/cpp/Platform.Data.Doublets/Decorators/UInt64Links.h index 05a4d326c..9e0462b22 100644 --- a/cpp/Platform.Data.Doublets/Decorators/UInt64Links.h +++ b/cpp/Platform.Data.Doublets/Decorators/UInt64Links.h @@ -1,49 +1,53 @@ namespace Platform::Data::Doublets::Decorators { - class UInt64Links : public LinksDisposableDecoratorBase - { - public: UInt64Links(ILinks &storage) : base(storage) { } +class UInt64Links : public LinksDisposableDecoratorBase +{ +public: + UInt64Links(ILinks& storage) : base(storage) {} - public: std::uint64_t Create(IList &restriction) { return this->decorated().TDecorated::CreatePoint(); } +public: + std::uint64_t Create(IList& restriction) { return this->decorated().TDecorated::CreatePoint(); } - public: std::uint64_t Update(IList &restriction, IList &substitution) +public: + std::uint64_t Update(IList& restriction, IList& substitution) + { + auto constants = _constants; + auto indexPartConstant = constants.IndexPart; + auto sourcePartConstant = constants.SourcePart; + auto targetPartConstant = constants.TargetPart; + auto nullConstant = constants.Null; + auto itselfConstant = constants.Itself; + auto existedLink = nullConstant; + auto updatedLink = restriction[indexPartConstant]; + auto newSource = substitution[sourcePartConstant]; + auto newTarget = substitution[targetPartConstant]; + if (newSource != itselfConstant && newTarget != itselfConstant) { - auto constants = _constants; - auto indexPartConstant = constants.IndexPart; - auto sourcePartConstant = constants.SourcePart; - auto targetPartConstant = constants.TargetPart; - auto nullConstant = constants.Null; - auto itselfConstant = constants.Itself; - auto existedLink = nullConstant; - auto updatedLink = restriction[indexPartConstant]; - auto newSource = substitution[sourcePartConstant]; - auto newTarget = substitution[targetPartConstant]; - if (newSource != itselfConstant && newTarget != itselfConstant) - { - existedLink = storage.SearchOrDefault(newSource, newTarget); - } - if (existedLink == nullConstant) - { - auto before = storage.GetLink(updatedLink); - if (before[sourcePartConstant] != newSource || before[targetPartConstant] != newTarget) - { - storage.Update(updatedLink, newSource == itselfConstant ? updatedLink : newSource, - newTarget == itselfConstant ? updatedLink : newTarget); - } - return updatedLink; - } - else + existedLink = storage.SearchOrDefault(newSource, newTarget); + } + if (existedLink == nullConstant) + { + auto before = storage.GetLink(updatedLink); + if (before[sourcePartConstant] != newSource || before[targetPartConstant] != newTarget) { - return this->facade().TFacade::MergeAndDelete(updatedLink, existedLink); + storage.Update(updatedLink, newSource == itselfConstant ? updatedLink : newSource, + newTarget == itselfConstant ? updatedLink : newTarget); } + return updatedLink; } - - public: void Delete(IList &restriction) + else { - auto linkIndex = restriction[_constants.IndexPart]; - storage.EnforceResetValues(linkIndex); - this->facade().TFacade::DeleteAllUsages(linkIndex); - storage.Delete(linkIndex); + return this->facade().TFacade::MergeAndDelete(updatedLink, existedLink); } - }; -} + } + +public: + void Delete(IList& restriction) + { + auto linkIndex = restriction[_constants.IndexPart]; + storage.EnforceResetValues(linkIndex); + this->facade().TFacade::DeleteAllUsages(linkIndex); + storage.Delete(linkIndex); + } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Decorators/UniLinks.h b/cpp/Platform.Data.Doublets/Decorators/UniLinks.h index 84a06eb1f..5c1150085 100644 --- a/cpp/Platform.Data.Doublets/Decorators/UniLinks.h +++ b/cpp/Platform.Data.Doublets/Decorators/UniLinks.h @@ -1,41 +1,112 @@ namespace Platform::Data::Doublets::Decorators { - template class UniLinks; - template class UniLinks : public DecoratorBase, IUniLinks +template +class UniLinks; +template +class UniLinks : public DecoratorBase, IUniLinks +{ +public: + UniLinks(ILinks& storage) : base(storage) {} + + struct Transition { - public: UniLinks(ILinks &storage) : base(storage) { } + public: + IList* Before; - struct Transition - { - public: IList *Before; - public: IList *After; + public: + IList* After; - public: Transition( const LinkType& before, const LinkType& after) - { - Before = before; - After = after; - } + public: + Transition(const LinkType& before, const LinkType& after) + { + Before = before; + After = after; } + } + + public : TLinkAddress + Trigger(const LinkType& restriction, + Func, IList, TLinkAddress> matchedHandler, + const LinkType& substitution, + Func, IList, TLinkAddress> substitutedHandler) + { + return _constants.Continue; + } - public: TLinkAddress Trigger(const LinkType& restriction, Func, IList, TLinkAddress> matchedHandler, const LinkType& substitution, Func, IList, TLinkAddress> substitutedHandler) +public: + TLinkAddress Trigger(const LinkType& patternOrCondition, Func, TLinkAddress> matchHandler, + const LinkType& substitution, + Func, IList, TLinkAddress> substitutionHandler) + { + auto constants = _constants; + if (patternOrCondition.IsNullOrEmpty() && substitution.IsNullOrEmpty()) { - return _constants.Continue; + return constants.Continue; } - - public: TLinkAddress Trigger( const LinkType& patternOrCondition, Func, TLinkAddress> matchHandler, const LinkType& substitution, Func, IList, TLinkAddress> substitutionHandler) + else if (patternOrCondition.EqualTo(substitution)) { - auto constants = _constants; - if (patternOrCondition.IsNullOrEmpty() && substitution.IsNullOrEmpty()) + throw std::logic_error("Not implemented exception."); + } + else if (!substitution.IsNullOrEmpty()) + { + auto before = Array.Empty(); + if (matchHandler != nullptr && this->matchHandler(before) == constants.Break) { + return constants.Break; + } + auto after = (IList)substitution.ToArray(); + if (after[0] == 0) + { + auto newLink = this->decorated().TDecorated::Create(); + after[0] = newLink; + } + if (substitution.Count() == 1) + { + after = this->decorated().TDecorated::GetLink(substitution[0]); + } + else if (substitution.Count() == 3) + { + } + else + { + throw std::logic_error("Not supported exception."); + } + if (matchHandler != nullptr) + { + return this->substitutionHandler(before, after); + } + return constants.Continue; + } + else if (!patternOrCondition.IsNullOrEmpty()) + { + if (patternOrCondition.Count() == 1) + { + auto linkToDelete = patternOrCondition[0]; + auto before = this->decorated().TDecorated::GetLink(linkToDelete); + if (matchHandler != nullptr && this->matchHandler(before) == constants.Break) + { + return constants.Break; + } + auto after = Array.Empty(); + this->decorated().TDecorated::Update(linkToDelete, constants.Null, constants.Null); + this->decorated().TDecorated::Delete(linkToDelete); + if (matchHandler != nullptr) + { + return this->substitutionHandler(before, after); + } return constants.Continue; } - else if (patternOrCondition.EqualTo(substitution)) + else { - throw std::logic_error("Not implemented exception."); + throw std::logic_error("Not supported exception."); } - else if (!substitution.IsNullOrEmpty()) + } + else + { + if (patternOrCondition.Count() == 1) { - auto before = Array.Empty(); + auto linkToUpdate = patternOrCondition[0]; + auto before = this->decorated().TDecorated::GetLink(linkToUpdate); if (matchHandler != nullptr && this->matchHandler(before) == constants.Break) { return constants.Break; @@ -43,12 +114,16 @@ auto after = (IList)substitution.ToArray(); if (after[0] == 0) { - auto newLink = this->decorated().TDecorated::Create(); - after[0] = newLink; + after[0] = linkToUpdate; } if (substitution.Count() == 1) { - after = this->decorated().TDecorated::GetLink(substitution[0]); + if (!substitution[0] == linkToUpdate) + { + after = this->decorated().TDecorated::GetLink(substitution[0]); + this->decorated().TDecorated::Update(linkToUpdate, constants.Null, constants.Null); + this->decorated().TDecorated::Delete(linkToUpdate); + } } else if (substitution.Count() == 3) { @@ -63,87 +138,28 @@ } return constants.Continue; } - else if (!patternOrCondition.IsNullOrEmpty()) - { - if (patternOrCondition.Count() == 1) - { - auto linkToDelete = patternOrCondition[0]; - auto before = this->decorated().TDecorated::GetLink(linkToDelete); - if (matchHandler != nullptr && this->matchHandler(before) == constants.Break) - { - return constants.Break; - } - auto after = Array.Empty(); - this->decorated().TDecorated::Update(linkToDelete, constants.Null, constants.Null); - this->decorated().TDecorated::Delete(linkToDelete); - if (matchHandler != nullptr) - { - return this->substitutionHandler(before, after); - } - return constants.Continue; - } - else - { - throw std::logic_error("Not supported exception."); - } - } else { - if (patternOrCondition.Count() == 1) - { - auto linkToUpdate = patternOrCondition[0]; - auto before = this->decorated().TDecorated::GetLink(linkToUpdate); - if (matchHandler != nullptr && this->matchHandler(before) == constants.Break) - { - return constants.Break; - } - auto after = (IList)substitution.ToArray(); - if (after[0] == 0) - { - after[0] = linkToUpdate; - } - if (substitution.Count() == 1) - { - if (!substitution[0] == linkToUpdate) - { - after = this->decorated().TDecorated::GetLink(substitution[0]); - this->decorated().TDecorated::Update(linkToUpdate, constants.Null, constants.Null); - this->decorated().TDecorated::Delete(linkToUpdate); - } - } - else if (substitution.Count() == 3) - { - } - else - { - throw std::logic_error("Not supported exception."); - } - if (matchHandler != nullptr) - { - return this->substitutionHandler(before, after); - } - return constants.Continue; - } - else - { - throw std::logic_error("Not supported exception."); - } + throw std::logic_error("Not supported exception."); } } + } - public: IList>> Trigger( const LinkType& condition, const LinkType& substitution) - { - auto changes = List>>(); - auto continue = _constants.Continue; - Trigger(condition, AlwaysContinue, substitution, (before, after) => - { - auto change = new[] { before, after }; +public: + IList>> Trigger(const LinkType& condition, const LinkType& substitution) + { + auto changes = List>>(); + auto continue = _constants.Continue; + Trigger( + condition, AlwaysContinue, substitution, (before, after) = > { + auto change = new[]{before, after}; changes.Add(change); return continue; }); - return changes; - } + return changes; + } - private: TLinkAddress AlwaysContinue( const LinkType& linkToMatch) { return _constants.Continue; } - }; -} +private: + TLinkAddress AlwaysContinue(const LinkType& linkToMatch) { return _constants.Continue; } +}; +} // namespace Platform::Data::Doublets::Decorators diff --git a/cpp/Platform.Data.Doublets/Doublet.h b/cpp/Platform.Data.Doublets/Doublet.h index a7117769f..218d0fe64 100644 --- a/cpp/Platform.Data.Doublets/Doublet.h +++ b/cpp/Platform.Data.Doublets/Doublet.h @@ -1,28 +1,42 @@ namespace Platform::Data::Doublets { - // todo! use link concept - template - struct Doublet - { - public: T Source = 0; +// todo! use link concept +template +struct Doublet +{ +public: + T Source = 0; - public: T Target = 0; +public: + T Target = 0; - public: Doublet(T source = 0, T target = 0) - : Source(source), Target(target) {} +public: + Doublet(T source = 0, T target = 0) : Source(source), Target(target) {} - public: explicit operator std::string() const { return std::string("").append(Platform::Converters::To(Source)).append("->").append(Platform::Converters::To(Target)); } +public: + explicit operator std::string() const + { + return std::string("") + .append(Platform::Converters::To(Source)) + .append("->") + .append(Platform::Converters::To(Target)); + } - public: friend std::ostream& operator<<(std::ostream& stream, const Doublet& self) { return stream << static_cast(self); } +public: + friend std::ostream& operator<<(std::ostream& stream, const Doublet& self) + { + return stream << static_cast(self); + } - public: bool operator==(const Doublet &other) const = default; - }; +public: + bool operator==(const Doublet& other) const = default; +}; - template - Doublet(Args...) -> Doublet>; -} +template +Doublet(Args...) -> Doublet>; +} // namespace Platform::Data::Doublets -template +template struct std::hash> { std::size_t operator()(const Platform::Data::Doublets::Doublet& self) const diff --git a/cpp/Platform.Data.Doublets/DoubletComparer.h b/cpp/Platform.Data.Doublets/DoubletComparer.h index d03f201ae..c20c23b3a 100644 --- a/cpp/Platform.Data.Doublets/DoubletComparer.h +++ b/cpp/Platform.Data.Doublets/DoubletComparer.h @@ -1,14 +1,19 @@ namespace Platform::Data::Doublets { - template class DoubletComparer; - template class DoubletComparer : public IEqualityComparer> - { - public: inline static DoubletComparer Default; +template +class DoubletComparer; +template +class DoubletComparer : public IEqualityComparer> +{ +public: + inline static DoubletComparer Default; - public: bool operator ==(const Doublet x, Doublet &y) const { return x.Equals(y); } +public: + bool operator==(const Doublet x, Doublet& y) const { return x.Equals(y); } - public: std::int32_t GetHashCode(Doublet obj) { return obj.GetHashCode(); } - }; -} +public: + std::int32_t GetHashCode(Doublet obj) { return obj.GetHashCode(); } +}; +} // namespace Platform::Data::Doublets constexpr auto x = "LOOOOL228"; diff --git a/cpp/Platform.Data.Doublets/Ffi/Links.h b/cpp/Platform.Data.Doublets/Ffi/Links.h index 2a967c147..bcf3ba9f7 100644 --- a/cpp/Platform.Data.Doublets/Ffi/Links.h +++ b/cpp/Platform.Data.Doublets/Ffi/Links.h @@ -1,10 +1,10 @@ namespace Platform::Data::Doublets::Ffi { - template - class Links : public LinksBase, TLinkOptions, TBase...> - { - public: - using base = LinksBase, TLinkOptions, TBase...>; - using base::base; - }; -} +template +class Links : public LinksBase, TLinkOptions, TBase...> +{ +public: + using base = LinksBase, TLinkOptions, TBase...>; + using base::base; +}; +} // namespace Platform::Data::Doublets::Ffi diff --git a/cpp/Platform.Data.Doublets/Ffi/LinksBase.h b/cpp/Platform.Data.Doublets/Ffi/LinksBase.h index a08ffb8c1..5faac7b65 100644 --- a/cpp/Platform.Data.Doublets/Ffi/LinksBase.h +++ b/cpp/Platform.Data.Doublets/Ffi/LinksBase.h @@ -1,409 +1,381 @@ namespace Platform::Data::Doublets::Ffi { - template - thread_local std::function GLOBAL_FUNCTION = nullptr; +template +thread_local std::function GLOBAL_FUNCTION = nullptr; - template - TReturn call_last_global(TArgs... args) - { - decltype(auto) result = GLOBAL_FUNCTION(args...); - return result; - } - - template - void set_global(std::function function) - { - GLOBAL_FUNCTION = std::move(function); - } +template +TReturn call_last_global(TArgs... args) +{ + decltype(auto) result = GLOBAL_FUNCTION(args...); + return result; +} - template - using CUDCallback = LinkAddressType (*)(Link before, Link after); +template +void set_global(std::function function) +{ + GLOBAL_FUNCTION = std::move(function); +} - template - using EachCallback = LinkAddressType (*)(Link); +template +using CUDCallback = LinkAddressType (*)(Link before, Link after); - template - struct FfiConstants - { - LinkAddressType index_part; - LinkAddressType source_part; - LinkAddressType target_part; - LinkAddressType null; - LinkAddressType $continue; - LinkAddressType $break; - LinkAddressType skip; - LinkAddressType any; - LinkAddressType itself; - LinkAddressType error; - Ranges::Range internal_range; - Ranges::Range external_range; - bool _opt_marker; - }; +template +using EachCallback = LinkAddressType (*)(Link); - extern "C" - { - void* ByteLinks_New(const char* path); +template +struct FfiConstants +{ + LinkAddressType index_part; + LinkAddressType source_part; + LinkAddressType target_part; + LinkAddressType null; + LinkAddressType $continue; + LinkAddressType $break; + LinkAddressType skip; + LinkAddressType any; + LinkAddressType itself; + LinkAddressType error; + Ranges::Range internal_range; + Ranges::Range external_range; + bool _opt_marker; +}; + +extern "C" +{ + void* ByteLinks_New(const char* path); - void* UInt16Links_New(const char* path); + void* UInt16Links_New(const char* path); - void* UInt32Links_New(const char* path); + void* UInt32Links_New(const char* path); - void* UInt64Links_New(const char* path); + void* UInt64Links_New(const char* path); - void ByteLinks_Drop(void* this_); + void ByteLinks_Drop(void* this_); - void UInt16Links_Drop(void* this_); + void UInt16Links_Drop(void* this_); - void UInt32Links_Drop(void* this_); + void UInt32Links_Drop(void* this_); - void UInt64Links_Drop(void* this_); + void UInt64Links_Drop(void* this_); - FfiConstants ByteLinks_GetConstants(void* this_); + FfiConstants ByteLinks_GetConstants(void* this_); - FfiConstants UInt16Links_GetConstants(void* this_); + FfiConstants UInt16Links_GetConstants(void* this_); - FfiConstants UInt32Links_GetConstants(void* this_); + FfiConstants UInt32Links_GetConstants(void* this_); - FfiConstants UInt64Links_GetConstants(void* this_); + FfiConstants UInt64Links_GetConstants(void* this_); - uint8_t ByteLinks_Create(void* this_, - const uint8_t* query, - uintptr_t len, - CUDCallback callback); + uint8_t ByteLinks_Create(void* this_, const uint8_t* query, uintptr_t len, CUDCallback callback); - uint16_t UInt16Links_Create(void* this_, - const uint16_t* query, - uintptr_t len, - CUDCallback callback); + uint16_t UInt16Links_Create(void* this_, const uint16_t* query, uintptr_t len, CUDCallback callback); - uint32_t UInt32Links_Create(void* this_, - const uint32_t* query, - uintptr_t len, - CUDCallback callback); + uint32_t UInt32Links_Create(void* this_, const uint32_t* query, uintptr_t len, CUDCallback callback); - uint64_t UInt64Links_Create(void* this_, - const uint64_t* query, - uintptr_t len, - CUDCallback callback); + uint64_t UInt64Links_Create(void* this_, const uint64_t* query, uintptr_t len, CUDCallback callback); - uint8_t ByteLinks_Each(void* this_, - const uint8_t* query, - uintptr_t len, - EachCallback callback); + uint8_t ByteLinks_Each(void* this_, const uint8_t* query, uintptr_t len, EachCallback callback); - uint16_t UInt16Links_Each(void* this_, - const uint16_t* query, - uintptr_t len, - EachCallback callback); + uint16_t UInt16Links_Each(void* this_, const uint16_t* query, uintptr_t len, EachCallback callback); - uint32_t UInt32Links_Each(void* this_, - const uint32_t* query, - uintptr_t len, - EachCallback callback); + uint32_t UInt32Links_Each(void* this_, const uint32_t* query, uintptr_t len, EachCallback callback); - uint64_t UInt64Links_Each(void* this_, - const uint64_t* query, - uintptr_t len, - EachCallback callback); + uint64_t UInt64Links_Each(void* this_, const uint64_t* query, uintptr_t len, EachCallback callback); - uint8_t ByteLinks_Count(void* this_, const uint8_t* query, uintptr_t len); + uint8_t ByteLinks_Count(void* this_, const uint8_t* query, uintptr_t len); - uint16_t UInt16Links_Count(void* this_, const uint16_t* query, uintptr_t len); + uint16_t UInt16Links_Count(void* this_, const uint16_t* query, uintptr_t len); - uint32_t UInt32Links_Count(void* this_, const uint32_t* query, uintptr_t len); + uint32_t UInt32Links_Count(void* this_, const uint32_t* query, uintptr_t len); - uint64_t UInt64Links_Count(void* this_, const uint64_t* query, uintptr_t len); + uint64_t UInt64Links_Count(void* this_, const uint64_t* query, uintptr_t len); - uint8_t ByteLinks_Update(void* this_, - const uint8_t* restriction, - uintptr_t len_r, - const uint8_t* substitution, - uintptr_t len_s, - CUDCallback callback); + uint8_t ByteLinks_Update(void* this_, const uint8_t* restriction, uintptr_t len_r, const uint8_t* substitution, + uintptr_t len_s, CUDCallback callback); - uint16_t UInt16Links_Update(void* this_, - const uint16_t* restriction, - uintptr_t len_r, - const uint16_t* substitution, - uintptr_t len_s, - CUDCallback callback); + uint16_t UInt16Links_Update(void* this_, const uint16_t* restriction, uintptr_t len_r, const uint16_t* substitution, + uintptr_t len_s, CUDCallback callback); - uint32_t UInt32Links_Update(void* this_, - const uint32_t* restriction, - uintptr_t len_r, - const uint32_t* substitution, - uintptr_t len_s, - CUDCallback callback); + uint32_t UInt32Links_Update(void* this_, const uint32_t* restriction, uintptr_t len_r, const uint32_t* substitution, + uintptr_t len_s, CUDCallback callback); - uint64_t UInt64Links_Update(void* this_, - const uint64_t* restriction, - uintptr_t len_r, - const uint64_t* substitution, - uintptr_t len_s, - CUDCallback callback); + uint64_t UInt64Links_Update(void* this_, const uint64_t* restriction, uintptr_t len_r, const uint64_t* substitution, + uintptr_t len_s, CUDCallback callback); - uint8_t ByteLinks_Delete(void* this_, - const uint8_t* query, - uintptr_t len, - CUDCallback callback); + uint8_t ByteLinks_Delete(void* this_, const uint8_t* query, uintptr_t len, CUDCallback callback); - uint16_t UInt16Links_Delete(void* this_, - const uint16_t* query, - uintptr_t len, - CUDCallback callback); + uint16_t UInt16Links_Delete(void* this_, const uint16_t* query, uintptr_t len, CUDCallback callback); - uint32_t UInt32Links_Delete(void* this_, - const uint32_t* query, - uintptr_t len, - CUDCallback callback); - - uint64_t UInt64Links_Delete(void* this_, - const uint64_t* query, - uintptr_t len, - CUDCallback callback); - - void init_fmt_logger(); - } + uint32_t UInt32Links_Delete(void* this_, const uint32_t* query, uintptr_t len, CUDCallback callback); - template - struct stopper - { - static constexpr bool value = false; - }; + uint64_t UInt64Links_Delete(void* this_, const uint64_t* query, uintptr_t len, CUDCallback callback); - template - class LinksBase : public Interfaces::Polymorph - { - private: - void* _ptr; + void init_fmt_logger(); +} - public: - using LinksOptionsType = TLinkOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - static constexpr LinksConstants Constants = LinksOptionsType::Constants; +template +struct stopper +{ + static constexpr bool value = false; +}; - LinksBase(std::string_view path) +template +class LinksBase : public Interfaces::Polymorph +{ +private: + void* _ptr; + +public: + using LinksOptionsType = TLinkOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + static constexpr LinksConstants Constants = LinksOptionsType::Constants; + + LinksBase(std::string_view path) + { + if constexpr (std::same_as) { - if constexpr (std::same_as) - { - _ptr = ByteLinks_New(path.data()); - } - else if constexpr (std::same_as) - { - _ptr = UInt16Links_New(path.data()); - } - else if constexpr (std::same_as) - { - _ptr = UInt32Links_New(path.data()); - } - else if constexpr (std::same_as) - { - _ptr = UInt64Links_New(path.data()); - } - else - { - static_assert(stopper::value, "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); - } + _ptr = ByteLinks_New(path.data()); + } + else if constexpr (std::same_as) + { + _ptr = UInt16Links_New(path.data()); + } + else if constexpr (std::same_as) + { + _ptr = UInt32Links_New(path.data()); + } + else if constexpr (std::same_as) + { + _ptr = UInt64Links_New(path.data()); } + else + { + static_assert(stopper::value, + "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); + } + } - ~LinksBase() + ~LinksBase() + { + if constexpr (std::same_as) { - if constexpr (std::same_as) + if (_ptr != nullptr) { - if (_ptr != nullptr) - { - ByteLinks_Drop(_ptr); - } + ByteLinks_Drop(_ptr); } - else if constexpr (std::same_as) - { - if (_ptr != nullptr) - { - UInt16Links_Drop(_ptr); - } - } - else if constexpr (std::same_as) + } + else if constexpr (std::same_as) + { + if (_ptr != nullptr) { - if (_ptr != nullptr) - { - UInt32Links_Drop(_ptr); - } + UInt16Links_Drop(_ptr); } - else if constexpr (std::same_as) + } + else if constexpr (std::same_as) + { + if (_ptr != nullptr) { - if (_ptr != nullptr) - { - UInt64Links_Drop(_ptr); - } + UInt32Links_Drop(_ptr); } - else + } + else if constexpr (std::same_as) + { + if (_ptr != nullptr) { - static_assert(stopper::value, "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); + UInt64Links_Drop(_ptr); } } + else + { + static_assert(stopper::value, + "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); + } + } - LinkAddressType Create(const LinkType& substitution, const WriteHandlerType& handler) + LinkAddressType Create(const LinkType& substitution, const WriteHandlerType& handler) + { + auto substitutionLength = std::ranges::size(substitution); + auto substitutionPtr = std::ranges::data(substitution); + auto callback = [&](Link before, Link after) -> LinkAddressType { - auto substitutionLength = std::ranges::size(substitution); - auto substitutionPtr = std::ranges::data(substitution); - auto callback = [&](Link before, Link after) -> LinkAddressType { - Link beforeLink{before.Index, before.Source, before.Target}; - Link afterLink{after.Index, after.Source, after.Target}; - return handler(beforeLink, afterLink); - }; - using Signature = LinkAddressType(Link, Link); - set_global(callback); - if constexpr (std::same_as) - { - return ByteLinks_Create(_ptr, substitutionPtr, substitutionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt16Links_Create(_ptr, substitutionPtr, substitutionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt32Links_Create(_ptr, substitutionPtr, substitutionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt64Links_Create(_ptr, substitutionPtr, substitutionLength, call_last_global>); - } - else - { - static_assert(stopper::value, "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); - } + Link beforeLink{before.Index, before.Source, before.Target}; + Link afterLink{after.Index, after.Source, after.Target}; + return handler(beforeLink, afterLink); }; + using Signature = LinkAddressType(Link, Link); + set_global(callback); + if constexpr (std::same_as) + { + return ByteLinks_Create(_ptr, substitutionPtr, substitutionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt16Links_Create(_ptr, substitutionPtr, substitutionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt32Links_Create(_ptr, substitutionPtr, substitutionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt64Links_Create(_ptr, substitutionPtr, substitutionLength, + call_last_global>); + } + else + { + static_assert(stopper::value, + "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); + } + }; - LinkAddressType Update(const LinkType& restriction, const LinkType& substitution, const WriteHandlerType& handler) - { - auto restrictionLength = std::ranges::size(restriction); - auto restrictionPtr{std::ranges::data(restriction)}; - auto substitutionLength = std::ranges::size(substitution); - auto substitutionPtr{std::ranges::data(substitution)}; - auto callback = [&](Link before, Link after) { - Link beforeLink{before.Index, before.Source, before.Target}; - Link afterLink{after.Index, after.Source, after.Target}; - return handler(beforeLink, afterLink); - }; - using Signature = LinkAddressType(Link, Link); - set_global(callback); - if constexpr (std::same_as) - { - return ByteLinks_Update(_ptr, restrictionPtr, restrictionLength, substitutionPtr, substitutionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt16Links_Update(_ptr, restrictionPtr, restrictionLength, substitutionPtr, substitutionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt32Links_Update(_ptr, restrictionPtr, restrictionLength, substitutionPtr, substitutionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt64Links_Update(_ptr, restrictionPtr, restrictionLength, substitutionPtr, substitutionLength, call_last_global>); - } - else - { - static_assert(stopper::value, "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); - } + LinkAddressType Update(const LinkType& restriction, const LinkType& substitution, const WriteHandlerType& handler) + { + auto restrictionLength = std::ranges::size(restriction); + auto restrictionPtr{std::ranges::data(restriction)}; + auto substitutionLength = std::ranges::size(substitution); + auto substitutionPtr{std::ranges::data(substitution)}; + auto callback = [&](Link before, Link after) + { + Link beforeLink{before.Index, before.Source, before.Target}; + Link afterLink{after.Index, after.Source, after.Target}; + return handler(beforeLink, afterLink); + }; + using Signature = LinkAddressType(Link, Link); + set_global(callback); + if constexpr (std::same_as) + { + return ByteLinks_Update(_ptr, restrictionPtr, restrictionLength, substitutionPtr, substitutionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt16Links_Update(_ptr, restrictionPtr, restrictionLength, substitutionPtr, substitutionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt32Links_Update(_ptr, restrictionPtr, restrictionLength, substitutionPtr, substitutionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt64Links_Update(_ptr, restrictionPtr, restrictionLength, substitutionPtr, substitutionLength, + call_last_global>); + } + else + { + static_assert(stopper::value, + "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); } + } - LinkAddressType Delete(const LinkType& restriction, const WriteHandlerType& handler) + LinkAddressType Delete(const LinkType& restriction, const WriteHandlerType& handler) + { + auto restrictionLength = std::ranges::size(restriction); + auto restrictionPtr = std::ranges::data(restriction); + auto callback = [&](Link before, Link after) { - auto restrictionLength = std::ranges::size(restriction); - auto restrictionPtr = std::ranges::data(restriction); - auto callback = [&](Link before, Link after) { - Link beforeLink{before.Index, before.Source, before.Target}; - Link afterLink{after.Index, after.Source, after.Target}; - return handler(beforeLink, afterLink); - }; - using Signature = LinkAddressType(Link, Link); - set_global(callback); - if constexpr (std::same_as) - { - return ByteLinks_Delete(_ptr, restrictionPtr, restrictionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt16Links_Delete(_ptr, restrictionPtr, restrictionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt32Links_Delete(_ptr, restrictionPtr, restrictionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt64Links_Delete(_ptr, restrictionPtr, restrictionLength, call_last_global>); - } - else - { - static_assert(stopper::value, "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); - } + Link beforeLink{before.Index, before.Source, before.Target}; + Link afterLink{after.Index, after.Source, after.Target}; + return handler(beforeLink, afterLink); + }; + using Signature = LinkAddressType(Link, Link); + set_global(callback); + if constexpr (std::same_as) + { + return ByteLinks_Delete(_ptr, restrictionPtr, restrictionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt16Links_Delete(_ptr, restrictionPtr, restrictionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt32Links_Delete(_ptr, restrictionPtr, restrictionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt64Links_Delete(_ptr, restrictionPtr, restrictionLength, + call_last_global>); } + else + { + static_assert(stopper::value, + "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); + } + } - LinkAddressType Each(const LinkType& restriction, const ReadHandlerType& handler) const + LinkAddressType Each(const LinkType& restriction, const ReadHandlerType& handler) const + { + using Signature = LinkAddressType(Link); + auto restrictionLength = std::ranges::size(restriction); + auto restrictionPtr = std::ranges::data(restriction); + auto callback = [&](Link link) { return handler(Link{link.Index, link.Source, link.Target}); }; + set_global(callback); + if constexpr (std::same_as) { - using Signature = LinkAddressType(Link); - auto restrictionLength = std::ranges::size(restriction); - auto restrictionPtr = std::ranges::data(restriction); - auto callback = [&](Link link) { - return handler(Link{link.Index, link.Source, link.Target}); - }; - set_global(callback); - if constexpr (std::same_as) - { - return ByteLinks_Each(_ptr, restrictionPtr, restrictionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt16Links_Each(_ptr, restrictionPtr, restrictionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt32Links_Each(_ptr, restrictionPtr, restrictionLength, call_last_global>); - } - else if constexpr (std::same_as) - { - return UInt64Links_Each(_ptr, restrictionPtr, restrictionLength, call_last_global>); - } - else - { - static_assert(stopper::value, "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); - } + return ByteLinks_Each(_ptr, restrictionPtr, restrictionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt16Links_Each(_ptr, restrictionPtr, restrictionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt32Links_Each(_ptr, restrictionPtr, restrictionLength, + call_last_global>); + } + else if constexpr (std::same_as) + { + return UInt64Links_Each(_ptr, restrictionPtr, restrictionLength, + call_last_global>); } + else + { + static_assert(stopper::value, + "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); + } + } - LinkAddressType Count(const LinkType& restriction) const + LinkAddressType Count(const LinkType& restriction) const + { + auto restrictionLength = std::ranges::size(restriction); + auto restrictionPtr = std::ranges::data(restriction); + if constexpr (std::same_as) { - auto restrictionLength = std::ranges::size(restriction); - auto restrictionPtr = std::ranges::data(restriction); - if constexpr (std::same_as) - { - return ByteLinks_Count(_ptr, restrictionPtr, restrictionLength); - } - else if constexpr (std::same_as) - { - return UInt16Links_Count(_ptr, restrictionPtr, restrictionLength); - } - else if constexpr (std::same_as) - { - return UInt32Links_Count(_ptr, restrictionPtr, restrictionLength); - } - else if constexpr (std::same_as) - { - return UInt64Links_Count(_ptr, restrictionPtr, restrictionLength); - } - else - { - static_assert(stopper::value, "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); - } + return ByteLinks_Count(_ptr, restrictionPtr, restrictionLength); } + else if constexpr (std::same_as) + { + return UInt16Links_Count(_ptr, restrictionPtr, restrictionLength); + } + else if constexpr (std::same_as) + { + return UInt32Links_Count(_ptr, restrictionPtr, restrictionLength); + } + else if constexpr (std::same_as) + { + return UInt64Links_Count(_ptr, restrictionPtr, restrictionLength); + } + else + { + static_assert(stopper::value, + "LinkAddressType must be one of std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t"); + } + } - // Extensions - }; -}// namespace Platform::Data::Doublets::Memory::United::Ffi + // Extensions +}; +} // namespace Platform::Data::Doublets::Ffi diff --git a/cpp/Platform.Data.Doublets/ILinksExtensions.h b/cpp/Platform.Data.Doublets/ILinksExtensions.h index 902eb08c9..c9bcf2e8f 100644 --- a/cpp/Platform.Data.Doublets/ILinksExtensions.h +++ b/cpp/Platform.Data.Doublets/ILinksExtensions.h @@ -1,672 +1,785 @@ namespace Platform::Data::Doublets { - template - static void RunRandomCreations(TStorage& storage, typename TStorage::LinkAddressType amountOfCreations) - { - using namespace Platform::Data; - using namespace Platform::Random; - using namespace Platform::Ranges; - auto& randomGenerator64 = Random::RandomHelpers::Default; - for (typename TStorage::LinkAddressType i { 0 }; i < amountOfCreations; ++i) - { - Range linksAddressRange { 0, Count(storage) }; - auto source = Random::NextUInt64(randomGenerator64, linksAddressRange); - auto target = Random::NextUInt64(randomGenerator64, linksAddressRange); - GetOrCreate(storage, source, target); - } +template +static void RunRandomCreations(TStorage& storage, typename TStorage::LinkAddressType amountOfCreations) +{ + using namespace Platform::Data; + using namespace Platform::Random; + using namespace Platform::Ranges; + auto& randomGenerator64 = Random::RandomHelpers::Default; + for (typename TStorage::LinkAddressType i{0}; i < amountOfCreations; ++i) + { + Range linksAddressRange{0, Count(storage)}; + auto source = Random::NextUInt64(randomGenerator64, linksAddressRange); + auto target = Random::NextUInt64(randomGenerator64, linksAddressRange); + GetOrCreate(storage, source, target); } +} - template - static void RunRandomSearches(const TStorage& storage, typename TStorage::LinkAddressType amountOfSearches) +template +static void RunRandomSearches(const TStorage& storage, typename TStorage::LinkAddressType amountOfSearches) +{ + using namespace Platform::Data; + using namespace Platform::Random; + using namespace Platform::Ranges; + auto randomGenerator64 = Random::RandomHelpers::Default; + for (typename TStorage::LinkAddressType i{0}; i < amountOfSearches; ++i) { - using namespace Platform::Data; - using namespace Platform::Random; - using namespace Platform::Ranges; - auto randomGenerator64 = Random::RandomHelpers::Default; - for (typename TStorage::LinkAddressType i { 0 }; i < amountOfSearches; ++i) - { - auto linksAddressRange = Range(0, Count(storage)); - auto source = Random::NextUInt64(randomGenerator64, linksAddressRange); - auto target = Random::NextUInt64(randomGenerator64, linksAddressRange); - SearchOrDefault(storage, source, target); - } + auto linksAddressRange = Range(0, Count(storage)); + auto source = Random::NextUInt64(randomGenerator64, linksAddressRange); + auto target = Random::NextUInt64(randomGenerator64, linksAddressRange); + SearchOrDefault(storage, source, target); } +} - template - static void RunRandomDeletions(TStorage& storage, typename TStorage::LinkAddressType amountOfDeletions) +template +static void RunRandomDeletions(TStorage& storage, typename TStorage::LinkAddressType amountOfDeletions) +{ + using namespace Platform::Data; + using namespace Platform::Random; + using namespace Platform::Ranges; + auto& randomGenerator64 = RandomHelpers::Default; + auto linksCount = Count(storage); + typename TStorage::LinkAddressType min = amountOfDeletions > linksCount ? 0 : linksCount - amountOfDeletions; + for (typename TStorage::LinkAddressType i{0}; i < amountOfDeletions; ++i) { - using namespace Platform::Data; - using namespace Platform::Random; - using namespace Platform::Ranges; - auto& randomGenerator64 = RandomHelpers::Default; - auto linksCount = Count(storage); - typename TStorage::LinkAddressType min = amountOfDeletions > linksCount ? 0 : linksCount - amountOfDeletions; - for (typename TStorage::LinkAddressType i { 0 }; i < amountOfDeletions; ++i) + linksCount = Count(storage); + if (linksCount <= min) { - linksCount = Count(storage); - if (linksCount <= min) - { - break; - } - auto linksAddressRange = Range(min, linksCount); - auto linkAddress = Random::NextUInt64(randomGenerator64, linksAddressRange); - Delete(storage, linkAddress); + break; } + auto linksAddressRange = Range(min, linksCount); + auto linkAddress = Random::NextUInt64(randomGenerator64, linksAddressRange); + Delete(storage, linkAddress); } +} - template - void TestRandomCreationsAndDeletions(TStorage& storage, typename TStorage::LinkAddressType maximumOperationsPerCycle) +template +void TestRandomCreationsAndDeletions(TStorage& storage, typename TStorage::LinkAddressType maximumOperationsPerCycle) +{ + using namespace Platform::Random; + using namespace Platform::Ranges; + using namespace Platform::Interfaces; + for (auto N = 1; N < maximumOperationsPerCycle; N++) { - using namespace Platform::Random; - using namespace Platform::Ranges; - using namespace Platform::Interfaces; - for (auto N = 1; N < maximumOperationsPerCycle; N++) - { - auto& randomGen64 = RandomHelpers::Default; - typename TStorage::LinkAddressType created = 0; - typename TStorage::LinkAddressType deleted = 0; - for (auto i = 0; i < N; i++) + auto& randomGen64 = RandomHelpers::Default; + typename TStorage::LinkAddressType created = 0; + typename TStorage::LinkAddressType deleted = 0; + for (auto i = 0; i < N; i++) + { + auto linksCount = Count(storage); + auto createPoint = Random::NextBoolean(randomGen64); + if (linksCount >= 2 && createPoint) { - auto linksCount = Count(storage); - auto createPoint = Random::NextBoolean(randomGen64); - if (linksCount >= 2 && createPoint) + Ranges::Range linksAddressRange{1, linksCount}; + auto source = Random::NextUInt64(randomGen64, linksAddressRange); + auto target = Random::NextUInt64(randomGen64, linksAddressRange); //-V3086 + auto resultLink = GetOrCreate(storage, source, target); + if (resultLink > linksCount) { - Ranges::Range linksAddressRange {1, linksCount}; - auto source = Random::NextUInt64(randomGen64, linksAddressRange); - auto target = Random::NextUInt64(randomGen64, linksAddressRange); //-V3086 - auto resultLink = GetOrCreate(storage, source, target); - if (resultLink > linksCount) - { - ++created; - } - } - else - { - Create(storage); ++created; } } - auto count = Count(storage); - for (auto i = 0; i < count; i++) + else { - auto link = i + 1; - { - DIRECT_METHOD_CALL(TStorage, storage, Update,link, 0, 0); - Delete(storage, link); - ++deleted; - } + Create(storage); + ++created; } } - } - - template - static typename TStorage::LinkAddressType Delete(TStorage& storage, typename TStorage::LinkAddressType linkToDelete, const typename TStorage::WriteHandlerType& handler) - { - if (Exists(storage, linkToDelete)) + auto count = Count(storage); + for (auto i = 0; i < count; i++) { - EnforceResetValues(storage, linkToDelete, handler); + auto link = i + 1; + { + DIRECT_METHOD_CALL(TStorage, storage, Update, link, 0, 0); + Delete(storage, link); + ++deleted; + } } - return Delete(storage, linkToDelete, handler); } +} - template - static typename TStorage::LinkAddressType First(const TStorage& storage) +template +static typename TStorage::LinkAddressType Delete(TStorage& storage, typename TStorage::LinkAddressType linkToDelete, + const typename TStorage::WriteHandlerType& handler) +{ + if (Exists(storage, linkToDelete)) { - constexpr auto constants = storage.Constants; - auto $break {constants.Break}; - typename TStorage::LinkAddressType firstLink = 0; - Expects(constants.Null != firstLink); - DIRECT_METHOD_CALL(TStorage, storage, Each,typename TStorage::LinkType{storage.Constants.Any, storage.Constants.Any, storage.Constants.Any}, [&firstLink, $break](const typename TStorage::LinkType& link){ - firstLink = link[0]; - return $break; - }); - Ensures(constants.Null != firstLink); - return firstLink; + EnforceResetValues(storage, linkToDelete, handler); } + return Delete(storage, linkToDelete, handler); +} + +template +static typename TStorage::LinkAddressType First(const TStorage& storage) +{ + constexpr auto constants = storage.Constants; + auto $break{constants.Break}; + typename TStorage::LinkAddressType firstLink = 0; + Expects(constants.Null != firstLink); + DIRECT_METHOD_CALL(TStorage, storage, Each, + typename TStorage::LinkType{storage.Constants.Any, storage.Constants.Any, storage.Constants.Any}, + [&firstLink, $break](const typename TStorage::LinkType& link) + { + firstLink = link[0]; + return $break; + }); + Ensures(constants.Null != firstLink); + return firstLink; +} + +template +static typename TStorage::HandlerParameterType SingleOrDefault(const TStorage& storage, + const typename TStorage::LinkType& query) +{ + typename TStorage::LinkType result{}; + auto count = 0; + constexpr auto constants = storage.Constants; + auto linkHandler{[&result, &count, &constants](const typename TStorage::LinkType& link) + { + if (count == 0) + { + result = link; + ++count; + return constants.Continue; + } + else + { + result = {}; + return constants.Break; + } + }}; + DIRECT_METHOD_CALL(TStorage, storage, Each, query, linkHandler); + return result; +} - template - static typename TStorage::HandlerParameterType SingleOrDefault(const TStorage& storage, const typename TStorage::LinkType& query) +template +static bool CheckPathExistence(const TStorage& storage, + std::convertible_to auto... pathPack) +{ + typename TStorage::HandlerParameterType path{static_cast(pathPack)...}; + auto current = path[0]; + if (!Exists(storage, current)) { - typename TStorage::LinkType result {}; - auto count = 0; - constexpr auto constants = storage.Constants; - auto linkHandler { [&result, &count, &constants] (const typename TStorage::LinkType& link) { - if (count == 0) - { - result = link; - ++count; - return constants.Continue; - } - else - { - result = {}; - return constants.Break; - } - }}; - DIRECT_METHOD_CALL(TStorage, storage, Each,query, linkHandler); - return result; + return false; } - - template - static bool CheckPathExistence(const TStorage& storage, std::convertible_to auto ... pathPack) + constexpr auto constants = storage.Constants; + for (typename TStorage::LinkAddressType i{1}; i < std::ranges::size(path); ++i) { - typename TStorage::HandlerParameterType path{ static_cast(pathPack)... }; - auto current = path[0]; - if (!Exists(storage, current)) + auto next = path[i]; + auto values = GetLink(storage, current); + auto source = GetSource(storage, values); + auto target = GetTarget(storage, values); + if (target == source && next == source) { return false; } - constexpr auto constants = storage.Constants; - for (typename TStorage::LinkAddressType i { 1 }; i < std::ranges::size(path); ++i) + if ((source != next) && (target != next)) { - auto next = path[i]; - auto values = GetLink(storage, current); - auto source = GetSource(storage, values); - auto target = GetTarget(storage, values); - if (target == source && next == source) - { - return false; - } - if ((source != next) && (target != next)) - { - return false; - } - current = next; + return false; } - return true; + current = next; } + return true; +} - template - static typename TStorage::LinkAddressType GetByKeys(TStorage& storage, typename TStorage::LinkAddressType root, std::convertible_to auto ... pathPack) +template +static typename TStorage::LinkAddressType +GetByKeys(TStorage& storage, typename TStorage::LinkAddressType root, + std::convertible_to auto... pathPack) +{ + typename TStorage::HandlerParameterType path{static_cast(pathPack)...}; + storage.EnsureLinkExists(root, "root"); + auto currentLink = root; + for (typename TStorage::LinkAddressType i{0}; i < std::ranges::size(path); ++i) { - typename TStorage::HandlerParameterType path{ static_cast(pathPack)... }; - storage.EnsureLinkExists(root, "root"); - auto currentLink = root; - for (typename TStorage::LinkAddressType i { 0 }; i < std::ranges::size(path); ++i) - { - currentLink = GetLink(storage, currentLink)[path[i]]; - } - return currentLink; - } - - // template - // static typename TStorage::LinkAddressType GetSquareMatrixSequenceElementByIndex(TStorage& storage, typename TStorage::LinkAddressType root, std::uint64_t size, std::uint64_t index) - // { - // using namespace Platform::Numbers; - // constexpr auto constants = storage.Constants; - // auto source = constants.SourcePart; - // auto target = constants.TargetPart; - // if (!Numbers::Math::IsPowerOfTwo(size)) - // { - // throw std::invalid_argument("size", "Sequences with sizes other than powers of two are not supported."); - // } - // auto path = BitArray(BitConverter.GetBytes(index)); - // auto length = Bit.GetLowestPosition(size); - // storage.EnsureLinkExists(root, "root"); - // auto currentLink = root; - // for (auto i { length - 1 }; i >= 0; i--) - // { - // currentLink = GetLink(storage, currentLink)[path[i] ? target : source]; - // } - // return currentLink; - // } - - template - static auto GetIndex(const TStorage& storage, const typename TStorage::LinkType& link) { return link[storage.Constants.IndexPart]; } - - template - static typename TStorage::LinkAddressType GetSource(const TStorage& storage, typename TStorage::LinkAddressType linkAddress) { return GetLink(storage, linkAddress)[storage.Constants.SourcePart]; } - - template - static typename TStorage::LinkAddressType GetSource(const TStorage& storage, const typename TStorage::LinkType& link) { return link[storage.Constants.SourcePart]; } - - template - static typename TStorage::LinkAddressType GetTarget(const TStorage& storage, typename TStorage::LinkAddressType linkAddress) { return GetLink(storage, linkAddress)[storage.Constants.TargetPart]; } - - template - static typename TStorage::LinkAddressType GetTarget(const TStorage& storage, const typename TStorage::LinkType& link) { return link[storage.Constants.TargetPart]; } - - template - static std::vector All(const TStorage& storage, const typename TStorage::LinkType& restriction) - { - using namespace Platform::Collections; - auto $continue {storage.Constants.Continue}; - std::vector allLinks {}; - DIRECT_METHOD_CALL(TStorage, storage, Each,restriction, [&allLinks, $continue](const typename TStorage::LinkType& link){ - allLinks.push_back(link); - return $continue; - }); - return allLinks; + currentLink = GetLink(storage, currentLink)[path[i]]; } + return currentLink; +} - template - static auto All(const TStorage& storage, std::convertible_to auto ... restrictionPack) - { - typename TStorage::LinkType restriction { static_cast(restrictionPack)... }; - return All(storage, typename TStorage::LinkType{}); - } +// template +// static typename TStorage::LinkAddressType GetSquareMatrixSequenceElementByIndex(TStorage& storage, typename +// TStorage::LinkAddressType root, std::uint64_t size, std::uint64_t index) +// { +// using namespace Platform::Numbers; +// constexpr auto constants = storage.Constants; +// auto source = constants.SourcePart; +// auto target = constants.TargetPart; +// if (!Numbers::Math::IsPowerOfTwo(size)) +// { +// throw std::invalid_argument("size", "Sequences with sizes other than powers of two are not supported."); +// } +// auto path = BitArray(BitConverter.GetBytes(index)); +// auto length = Bit.GetLowestPosition(size); +// storage.EnsureLinkExists(root, "root"); +// auto currentLink = root; +// for (auto i { length - 1 }; i >= 0; i--) +// { +// currentLink = GetLink(storage, currentLink)[path[i] ? target : source]; +// } +// return currentLink; +// } - template - static typename TStorage::LinkAddressType AllIndices(TStorage& storage, const typename TStorage::LinkType& restriction) - { - std::vector allIndices {}; - auto usages = std::vector(); - auto $continue = storage.Constants.Continue; - DIRECT_METHOD_CALL(TStorage, storage, Each,restriction, [&allIndices, $continue](const typename TStorage::LinkType& link){ - allIndices.push_back(link); - return $continue; - }); - return allIndices; - } +template +static auto GetIndex(const TStorage& storage, const typename TStorage::LinkType& link) +{ + return link[storage.Constants.IndexPart]; +} +template +static typename TStorage::LinkAddressType GetSource(const TStorage& storage, + typename TStorage::LinkAddressType linkAddress) +{ + return GetLink(storage, linkAddress)[storage.Constants.SourcePart]; +} - template - static void EnsureLinkExists(TStorage& storage, const typename TStorage::LinkType& restriction) - { - for (auto i { 0 }; i < restriction.Count(); ++i) - { - if (!storage.Exists(restriction[i])) - { - throw ArgumentLinkDoesNotExistsException(restriction[i], std::string("sequence[").append(Platform::Converters::To(i)).append(1, ']')); - } - } - } +template +static typename TStorage::LinkAddressType GetSource(const TStorage& storage, const typename TStorage::LinkType& link) +{ + return link[storage.Constants.SourcePart]; +} - template - static bool Exists(TStorage& storage, typename TStorage::LinkAddressType source, typename TStorage::LinkAddressType target) - { - return DIRECT_METHOD_CALL(TStorage, storage, Count,typename TStorage::LinkType{storage.Constants.Any, source, target}) > 0; - } +template +static typename TStorage::LinkAddressType GetTarget(const TStorage& storage, + typename TStorage::LinkAddressType linkAddress) +{ + return GetLink(storage, linkAddress)[storage.Constants.TargetPart]; +} +template +static typename TStorage::LinkAddressType GetTarget(const TStorage& storage, const typename TStorage::LinkType& link) +{ + return link[storage.Constants.TargetPart]; +} - template - static void EnsureInnerReferenceExists(TStorage& storage, typename TStorage::LinkAddressType reference, std::string argumentName) - { - using namespace Platform::Exceptions; - if (storage.Constants.IsInternalReference(reference) && !storage.Exists(reference)) - { - throw ArgumentLinkDoesNotExistsException(reference, argumentName); - } - } +template +static std::vector All(const TStorage& storage, + const typename TStorage::LinkType& restriction) +{ + using namespace Platform::Collections; + auto $continue{storage.Constants.Continue}; + std::vector allLinks{}; + DIRECT_METHOD_CALL(TStorage, storage, Each, restriction, + [&allLinks, $continue](const typename TStorage::LinkType& link) + { + allLinks.push_back(link); + return $continue; + }); + return allLinks; +} - template - static void EnsureInnerReferenceExists(TStorage& storage, const typename TStorage::LinkType& restriction, std::string argumentName) - { - using namespace Platform::Exceptions; - for (std::int32_t i = 0; i < restriction.Count(); ++i) - { - storage.EnsureInnerReferenceExists(restriction[i], argumentName); - } - } +template +static auto All(const TStorage& storage, + std::convertible_to auto... restrictionPack) +{ + typename TStorage::LinkType restriction{static_cast(restrictionPack)...}; + return All(storage, typename TStorage::LinkType{}); +} - template - static void EnsureLinkIsAnyOrExists(TStorage& storage, const typename TStorage::LinkType& restriction) - { - using namespace Platform::Exceptions; - auto any = storage.Constants.Any; - for (auto i { 0 }; i < restriction.Count(); ++i) - { - if ((any != restriction[i]) && !storage.Exists(restriction[i])) - { - throw ArgumentLinkDoesNotExistsException(restriction[i], std::string("sequence[").append(Platform::Converters::To(i)).append(1, ']')); - } - } - } +template +static typename TStorage::LinkAddressType AllIndices(TStorage& storage, const typename TStorage::LinkType& restriction) +{ + std::vector allIndices{}; + auto usages = std::vector(); + auto $continue = storage.Constants.Continue; + DIRECT_METHOD_CALL(TStorage, storage, Each, restriction, + [&allIndices, $continue](const typename TStorage::LinkType& link) + { + allIndices.push_back(link); + return $continue; + }); + return allIndices; +} - template - static void EnsureLinkIsAnyOrExists(TStorage& storage, typename TStorage::LinkAddressType linkAddress, std::string argumentName) - { - using namespace Platform::Exceptions; - if ((storage.Constants.Any != linkAddress) && !storage.Exists(linkAddress)) - { - throw ArgumentLinkDoesNotExistsException(linkAddress, argumentName); - } - } - template - static void EnsureLinkIsItselfOrExists(TStorage& storage, typename TStorage::LinkAddressType linkAddress, std::string argumentName) +template +static void EnsureLinkExists(TStorage& storage, const typename TStorage::LinkType& restriction) +{ + for (auto i{0}; i < restriction.Count(); ++i) + { + if (!storage.Exists(restriction[i])) { - using namespace Platform::Exceptions; - if ((storage.Constants.Itself != linkAddress) && !storage.Exists(linkAddress)) - { - throw ArgumentLinkDoesNotExistsException(linkAddress, argumentName); - } + throw ArgumentLinkDoesNotExistsException( + restriction[i], + std::string("sequence[").append(Platform::Converters::To(i)).append(1, ']')); } + } +} - template - static void EnsureDoesNotExists(TStorage& storage, typename TStorage::LinkAddressType source, typename TStorage::LinkAddressType target) - { - using namespace Platform::Exceptions; - if (storage.Exists(source, target)) - { - throw Platform::Exceptions::LinkWithSameValueAlreadyExistsException(); - } - } +template +static bool Exists(TStorage& storage, typename TStorage::LinkAddressType source, + typename TStorage::LinkAddressType target) +{ + return DIRECT_METHOD_CALL(TStorage, storage, Count, + typename TStorage::LinkType{storage.Constants.Any, source, target}) > 0; +} - template - static void EnsureNoUsages(TStorage& storage, typename TStorage::LinkAddressType linkAddress) - { - using namespace Platform::Exceptions; - if (storage.HasUsages(linkAddress)) - { - throw ArgumentLinkHasDependenciesException(linkAddress); - } - } - template - static void EnsureCreated(TStorage& storage, const typename TStorage::LinkType& addresses) - { - storage.EnsureCreated(storage.Create, addresses); - } +template +static void EnsureInnerReferenceExists(TStorage& storage, typename TStorage::LinkAddressType reference, + std::string argumentName) +{ + using namespace Platform::Exceptions; + if (storage.Constants.IsInternalReference(reference) && !storage.Exists(reference)) + { + throw ArgumentLinkDoesNotExistsException(reference, argumentName); + } +} - template - static void EnsurePointsCreated(TStorage& storage, const typename TStorage::LinkType& addresses) +template +static void EnsureInnerReferenceExists(TStorage& storage, const typename TStorage::LinkType& restriction, + std::string argumentName) +{ + using namespace Platform::Exceptions; + for (std::int32_t i = 0; i < restriction.Count(); ++i) + { + storage.EnsureInnerReferenceExists(restriction[i], argumentName); + } +} + +template +static void EnsureLinkIsAnyOrExists(TStorage& storage, const typename TStorage::LinkType& restriction) +{ + using namespace Platform::Exceptions; + auto any = storage.Constants.Any; + for (auto i{0}; i < restriction.Count(); ++i) + { + if ((any != restriction[i]) && !storage.Exists(restriction[i])) { - storage.EnsureCreated(storage.CreatePoint, addresses); + throw ArgumentLinkDoesNotExistsException( + restriction[i], + std::string("sequence[").append(Platform::Converters::To(i)).append(1, ']')); } + } +} - template - static void EnsureCreated(TStorage& storage, std::function creator, const typename TStorage::LinkType& addresses) +template +static void EnsureLinkIsAnyOrExists(TStorage& storage, typename TStorage::LinkAddressType linkAddress, + std::string argumentName) +{ + using namespace Platform::Exceptions; + if ((storage.Constants.Any != linkAddress) && !storage.Exists(linkAddress)) + { + throw ArgumentLinkDoesNotExistsException(linkAddress, argumentName); + } +} + +template +static void EnsureLinkIsItselfOrExists(TStorage& storage, typename TStorage::LinkAddressType linkAddress, + std::string argumentName) +{ + using namespace Platform::Exceptions; + if ((storage.Constants.Itself != linkAddress) && !storage.Exists(linkAddress)) + { + throw ArgumentLinkDoesNotExistsException(linkAddress, argumentName); + } +} + +template +static void EnsureDoesNotExists(TStorage& storage, typename TStorage::LinkAddressType source, + typename TStorage::LinkAddressType target) +{ + using namespace Platform::Exceptions; + if (storage.Exists(source, target)) + { + throw Platform::Exceptions::LinkWithSameValueAlreadyExistsException(); + } +} + +template +static void EnsureNoUsages(TStorage& storage, typename TStorage::LinkAddressType linkAddress) +{ + using namespace Platform::Exceptions; + if (storage.HasUsages(linkAddress)) + { + throw ArgumentLinkHasDependenciesException(linkAddress); + } +} + +template +static void EnsureCreated(TStorage& storage, const typename TStorage::LinkType& addresses) +{ + storage.EnsureCreated(storage.Create, addresses); +} + +template +static void EnsurePointsCreated(TStorage& storage, const typename TStorage::LinkType& addresses) +{ + storage.EnsureCreated(storage.CreatePoint, addresses); +} + +template +static void EnsureCreated(TStorage& storage, std::function creator, + const typename TStorage::LinkType& addresses) +{ + std::unordered_set nonExistentLinkAddresses{}; + typename TStorage::LinkAddressType maxLinkAddress{}; + for (auto linkAddress : nonExistentLinkAddresses) + { + if (!storage.Exists(linkAddress)) { - std::unordered_set nonExistentLinkAddresses{}; - typename TStorage::LinkAddressType maxLinkAddress {}; - for(auto linkAddress : nonExistentLinkAddresses) - { - if(!storage.Exists(linkAddress)) - { - nonExistentLinkAddresses.insert(linkAddress); - if(linkAddress > maxLinkAddress) - { - maxLinkAddress = linkAddress; - } - } - } - if (!nonExistentLinkAddresses.empty()) + nonExistentLinkAddresses.insert(linkAddress); + if (linkAddress > maxLinkAddress) { - maxLinkAddress = std::min(maxLinkAddress, storage.Constants.InternalReferencesRange.Maximum); - std::vector createdLinks {}; - typename TStorage::LinkAddressType createdLink = creator(); - while (maxLinkAddress != createdLink) - { - createdLinks.Add(createdLink); - } - for (auto i { 0 }; i < createdLinks.size(); ++i) - { - if (!nonExistentLinkAddresses.contains(createdLinks[i])) - { - Delete(storage, createdLinks[i]); - } - } + maxLinkAddress = linkAddress; } } - - template - static typename TStorage::LinkAddressType CountUsages(TStorage& storage, typename TStorage::LinkAddressType linkAddress) + } + if (!nonExistentLinkAddresses.empty()) + { + maxLinkAddress = std::min(maxLinkAddress, storage.Constants.InternalReferencesRange.Maximum); + std::vector createdLinks{}; + typename TStorage::LinkAddressType createdLink = creator(); + while (maxLinkAddress != createdLink) { - constexpr auto constants = storage.Constants; - auto values = GetLink(storage, linkAddress); - auto usagesAsSource = DIRECT_METHOD_CALL(TStorage, storage, Count,typename TStorage::LinkType{constants.Any, storage, linkAddress, constants.Any}); - if (linkAddress == GetSource(storage, values)) - { - --usagesAsSource; - } - auto usagesAsTarget = DIRECT_METHOD_CALL(TStorage, storage, Count,typename TStorage::LinkType{constants.Any, storage, constants.Any, linkAddress}); - if (linkAddress == GetTarget(storage, values)) + createdLinks.Add(createdLink); + } + for (auto i{0}; i < createdLinks.size(); ++i) + { + if (!nonExistentLinkAddresses.contains(createdLinks[i])) { - --usagesAsTarget; + Delete(storage, createdLinks[i]); } - return usagesAsSource + usagesAsTarget; } + } +} - template - static bool HasUsages(TStorage& storage, typename TStorage::LinkAddressType linkAddress) { return CountUsages(storage,linkAddress)>0; } +template +static typename TStorage::LinkAddressType CountUsages(TStorage& storage, typename TStorage::LinkAddressType linkAddress) +{ + constexpr auto constants = storage.Constants; + auto values = GetLink(storage, linkAddress); + auto usagesAsSource = DIRECT_METHOD_CALL( + TStorage, storage, Count, typename TStorage::LinkType{constants.Any, storage, linkAddress, constants.Any}); + if (linkAddress == GetSource(storage, values)) + { + --usagesAsSource; + } + auto usagesAsTarget = DIRECT_METHOD_CALL( + TStorage, storage, Count, typename TStorage::LinkType{constants.Any, storage, constants.Any, linkAddress}); + if (linkAddress == GetTarget(storage, values)) + { + --usagesAsTarget; + } + return usagesAsSource + usagesAsTarget; +} - template - typename TStorage::LinkAddressType SearchOrDefault(TStorage& storage, typename TStorage::LinkAddressType source, typename TStorage::LinkAddressType target) - { - constexpr auto constants = storage.Constants; - auto _break = constants.Break; - typename TStorage::LinkAddressType searchedLinkAddress {}; - DIRECT_METHOD_CALL(TStorage, storage, Each,typename TStorage::LinkType{storage.Constants.Any, source, target}, [&searchedLinkAddress, _break] (const typename TStorage::LinkType& link) { - searchedLinkAddress = link[0]; - return _break; - }); - return searchedLinkAddress; - } - template - auto CreatePoint(TStorage& storage) - { - auto point = Platform::Data::Create(storage); - return Update(storage, point, point, point); - } +template +static bool HasUsages(TStorage& storage, typename TStorage::LinkAddressType linkAddress) +{ + return CountUsages(storage, linkAddress) > 0; +} - template - static typename TStorage::LinkAddressType CreatePoint(TStorage& storage, const typename TStorage::WriteHandlerType& handler) - { - constexpr auto constants = storage.Constants; - WriteHandlerState handlerState {constants.Continue, constants.Break, handler}; - typename TStorage::LinkAddressType linkAddress; - typename TStorage::LinkAddressType HandlerWrapper = [&linkAddress, &handlerState](const typename TStorage::LinkType& before, const typename TStorage::LinkType& after){ - linkAddress = after[0]; - return handlerState.Handle(before, after); - }; - handlerState.Apply(DIRECT_METHOD_CALL(TStorage, storage, Create,typename TStorage::LinkType{}, HandlerWrapper)); - return handlerState.Apply(DIRECT_METHOD_CALL(TStorage, storage, Update,linkAddress, linkAddress, linkAddress, HandlerWrapper)); - } +template +typename TStorage::LinkAddressType SearchOrDefault(TStorage& storage, typename TStorage::LinkAddressType source, + typename TStorage::LinkAddressType target) +{ + constexpr auto constants = storage.Constants; + auto _break = constants.Break; + typename TStorage::LinkAddressType searchedLinkAddress{}; + DIRECT_METHOD_CALL(TStorage, storage, Each, typename TStorage::LinkType{storage.Constants.Any, source, target}, + [&searchedLinkAddress, _break](const typename TStorage::LinkType& link) + { + searchedLinkAddress = link[0]; + return _break; + }); + return searchedLinkAddress; +} +template +auto CreatePoint(TStorage& storage) +{ + auto point = Platform::Data::Create(storage); + return Update(storage, point, point, point); +} - template - typename TStorage::LinkAddressType CreateAndUpdate(TStorage& storage, typename TStorage::LinkAddressType source, typename TStorage::LinkAddressType target) - { - auto $continue {storage.Constants.Continue}; - typename TStorage::LinkAddressType linkAddress; - return CreateAndUpdate(storage, source, target, [&linkAddress, $continue](const typename TStorage::LinkType& before, const typename TStorage::LinkType& after){ - linkAddress = after[0]; - return $continue; - }); - } +template +static typename TStorage::LinkAddressType CreatePoint(TStorage& storage, + const typename TStorage::WriteHandlerType& handler) +{ + constexpr auto constants = storage.Constants; + WriteHandlerState handlerState{constants.Continue, constants.Break, handler}; + typename TStorage::LinkAddressType linkAddress; + typename TStorage::LinkAddressType HandlerWrapper = + [&linkAddress, &handlerState](const typename TStorage::LinkType& before, + const typename TStorage::LinkType& after) + { + linkAddress = after[0]; + return handlerState.Handle(before, after); + }; + handlerState.Apply(DIRECT_METHOD_CALL(TStorage, storage, Create, typename TStorage::LinkType{}, HandlerWrapper)); + return handlerState.Apply( + DIRECT_METHOD_CALL(TStorage, storage, Update, linkAddress, linkAddress, linkAddress, HandlerWrapper)); +} - template - static typename TStorage::LinkAddressType CreateAndUpdate(TStorage& storage, typename TStorage::LinkAddressType source, typename TStorage::LinkAddressType target, const typename TStorage::WriteHandlerType& handler) +template +typename TStorage::LinkAddressType CreateAndUpdate(TStorage& storage, typename TStorage::LinkAddressType source, + typename TStorage::LinkAddressType target) +{ + auto $continue{storage.Constants.Continue}; + typename TStorage::LinkAddressType linkAddress; + return CreateAndUpdate( + storage, source, target, + [&linkAddress, $continue](const typename TStorage::LinkType& before, const typename TStorage::LinkType& after) { - constexpr auto constants = storage.Constants; - typename TStorage::LinkAddressType createdLinkAddress; - WriteHandlerState handlerState {constants.Continue, constants.Break, handler}; - handlerState.Apply(DIRECT_METHOD_CALL(TStorage, storage, Create,typename TStorage::LinkType{}, [&createdLinkAddress, &handlerState](const typename TStorage::LinkType& before, const typename TStorage::LinkType& after){ - createdLinkAddress = after[0]; - return handlerState.Handle(before, after); - })); - return handlerState.Apply(Update(storage, createdLinkAddress, source, target, handlerState.Handler)); - } + linkAddress = after[0]; + return $continue; + }); +} - template - typename TStorage::LinkAddressType Update(TStorage& storage, CArray auto&& restriction, CArray auto&& substitution) - { - auto $continue {storage.Constants.Continue}; - typename TStorage::LinkAddressType updatedLinkAddress; - DIRECT_METHOD_CALL(TStorage, storage, Update,restriction, substitution, [&updatedLinkAddress, $continue] (const typename TStorage::LinkType& before, const typename TStorage::LinkType& after) { - updatedLinkAddress = after[0]; - return $continue; - }); - return updatedLinkAddress; - } +template +static typename TStorage::LinkAddressType CreateAndUpdate(TStorage& storage, typename TStorage::LinkAddressType source, + typename TStorage::LinkAddressType target, + const typename TStorage::WriteHandlerType& handler) +{ + constexpr auto constants = storage.Constants; + typename TStorage::LinkAddressType createdLinkAddress; + WriteHandlerState handlerState{constants.Continue, constants.Break, handler}; + handlerState.Apply( + DIRECT_METHOD_CALL(TStorage, storage, Create, typename TStorage::LinkType{}, + [&createdLinkAddress, &handlerState](const typename TStorage::LinkType& before, + const typename TStorage::LinkType& after) + { + createdLinkAddress = after[0]; + return handlerState.Handle(before, after); + })); + return handlerState.Apply(Update(storage, createdLinkAddress, source, target, handlerState.Handler)); +} - template - static typename TStorage::LinkAddressType Update(TStorage& storage, const typename TStorage::LinkType& restriction, const typename TStorage::WriteHandlerType& handler) - { - const auto length { std::ranges::size(restriction) }; - if (length == 2) - { - return MergeAndDelete(storage, restriction[0], restriction[1], handler); - } - else if (length == 4) - { - return UpdateOrCreateOrGet(storage, restriction[0], restriction[1], restriction[2], restriction[3], handler); - } - else - { - return Update(storage, restriction[0], restriction[1], restriction[2], handler); - } - } +template +typename TStorage::LinkAddressType Update(TStorage& storage, + CArray auto&& restriction, + CArray auto&& substitution) +{ + auto $continue{storage.Constants.Continue}; + typename TStorage::LinkAddressType updatedLinkAddress; + DIRECT_METHOD_CALL(TStorage, storage, Update, restriction, substitution, + [&updatedLinkAddress, $continue](const typename TStorage::LinkType& before, + const typename TStorage::LinkType& after) + { + updatedLinkAddress = after[0]; + return $continue; + }); + return updatedLinkAddress; +} - template - static typename TStorage::LinkAddressType Update(TStorage& storage, typename TStorage::LinkAddressType linkAddress, typename TStorage::LinkAddressType newSource, typename TStorage::LinkAddressType newTarget, const typename TStorage::WriteHandlerType& handler) - { - return DIRECT_METHOD_CALL(TStorage, storage, Update, typename TStorage::LinkType{linkAddress}, typename TStorage::LinkType{linkAddress, newSource, newTarget}, handler); -// return std::is_abstract::value ? DIRECT_METHOD_CALL(TStorage, storage, Update,typename TStorage::LinkType{linkAddress}, typename TStorage::LinkType{linkAddress, newSource, newTarget}, handler) : storage.TStorage::Update(typename TStorage::LinkType{linkAddress}, typename TStorage::LinkType{linkAddress, newSource, newTarget}, handler); -// if constexpr (std::is_abstract::value) { -// return DIRECT_METHOD_CALL(TStorage, storage, Update,typename TStorage::LinkType{linkAddress}, typename TStorage::LinkType{linkAddress, newSource, newTarget}, handler); -// } else { -// return storage.TStorage::Update(typename TStorage::LinkType{linkAddress}, typename TStorage::LinkType{linkAddress, newSource, newTarget}, handler); -// } - } +template +static typename TStorage::LinkAddressType Update(TStorage& storage, const typename TStorage::LinkType& restriction, + const typename TStorage::WriteHandlerType& handler) +{ + const auto length{std::ranges::size(restriction)}; + if (length == 2) + { + return MergeAndDelete(storage, restriction[0], restriction[1], handler); + } + else if (length == 4) + { + return UpdateOrCreateOrGet(storage, restriction[0], restriction[1], restriction[2], restriction[3], handler); + } + else + { + return Update(storage, restriction[0], restriction[1], restriction[2], handler); + } +} - template - static typename TStorage::LinkAddressType Update(TStorage& storage, typename TStorage::LinkAddressType linkAddress, typename TStorage::LinkAddressType newSource, typename TStorage::LinkAddressType newTarget) - { - auto $continue {storage.Constants.Continue}; - typename TStorage::LinkAddressType updatedLinkAddress; - Update(storage, linkAddress, newSource, newTarget, [&updatedLinkAddress, $continue] (const typename TStorage::LinkType& before, const typename TStorage::LinkType& after) { - updatedLinkAddress = after[0]; - return $continue; - }); - return updatedLinkAddress; - } +template +static typename TStorage::LinkAddressType +Update(TStorage& storage, typename TStorage::LinkAddressType linkAddress, typename TStorage::LinkAddressType newSource, + typename TStorage::LinkAddressType newTarget, const typename TStorage::WriteHandlerType& handler) +{ + return DIRECT_METHOD_CALL(TStorage, storage, Update, typename TStorage::LinkType{linkAddress}, + typename TStorage::LinkType{linkAddress, newSource, newTarget}, handler); + // return std::is_abstract::value ? DIRECT_METHOD_CALL(TStorage, storage, Update,typename + // TStorage::LinkType{linkAddress}, typename TStorage::LinkType{linkAddress, newSource, newTarget}, + // handler) : storage.TStorage::Update(typename TStorage::LinkType{linkAddress}, typename + // TStorage::LinkType{linkAddress, newSource, newTarget}, handler); if constexpr + // (std::is_abstract::value) { + // return DIRECT_METHOD_CALL(TStorage, storage, Update,typename TStorage::LinkType{linkAddress}, typename + // TStorage::LinkType{linkAddress, newSource, newTarget}, handler); + // } else { + // return storage.TStorage::Update(typename TStorage::LinkType{linkAddress}, typename + // TStorage::LinkType{linkAddress, newSource, newTarget}, handler); + // } +} - template - static typename TStorage::LinkAddressType Update(TStorage& storage, const typename TStorage::LinkType& restriction) - { - auto $continue {storage.Constants.Continue}; - typename TStorage::LinkAddressType updatedLinkAddress; - return Update(storage, restriction, [&updatedLinkAddress, $continue](const typename TStorage::LinkType& before, const typename TStorage::LinkType& after){ - updatedLinkAddress = after; - return $continue; - }); - } +template +static typename TStorage::LinkAddressType Update(TStorage& storage, typename TStorage::LinkAddressType linkAddress, + typename TStorage::LinkAddressType newSource, + typename TStorage::LinkAddressType newTarget) +{ + auto $continue{storage.Constants.Continue}; + typename TStorage::LinkAddressType updatedLinkAddress; + Update(storage, linkAddress, newSource, newTarget, + [&updatedLinkAddress, $continue](const typename TStorage::LinkType& before, + const typename TStorage::LinkType& after) + { + updatedLinkAddress = after[0]; + return $continue; + }); + return updatedLinkAddress; +} - template - static typename TStorage::LinkAddressType Update(TStorage& storage, const typename TStorage::WriteHandlerType& handler, std::convertible_to auto ... restrictionPack) - { - typename TStorage::HandlerParameterType restriction{ - static_cast(restrictionPack)... }; - return Update(storage, restriction, handler); - } - // - template - static typename TStorage::LinkType ResolveConstantAsSelfReference(const TStorage& storage, typename TStorage::LinkAddressType constant, const typename TStorage::LinkType& restriction, const typename TStorage::LinkType& substitution) - { - constexpr auto constants = storage.Constants; - auto restrictionIndex = GetIndex(storage, restriction); - auto substitutionIndex = GetIndex(storage, substitution); - if ( constants.Null == substitutionIndex) - { - substitutionIndex = restrictionIndex; - } - auto source = GetSource(storage, substitution); - auto target = GetTarget(storage, substitution); - source = constant == source ? substitutionIndex : source; - target = constant == target ? substitutionIndex : target; - return typename TStorage::LinkType{substitutionIndex, source, target}; - } +template +static typename TStorage::LinkAddressType Update(TStorage& storage, const typename TStorage::LinkType& restriction) +{ + auto $continue{storage.Constants.Continue}; + typename TStorage::LinkAddressType updatedLinkAddress; + return Update(storage, restriction, + [&updatedLinkAddress, $continue](const typename TStorage::LinkType& before, + const typename TStorage::LinkType& after) + { + updatedLinkAddress = after; + return $continue; + }); +} - template - typename TStorage::LinkAddressType GetOrCreate(TStorage& storage, typename TStorage::LinkAddressType source, typename TStorage::LinkAddressType target) - { - constexpr auto constants = storage.Constants; - auto link = SearchOrDefault(storage, source, target); - if (link == constants.Null) - { - link = CreateAndUpdate(storage, source, target); - } - return link; - } +template +static typename TStorage::LinkAddressType +Update(TStorage& storage, const typename TStorage::WriteHandlerType& handler, + std::convertible_to auto... restrictionPack) +{ + typename TStorage::HandlerParameterType restriction{ + static_cast(restrictionPack)...}; + return Update(storage, restriction, handler); +} +// +template +static typename TStorage::LinkType ResolveConstantAsSelfReference(const TStorage& storage, + typename TStorage::LinkAddressType constant, + const typename TStorage::LinkType& restriction, + const typename TStorage::LinkType& substitution) +{ + constexpr auto constants = storage.Constants; + auto restrictionIndex = GetIndex(storage, restriction); + auto substitutionIndex = GetIndex(storage, substitution); + if (constants.Null == substitutionIndex) + { + substitutionIndex = restrictionIndex; + } + auto source = GetSource(storage, substitution); + auto target = GetTarget(storage, substitution); + source = constant == source ? substitutionIndex : source; + target = constant == target ? substitutionIndex : target; + return typename TStorage::LinkType{substitutionIndex, source, target}; +} - template - static typename TStorage::LinkAddressType UpdateOrCreateOrGet(TStorage& storage, typename TStorage::LinkAddressType source, typename TStorage::LinkAddressType target, typename TStorage::LinkAddressType newSource, typename TStorage::LinkAddressType newTarget, const typename TStorage::WriteHandlerType& handler) +template +typename TStorage::LinkAddressType GetOrCreate(TStorage& storage, typename TStorage::LinkAddressType source, + typename TStorage::LinkAddressType target) +{ + constexpr auto constants = storage.Constants; + auto link = SearchOrDefault(storage, source, target); + if (link == constants.Null) { - auto link = SearchOrDefault(storage, source, target); - if (storage.Constants.Null == link) - { - return CreateAndUpdate(storage, newSource, newTarget, handler); - } - if ((source == newSource) && (target == newTarget)) - { - return link; - } - return Update(storage, link, newSource, newTarget, handler); + link = CreateAndUpdate(storage, source, target); } + return link; +} - template - static typename TStorage::LinkAddressType UpdateOrCreateOrGet(TStorage& storage, typename TStorage::LinkAddressType source, typename TStorage::LinkAddressType target, typename TStorage::LinkAddressType newSource, typename TStorage::LinkAddressType newTarget) +template +static typename TStorage::LinkAddressType +UpdateOrCreateOrGet(TStorage& storage, typename TStorage::LinkAddressType source, + typename TStorage::LinkAddressType target, typename TStorage::LinkAddressType newSource, + typename TStorage::LinkAddressType newTarget, const typename TStorage::WriteHandlerType& handler) +{ + auto link = SearchOrDefault(storage, source, target); + if (storage.Constants.Null == link) { - auto $continue = storage.Constants.Continue; - typename TStorage::LinkAddressType resultLink; - UpdateOrCreateOrGet(storage, source, target, newSource, newTarget, [&resultLink, $continue](const typename TStorage::LinkType& before, const typename TStorage::LinkType& after) { + return CreateAndUpdate(storage, newSource, newTarget, handler); + } + if ((source == newSource) && (target == newTarget)) + { + return link; + } + return Update(storage, link, newSource, newTarget, handler); +} + +template +static typename TStorage::LinkAddressType +UpdateOrCreateOrGet(TStorage& storage, typename TStorage::LinkAddressType source, + typename TStorage::LinkAddressType target, typename TStorage::LinkAddressType newSource, + typename TStorage::LinkAddressType newTarget) +{ + auto $continue = storage.Constants.Continue; + typename TStorage::LinkAddressType resultLink; + UpdateOrCreateOrGet( + storage, source, target, newSource, newTarget, + [&resultLink, $continue](const typename TStorage::LinkType& before, const typename TStorage::LinkType& after) + { resultLink = after[0]; return $continue; }); - return resultLink; - } + return resultLink; +} - template - typename TStorage::LinkAddressType DeleteIfExists(TStorage& storage, typename TStorage::LinkAddressType source, typename TStorage::LinkAddressType target) +template +typename TStorage::LinkAddressType DeleteIfExists(TStorage& storage, typename TStorage::LinkAddressType source, + typename TStorage::LinkAddressType target) +{ + constexpr auto constants = storage.Constants; + auto linkAddress = storage.SearchOrDefault(source, target); + if (linkAddress != constants.Null) { - constexpr auto constants = storage.Constants; - auto linkAddress = storage.SearchOrDefault(source, target); - if (linkAddress != constants.Null) - { - return Delete(storage, linkAddress); - } - return constants.Null; + return Delete(storage, linkAddress); } + return constants.Null; +} - template - static void DeleteMany(TStorage& storage, const typename TStorage::LinkType& linkAddressesToDelete) +template +static void DeleteMany(TStorage& storage, const typename TStorage::LinkType& linkAddressesToDelete) +{ + for (auto linkAddress : linkAddressesToDelete) { - for (auto linkAddress : linkAddressesToDelete) { - Delete(storage, linkAddress); - } + Delete(storage, linkAddress); } +} - template - static typename TStorage::LinkAddressType DeleteAllUsages(TStorage& storage, typename TStorage::LinkAddressType linkIndex, const typename TStorage::WriteHandlerType& handler) +template +static typename TStorage::LinkAddressType DeleteAllUsages(TStorage& storage, + typename TStorage::LinkAddressType linkIndex, + const typename TStorage::WriteHandlerType& handler) +{ + constexpr auto constants = storage.Constants; + auto any = constants.Any; + auto $continue = storage.Constants.Continue; + auto $break = storage.Constants.Break; + auto usagesAsSourceQuery = typename TStorage::LinkType{any, linkIndex, any}; + auto usagesAsTargetQuery = typename TStorage::LinkType{any, any, linkIndex}; + auto usages = std::vector(); + DIRECT_METHOD_CALL(TStorage, storage, Each, usagesAsSourceQuery, + [&usages, $continue](const typename TStorage::LinkType& link) + { + usages.push_back(link); + return $continue; + }); + DIRECT_METHOD_CALL(TStorage, storage, Each, usagesAsTargetQuery, + [&usages, $continue](auto&& link) + { + usages.push_back(link); + return $continue; + }); + WriteHandlerState handlerState{$continue, $break, handler}; + for (auto usage : usages) { - constexpr auto constants = storage.Constants; - auto any = constants.Any; - auto $continue = storage.Constants.Continue; - auto $break = storage.Constants.Break; - auto usagesAsSourceQuery = typename TStorage::LinkType{any, linkIndex, any}; - auto usagesAsTargetQuery = typename TStorage::LinkType{any, any, linkIndex}; - auto usages = std::vector(); - DIRECT_METHOD_CALL(TStorage, storage, Each,usagesAsSourceQuery, [&usages, $continue](const typename TStorage::LinkType& link) { - usages.push_back(link); - return $continue; - }); - DIRECT_METHOD_CALL(TStorage, storage, Each,usagesAsTargetQuery, [&usages, $continue](auto&& link) { - usages.push_back(link); - return $continue; - }); - WriteHandlerState handlerState {$continue, $break, handler}; - for (auto usage : usages) + auto usageAddress{GetIndex(storage, usage)}; + if (linkIndex == usageAddress || Exists(storage, usageAddress)) { - auto usageAddress {GetIndex(storage, usage)}; - if (linkIndex == usageAddress || Exists(storage, usageAddress)) - { - continue; - } - auto result = DIRECT_METHOD_CALL(TStorage, storage, Delete,usage, handlerState.Handler); - handlerState.Apply(result); + continue; } - return handlerState.Result; + auto result = DIRECT_METHOD_CALL(TStorage, storage, Delete, usage, handlerState.Handler); + handlerState.Apply(result); } + return handlerState.Result; +} - template - static void DeleteAllUsages(TStorage& storage, typename TStorage::LinkAddressType linkIndex) - { - DeleteAllUsages(storage, linkIndex, nullptr); - } +template +static void DeleteAllUsages(TStorage& storage, typename TStorage::LinkAddressType linkIndex) +{ + DeleteAllUsages(storage, linkIndex, nullptr); +} - // Do not translate this +// Do not translate this // template // auto DeleteByQuery(TStorage& storage, CArray auto&& query) // { @@ -683,173 +796,183 @@ namespace Platform::Data::Doublets // } // } - template - auto DeleteAll(TStorage& storage) +template +auto DeleteAll(TStorage& storage) +{ + auto handler = [](typename TStorage::LinkType before, typename TStorage::LinkType substitution) + { return typename TStorage::LinkAddressType{}; }; + auto any = storage.Constants.Any; + for (auto count = Count(storage); count != storage.Constants.Null; count = Count(storage)) { - auto handler = [](typename TStorage::LinkType before, typename TStorage::LinkType substitution) { - return typename TStorage::LinkAddressType {}; - }; - auto any = storage.Constants.Any; - for (auto count = Count(storage); count != storage.Constants.Null; count = Count(storage)) - { - DIRECT_METHOD_CALL(TStorage, storage, Delete, {count, any, any}, handler); - } + DIRECT_METHOD_CALL(TStorage, storage, Delete, {count, any, any}, handler); } +} - template - static bool AreValuesReset(const TStorage& storage, typename TStorage::LinkAddressType linkIndex) +template +static bool AreValuesReset(const TStorage& storage, typename TStorage::LinkAddressType linkIndex) +{ + auto nullConstant = storage.Constants.Null; + auto link = GetLink(storage, linkIndex); + for (typename TStorage::LinkAddressType i = typename TStorage::LinkAddressType{1}; i < std::ranges::size(link); ++i) { - auto nullConstant = storage.Constants.Null; - auto link = GetLink(storage, linkIndex); - for (typename TStorage::LinkAddressType i = typename TStorage::LinkAddressType{1}; i < std::ranges::size(link); ++i) + if (nullConstant != link[i]) { - if ( nullConstant != link[i]) - { - return false; - } + return false; } - return true; } + return true; +} + +template +typename TStorage::LinkAddressType ResetValues(TStorage& storage, typename TStorage::LinkAddressType linkAddress, + const typename TStorage::WriteHandlerType& handler) +{ + return Update(storage, linkAddress, 0, 0, handler); +} + +template +void ResetValues(TStorage& storage, typename TStorage::LinkAddressType linkAddress) +{ + auto $break = storage.Constants.Break; + ResetValues(storage, linkAddress, nullptr); +} - template - typename TStorage::LinkAddressType ResetValues(TStorage& storage, typename TStorage::LinkAddressType linkAddress, const typename TStorage::WriteHandlerType& handler) +template +static typename TStorage::LinkAddressType EnforceResetValues(TStorage& storage, + typename TStorage::LinkAddressType linkIndex, + const typename TStorage::WriteHandlerType& handler) +{ + if (!AreValuesReset(storage, linkIndex)) { - return Update(storage, linkAddress, 0, 0, handler); + return ResetValues(storage, linkIndex, handler); } + return storage.Constants.Continue; +} + +template +static typename TStorage::LinkAddressType EnforceResetValues(TStorage& storage, + typename TStorage::LinkAddressType linkIndex) +{ + return EnforceResetValues(storage, linkIndex, nullptr); +} - template - void ResetValues(TStorage& storage, typename TStorage::LinkAddressType linkAddress) +template +static typename TStorage::LinkAddressType +MergeUsages(TStorage& storage, typename TStorage::LinkAddressType oldLinkIndex, + typename TStorage::LinkAddressType newLinkIndex, const typename TStorage::WriteHandlerType& handler) +{ + if (newLinkIndex == oldLinkIndex) { - auto $break = storage.Constants.Break; - ResetValues(storage, linkAddress, nullptr); + return newLinkIndex; } - - template - static typename TStorage::LinkAddressType EnforceResetValues(TStorage& storage, typename TStorage::LinkAddressType linkIndex, const typename TStorage::WriteHandlerType& handler) + constexpr auto constants = storage.Constants; + auto usagesAsSource = All(storage, typename TStorage::LinkType(constants.Any, oldLinkIndex, constants.Any)); + WriteHandlerState handlerState{constants.Continue, constants.Break, handler}; + for (auto i{0}; i < std::ranges::size(usagesAsSource); ++i) { - if (!AreValuesReset(storage, linkIndex)) + auto usageAsSource = usagesAsSource[i]; + if (oldLinkIndex == GetIndex(storage, usageAsSource)) { - return ResetValues(storage, linkIndex, handler); + continue; } - return storage.Constants.Continue; + typename TStorage::LinkType restriction{GetIndex(storage, usageAsSource)}; + typename TStorage::LinkType substitution = (newLinkIndex, GetTarget(storage, usageAsSource)); + handlerState.Apply( + DIRECT_METHOD_CALL(TStorage, storage, Update, restriction, substitution, handlerState.Handler)); } - - template - static typename TStorage::LinkAddressType EnforceResetValues(TStorage& storage, typename TStorage::LinkAddressType linkIndex) + auto usagesAsTarget = All(storage, typename TStorage::LinkType(constants.Any, constants.Any, oldLinkIndex)); + for (auto i{0}; i < std::ranges::size(usagesAsTarget); ++i) { - return EnforceResetValues(storage, linkIndex, nullptr); - } - - template - static typename TStorage::LinkAddressType MergeUsages(TStorage& storage, typename TStorage::LinkAddressType oldLinkIndex, typename TStorage::LinkAddressType newLinkIndex, const typename TStorage::WriteHandlerType& handler) + auto usageAsTarget = usagesAsTarget[i]; + if (oldLinkIndex == GetIndex(storage, usageAsTarget)) { - if (newLinkIndex == oldLinkIndex) - { - return newLinkIndex; - } - constexpr auto constants = storage.Constants; - auto usagesAsSource = All(storage, typename TStorage::LinkType(constants.Any, oldLinkIndex, constants.Any)); - WriteHandlerState handlerState {constants.Continue, constants.Break, handler}; - for (auto i { 0 }; i < std::ranges::size(usagesAsSource); ++i) - { - auto usageAsSource = usagesAsSource[i]; - if ( oldLinkIndex == GetIndex(storage, usageAsSource)) - { - continue; - } - typename TStorage::LinkType restriction {GetIndex(storage, usageAsSource)}; - typename TStorage::LinkType substitution = (newLinkIndex, GetTarget(storage, usageAsSource)); - handlerState.Apply(DIRECT_METHOD_CALL(TStorage, storage, Update,restriction, substitution, handlerState.Handler)); - } - auto usagesAsTarget = All(storage, typename TStorage::LinkType(constants.Any, constants.Any, oldLinkIndex)); - for (auto i { 0 }; i < std::ranges::size(usagesAsTarget); ++i) - { - auto usageAsTarget = usagesAsTarget[i]; - if ( oldLinkIndex == GetIndex(storage, usageAsTarget)) - { - continue; - } - auto substitution = typename TStorage::LinkType(GetTarget(storage, usageAsTarget), newLinkIndex); - handlerState.Apply(DIRECT_METHOD_CALL(TStorage, storage, Update,usageAsTarget, substitution, handlerState.Handler)); - } - return handlerState.Result; + continue; } + auto substitution = typename TStorage::LinkType(GetTarget(storage, usageAsTarget), newLinkIndex); + handlerState.Apply( + DIRECT_METHOD_CALL(TStorage, storage, Update, usageAsTarget, substitution, handlerState.Handler)); + } + return handlerState.Result; +} - template - static void MergeUsages(TStorage& storage, typename TStorage::LinkAddressType oldLinkIndex, typename TStorage::LinkAddressType newLinkIndex) - { - MergeUsages(storage, oldLinkIndex, newLinkIndex, nullptr); - } +template +static void MergeUsages(TStorage& storage, typename TStorage::LinkAddressType oldLinkIndex, + typename TStorage::LinkAddressType newLinkIndex) +{ + MergeUsages(storage, oldLinkIndex, newLinkIndex, nullptr); +} - template - static typename TStorage::LinkAddressType MergeAndDelete(TStorage& storage, typename TStorage::LinkAddressType oldLinkIndex, typename TStorage::LinkAddressType newLinkIndex) - { - if ( newLinkIndex != oldLinkIndex) - { - MergeUsages(storage, oldLinkIndex, newLinkIndex); - Delete(storage, oldLinkIndex); - } - return newLinkIndex; - } +template +static typename TStorage::LinkAddressType MergeAndDelete(TStorage& storage, + typename TStorage::LinkAddressType oldLinkIndex, + typename TStorage::LinkAddressType newLinkIndex) +{ + if (newLinkIndex != oldLinkIndex) + { + MergeUsages(storage, oldLinkIndex, newLinkIndex); + Delete(storage, oldLinkIndex); + } + return newLinkIndex; +} - template - static typename TStorage::LinkAddressType MergeAndDelete(TStorage& storage, typename TStorage::LinkAddressType oldLinkIndex, typename TStorage::LinkAddressType newLinkIndex, const typename TStorage::WriteHandlerType& handler) - { - constexpr auto constants = storage.Constants; - WriteHandlerState handlerState {constants.Continue, constants.Break, handler}; - if ( newLinkIndex != oldLinkIndex) - { - handlerState.Apply(MergeUsages(storage, oldLinkIndex, newLinkIndex, handlerState.Handler)); - handlerState.Apply(Delete(storage, oldLinkIndex, handlerState.Handler)); - } - return handlerState.Result; - } +template +static typename TStorage::LinkAddressType +MergeAndDelete(TStorage& storage, typename TStorage::LinkAddressType oldLinkIndex, + typename TStorage::LinkAddressType newLinkIndex, const typename TStorage::WriteHandlerType& handler) +{ + constexpr auto constants = storage.Constants; + WriteHandlerState handlerState{constants.Continue, constants.Break, handler}; + if (newLinkIndex != oldLinkIndex) + { + handlerState.Apply(MergeUsages(storage, oldLinkIndex, newLinkIndex, handlerState.Handler)); + handlerState.Apply(Delete(storage, oldLinkIndex, handlerState.Handler)); + } + return handlerState.Result; +} - template - static std::string Format(TStorage& storage, const typename TStorage::LinkType& link) - { - constexpr auto constants = storage.Constants; - return std::string{} - .append("(") - .append(std::to_string(GetIndex(storage, link))) - .append("): ") - .append("(") - .append(std::to_string(GetSource(storage, link))) - .append(")") - .append(" -> ") - .append("(") - .append(std::to_string(GetTarget(storage,link))) - .append(")"); - } +template +static std::string Format(TStorage& storage, const typename TStorage::LinkType& link) +{ + constexpr auto constants = storage.Constants; + return std::string{} + .append("(") + .append(std::to_string(GetIndex(storage, link))) + .append("): ") + .append("(") + .append(std::to_string(GetSource(storage, link))) + .append(")") + .append(" -> ") + .append("(") + .append(std::to_string(GetTarget(storage, link))) + .append(")"); +} - template - std::string Format(TStorage& storage, typename TStorage::LinkAddressType linkAddress) - { - return Format(GetLink(storage, linkAddress)); - } +template +std::string Format(TStorage& storage, typename TStorage::LinkAddressType linkAddress) +{ + return Format(GetLink(storage, linkAddress)); +} - template - typename TStorage::LinkAddressType HasUsages(TStorage& storage, typename TStorage::LinkAddressType linkAddress) - { - return storage.CountUsages(linkAddress) != 0; - } +template +typename TStorage::LinkAddressType HasUsages(TStorage& storage, typename TStorage::LinkAddressType linkAddress) +{ + return storage.CountUsages(linkAddress) != 0; +} +template +static void DeleteByQuery(TStorage& storage, typename TStorage::LinkType query) +{ + typename TStorage::LinkType queryResult; + DIRECT_METHOD_CALL(TStorage, storage, Each, query, + [&](typename TStorage::LinkType vec) -> typename TStorage::LinkAddressType + { return storage.Constants.Continue; }); - template - static void DeleteByQuery(TStorage& storage, typename TStorage::LinkType query) + for (auto link : queryResult) { - typename TStorage::LinkType queryResult; - DIRECT_METHOD_CALL(TStorage, storage, Each,query, [&](typename TStorage::LinkType vec) -> typename TStorage::LinkAddressType{ - return storage.Constants.Continue; - }); - - for (auto link: queryResult) - { - Delete(storage, link); - } + Delete(storage, link); } +} - -} +} // namespace Platform::Data::Doublets diff --git a/cpp/Platform.Data.Doublets/ISynchronizedLinks.h b/cpp/Platform.Data.Doublets/ISynchronizedLinks.h index 4b7b44f53..a4a1bf9ee 100644 --- a/cpp/Platform.Data.Doublets/ISynchronizedLinks.h +++ b/cpp/Platform.Data.Doublets/ISynchronizedLinks.h @@ -1,8 +1,11 @@ namespace Platform::Data::Doublets { - template class ISynchronizedLinks; - template class ISynchronizedLinks : public ISynchronizedLinks, LinksConstants>, ILinks - { - public: - }; -} +template +class ISynchronizedLinks; +template +class ISynchronizedLinks + : public ISynchronizedLinks, LinksConstants>, ILinks +{ +public: +}; +} // namespace Platform::Data::Doublets diff --git a/cpp/Platform.Data.Doublets/Link.h b/cpp/Platform.Data.Doublets/Link.h index b8c5d6cf9..33cf81c8c 100644 --- a/cpp/Platform.Data.Doublets/Link.h +++ b/cpp/Platform.Data.Doublets/Link.h @@ -1,150 +1,198 @@ namespace Platform::Data::Doublets { - template - struct Link - { - using value_type = TLinkAddress; - public: static constexpr Link Null{}; +template +struct Link +{ + using value_type = TLinkAddress; - private: static constexpr LinksConstants _constants{}; +public: + static constexpr Link Null{}; - private: static constexpr std::size_t Length = 3; +private: + static constexpr LinksConstants _constants{}; - public: TLinkAddress Index = _constants.Null; - public: TLinkAddress Source = _constants.Null; - public: TLinkAddress Target = _constants.Null; +private: + static constexpr std::size_t Length = 3; - public: Link() noexcept = default; - public: Link(const Link&) noexcept = default; - public: Link(Link&&) noexcept = default; +public: + TLinkAddress Index = _constants.Null; - public: auto& operator=(const Link& other) { - Index = other.Index; - Source = other.Source; - Target = other.Target; - return *this; - } +public: + TLinkAddress Source = _constants.Null; + +public: + TLinkAddress Target = _constants.Null; + +public: + Link() noexcept = default; + +public: + Link(const Link&) noexcept = default; + +public: + Link(Link&&) noexcept = default; + +public: + auto& operator=(const Link& other) + { + Index = other.Index; + Source = other.Source; + Target = other.Target; + return *this; + } + +public: + bool operator==(const Link&) const noexcept = default; - public: bool operator==(const Link&) const noexcept = default; - - public: Link(TLinkAddress index, TLinkAddress source, TLinkAddress target) : Index(index), Source(source), Target(target) {} - - public: Link(std::convertible_to auto ...valuesPack) - { - constexpr auto length = sizeof...(valuesPack); - std::array values {static_cast(valuesPack)... }; - if constexpr(0 == length) - { - Index = _constants.Null; - Source = _constants.Null; - Target = _constants.Null; - } - else if constexpr(1 == length) - { - Index = values[0]; - Source = _constants.Null; - Target = _constants.Null; - } - else if constexpr(2 == length) - { - Index = values[0]; - Source = values[1]; - Target = _constants.Null; - } - else if constexpr(3 == length) - { - Index = values[0]; - Source = values[1]; - Target = values[2]; - } - else - { - throw std::invalid_argument("Link: too many values"); - } - } - - - public: Link(std::ranges::range auto&& range) +public: + Link(TLinkAddress index, TLinkAddress source, TLinkAddress target) : Index(index), Source(source), Target(target) {} + +public: + Link(std::convertible_to auto... valuesPack) + { + constexpr auto length = sizeof...(valuesPack); + std::array values{static_cast(valuesPack)...}; + if constexpr (0 == length) { - for (std::size_t i = 0; auto&& item : range | std::views::take(3)) - { - (*this)[i++] = item; // TODO: later later use std::forward - } + Index = _constants.Null; + Source = _constants.Null; + Target = _constants.Null; } - - public: operator std::vector () + else if constexpr (1 == length) { - return std::vector{Index, Source, Target}; + Index = values[0]; + Source = _constants.Null; + Target = _constants.Null; } - - public: bool IsNull() const noexcept + else if constexpr (2 == length) { - constexpr auto null = _constants.Null; - return *this == Link{null, null, null}; + Index = values[0]; + Source = values[1]; + Target = _constants.Null; } - - public: auto&& operator[](std::size_t index) const + else if constexpr (3 == length) + { + Index = values[0]; + Source = values[1]; + Target = values[2]; + } + else { - using namespace Platform::Ranges; // TODO: EnsureExtensions - switch (index) - { - case _constants.IndexPart: - return Index; - case _constants.SourcePart: - return Source; - case _constants.TargetPart: - return Target; - default: - throw std::out_of_range("Link index out of range"); - } + throw std::invalid_argument("Link: too many values"); } + } + - public: auto&& operator[](std::size_t index) +public: + Link(std::ranges::range auto&& range) + { + for (std::size_t i = 0; auto&& item : range | std::views::take(3)) { - using namespace Platform::Ranges; // TODO: EnsureExtensions - switch (index) - { - case _constants.IndexPart: - return Index; - case _constants.SourcePart: - return Source; - case _constants.TargetPart: - return Target; - default: - throw std::out_of_range("Link index out of range"); - } + (*this)[i++] = item; // TODO: later later use std::forward } + } +public: + operator std::vector() { return std::vector{Index, Source, Target}; } - public: std::size_t size() const noexcept +public: + bool IsNull() const noexcept + { + constexpr auto null = _constants.Null; + return *this == Link{null, null, null}; + } + +public: + auto&& operator[](std::size_t index) const + { + using namespace Platform::Ranges; // TODO: EnsureExtensions + switch (index) { - return Length; + case _constants.IndexPart: + return Index; + case _constants.SourcePart: + return Source; + case _constants.TargetPart: + return Target; + default: + throw std::out_of_range("Link index out of range"); } + } - public: bool empty() const noexcept { return 0 == size(); } +public: + auto&& operator[](std::size_t index) + { + using namespace Platform::Ranges; // TODO: EnsureExtensions + switch (index) + { + case _constants.IndexPart: + return Index; + case _constants.SourcePart: + return Source; + case _constants.TargetPart: + return Target; + default: + throw std::out_of_range("Link index out of range"); + } + } - // TODO: a little unsafe - public: auto begin() const noexcept { return &Index; } - public: auto end() const noexcept { return &Target + 1; } +public: + std::size_t size() const noexcept { return Length; } - public: explicit operator std::string() const { return Index == _constants.Null ? ToString(Source, Target) : ToString(Index, Source, Target); } +public: + bool empty() const noexcept { return 0 == size(); } - public: friend auto& operator<<(std::ostream& stream, const Link& self) { return stream << static_cast(self); } + // TODO: a little unsafe +public: + auto begin() const noexcept { return &Index; } - public: static std::string ToString(TLinkAddress index, TLinkAddress source, TLinkAddress target) { return std::string("(").append(Platform::Converters::To(index)).append(": ").append(Platform::Converters::To(source)).append("->").append(Platform::Converters::To(target)).append(1, ')'); } +public: + auto end() const noexcept { return &Target + 1; } - public: static std::string ToString(TLinkAddress source, TLinkAddress target) { return std::string("(").append(Platform::Converters::To(source)).append("->").append(Platform::Converters::To(target)).append(1, ')'); } - }; +public: + explicit operator std::string() const + { + return Index == _constants.Null ? ToString(Source, Target) : ToString(Index, Source, Target); + } + +public: + friend auto& operator<<(std::ostream& stream, const Link& self) + { + return stream << static_cast(self); + } + +public: + static std::string ToString(TLinkAddress index, TLinkAddress source, TLinkAddress target) + { + return std::string("(") + .append(Platform::Converters::To(index)) + .append(": ") + .append(Platform::Converters::To(source)) + .append("->") + .append(Platform::Converters::To(target)) + .append(1, ')'); + } + +public: + static std::string ToString(TLinkAddress source, TLinkAddress target) + { + return std::string("(") + .append(Platform::Converters::To(source)) + .append("->") + .append(Platform::Converters::To(target)) + .append(1, ')'); + } +}; - template - Link(Args...) -> Link>; +template +Link(Args...) -> Link>; - template - Link(Range) -> Link>; -} +template +Link(Range) -> Link>; +} // namespace Platform::Data::Doublets -template +template struct std::hash> { using Self = Platform::Data::Doublets::Link; diff --git a/cpp/Platform.Data.Doublets/LinkExtensions.h b/cpp/Platform.Data.Doublets/LinkExtensions.h index 330ebd03e..a818c9db3 100644 --- a/cpp/Platform.Data.Doublets/LinkExtensions.h +++ b/cpp/Platform.Data.Doublets/LinkExtensions.h @@ -1,9 +1,19 @@ namespace Platform::Data::Doublets { - class LinkExtensions +class LinkExtensions +{ +public: + template + static bool IsFullPoint(Link link) { - public: template static bool IsFullPoint(Link link) { return Point.IsFullPoint(link); } + return Point.IsFullPoint(link); + } - public: template static bool IsPartialPoint(Link link) { return Point.IsPartialPoint(link); } - }; -} +public: + template + static bool IsPartialPoint(Link link) + { + return Point.IsPartialPoint(link); + } +}; +} // namespace Platform::Data::Doublets diff --git a/cpp/Platform.Data.Doublets/LinksOptions.h b/cpp/Platform.Data.Doublets/LinksOptions.h index 0b2ce851d..05409c176 100644 --- a/cpp/Platform.Data.Doublets/LinksOptions.h +++ b/cpp/Platform.Data.Doublets/LinksOptions.h @@ -1,14 +1,18 @@ namespace Platform::Data::Doublets { - template VConstants = LinksConstants{true}, typename TLink = std::vector, typename TReadHandler = std::function)>, typename TWriteHandler = std::function> - struct LinksOptions : Platform::Data::LinksOptions - { - using base = Platform::Data::LinksOptions; - using base::LinkAddressType; - using base::Constants; - using base::LinkType; - using base::WriteHandlerType; - using base::ReadHandlerType; - }; -} +template VConstants = LinksConstants{true}, + typename TLink = std::vector, + typename TReadHandler = std::function)>, + typename TWriteHandler = std::function> +struct LinksOptions : Platform::Data::LinksOptions +{ + using base = Platform::Data::LinksOptions; + using base::Constants; + using base::LinkAddressType; + using base::LinkType; + using base::ReadHandlerType; + using base::WriteHandlerType; +}; +} // namespace Platform::Data::Doublets diff --git a/cpp/Platform.Data.Doublets/Memory/ILinksListMethods.h b/cpp/Platform.Data.Doublets/Memory/ILinksListMethods.h index d65c97a62..251207056 100644 --- a/cpp/Platform.Data.Doublets/Memory/ILinksListMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/ILinksListMethods.h @@ -1,16 +1,10 @@ namespace Platform::Data::Doublets::Memory { - template - struct ILinksListMethods - { - void Detach(TLinkAddress freeLink) - { - return this->object().Detach(freeLink); - }; +template +struct ILinksListMethods +{ + void Detach(TLinkAddress freeLink) { return this->object().Detach(freeLink); }; - void AttachAsFirst(TLinkAddress link) - { - return this->object().AttachAsFirst(link); - }; - }; -} + void AttachAsFirst(TLinkAddress link) { return this->object().AttachAsFirst(link); }; +}; +} // namespace Platform::Data::Doublets::Memory diff --git a/cpp/Platform.Data.Doublets/Memory/ILinksTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/ILinksTreeMethods.h index 0f893a461..628963402 100644 --- a/cpp/Platform.Data.Doublets/Memory/ILinksTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/ILinksTreeMethods.h @@ -1,36 +1,27 @@ namespace Platform::Data::Doublets::Memory { - template - struct ILinksTreeMethods - { - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; +template +struct ILinksTreeMethods +{ + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - LinkAddressType CountUsages(LinkAddressType root) - { - return this->object().CountUsages(root); - }; + LinkAddressType CountUsages(LinkAddressType root) { return this->object().CountUsages(root); }; - LinkAddressType Search(LinkAddressType source, LinkAddressType target) - { - return this->object().Search(source, target); - }; + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + return this->object().Search(source, target); + }; - LinkAddressType EachUsage(LinkAddressType root, const ReadHandlerType& handler) - { - return this->object().EachUsage(root, handler); - }; + LinkAddressType EachUsage(LinkAddressType root, const ReadHandlerType& handler) + { + return this->object().EachUsage(root, handler); + }; - void Detach(LinkAddressType& root, LinkAddressType linkIndex) - { - this->object().Detach(root, linkIndex); - }; + void Detach(LinkAddressType& root, LinkAddressType linkIndex) { this->object().Detach(root, linkIndex); }; - void Attach(LinkAddressType& root, LinkAddressType linkIndex) - { - this->object().Attach(root, linkIndex); - }; - }; -} + void Attach(LinkAddressType& root, LinkAddressType linkIndex) { this->object().Attach(root, linkIndex); }; +}; +} // namespace Platform::Data::Doublets::Memory diff --git a/cpp/Platform.Data.Doublets/Memory/IndexTreeType.h b/cpp/Platform.Data.Doublets/Memory/IndexTreeType.h index ad1802b44..6452cef7b 100644 --- a/cpp/Platform.Data.Doublets/Memory/IndexTreeType.h +++ b/cpp/Platform.Data.Doublets/Memory/IndexTreeType.h @@ -1,11 +1,11 @@ namespace Platform::Data::Doublets::Memory { - enum class IndexTreeType - { - // TODO: LolBalancedTreee changeBalancedTree namesBalancedTree - Default, - SizeBalancedTree, - RecursionlessSizeBalancedTree, - SizedAndThreadedAVLBalancedTree - }; +enum class IndexTreeType +{ + // TODO: LolBalancedTreee changeBalancedTree namesBalancedTree + Default, + SizeBalancedTree, + RecursionlessSizeBalancedTree, + SizedAndThreadedAVLBalancedTree +}; } diff --git a/cpp/Platform.Data.Doublets/Memory/LinksHeader.h b/cpp/Platform.Data.Doublets/Memory/LinksHeader.h index f78abfdaf..887e9f4c7 100644 --- a/cpp/Platform.Data.Doublets/Memory/LinksHeader.h +++ b/cpp/Platform.Data.Doublets/Memory/LinksHeader.h @@ -1,29 +1,29 @@ namespace Platform::Data::Doublets::Memory { - template - struct LinksHeader - { - TLinkAddress AllocatedLinks; +template +struct LinksHeader +{ + TLinkAddress AllocatedLinks; - TLinkAddress ReservedLinks; + TLinkAddress ReservedLinks; - TLinkAddress FreeLinks; + TLinkAddress FreeLinks; - TLinkAddress FirstFreeLink; + TLinkAddress FirstFreeLink; - TLinkAddress RootAsSource; + TLinkAddress RootAsSource; - TLinkAddress RootAsTarget; + TLinkAddress RootAsTarget; - TLinkAddress LastFreeLink; + TLinkAddress LastFreeLink; - TLinkAddress Reserved8; + TLinkAddress Reserved8; - constexpr bool operator==(const LinksHeader&) const noexcept = default; - }; -} + constexpr bool operator==(const LinksHeader&) const noexcept = default; +}; +} // namespace Platform::Data::Doublets::Memory -template +template struct std::hash> { using Self = Platform::Data::Doublets::Memory::LinksHeader; @@ -31,15 +31,7 @@ struct std::hash> auto operator()(const Self& self) const noexcept { using Platform::Hashing::Hash; - return Hash( - self.AllocatedLinks, - self.ReservedLinks, - self.FreeLinks, - self.FirstFreeLink, - self.RootAsSource, - self.RootAsTarget, - self.LastFreeLink, - self.Reserved8 - ); + return Hash(self.AllocatedLinks, self.ReservedLinks, self.FreeLinks, self.FirstFreeLink, self.RootAsSource, + self.RootAsTarget, self.LastFreeLink, self.Reserved8); } }; diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksRecursionlessSizeBalancedTreeMethodsBase.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksRecursionlessSizeBalancedTreeMethodsBase.h index cbdb6b709..97bec0093 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksRecursionlessSizeBalancedTreeMethodsBase.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksRecursionlessSizeBalancedTreeMethodsBase.h @@ -1,201 +1,241 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class ExternalLinksRecursionlessSizeBalancedTreeMethodsBase : public Platform::Collections::Methods::Trees::RecursionlessSizeBalancedTreeMethods/*, ILinksTreeMethods*/ +template +class ExternalLinksRecursionlessSizeBalancedTreeMethodsBase + : public Platform::Collections::Methods::Trees::RecursionlessSizeBalancedTreeMethods< + TSelf, + typename TLinksOptions::LinkAddressType> /*, ILinksTreeMethods*/ +{ +public: + using LinksOptionsType = TLinksOptions; + +public: + static constexpr auto Constants = LinksOptionsType::Constants; + +public: + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + +public: + static constexpr LinkAddressType Break = Constants.Break; + +public: + static constexpr LinkAddressType Continue = Constants.Continue; + +public: + std::byte* LinksDataParts; + +public: + std::byte* LinksIndexParts; + +public: + std::byte* Header; + +public: + ExternalLinksRecursionlessSizeBalancedTreeMethodsBase(std::byte* linksDataParts, std::byte* linksIndexParts, + std::byte* header) { - public: using LinksOptionsType = TLinksOptions; - public: static constexpr auto Constants = LinksOptionsType::Constants; - public: using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - public: static constexpr LinkAddressType Break = Constants.Break; - public: static constexpr LinkAddressType Continue = Constants.Continue; - public: std::byte* LinksDataParts; - public: std::byte* LinksIndexParts; - public: std::byte* Header; - - public: ExternalLinksRecursionlessSizeBalancedTreeMethodsBase(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) - { - LinksDataParts = linksDataParts; - LinksIndexParts = linksIndexParts; - Header = header; - } + LinksDataParts = linksDataParts; + LinksIndexParts = linksIndexParts; + Header = header; + } - public: LinkAddressType GetTreeRoot() - { - return this->object().GetTreeRoot(); - }; +public: + LinkAddressType GetTreeRoot() { return this->object().GetTreeRoot(); }; - public: LinkAddressType GetBasePartValue(LinkAddressType link) - { - return this->object().GetBasePartValue(link); - }; +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->object().GetBasePartValue(link); }; - public: bool FirstIsToTheRightOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, LinkAddressType rootTarget) - { - return this->object().FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget); - }; +public: + bool FirstIsToTheRightOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, + LinkAddressType rootTarget) + { + return this->object().FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget); + }; - public: bool FirstIsToTheLeftOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, LinkAddressType rootTarget) - { - return this->object().FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget); - }; +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, + LinkAddressType rootTarget) + { + return this->object().FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget); + }; - public: auto& GetHeaderReference() - { - return *reinterpret_cast*>(Header); - } +public: + auto& GetHeaderReference() { return *reinterpret_cast*>(Header); } - public: RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) { return *reinterpret_cast*>(LinksDataParts + (RawLinkDataPart::SizeInBytes * link)); } +public: + RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) + { + return *reinterpret_cast*>( + LinksDataParts + (RawLinkDataPart::SizeInBytes * link)); + } - public: RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) { return *reinterpret_cast*>(LinksIndexParts + (RawLinkIndexPart::SizeInBytes * link)); } +public: + RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) + { + return *reinterpret_cast*>( + LinksIndexParts + (RawLinkIndexPart::SizeInBytes * link)); + } - public: auto GetLinkValues(LinkAddressType linkIndex) - { - auto& link = GetLinkDataPartReference(linkIndex); - return LinkType{linkIndex, link.Source, link.Target}; - } +public: + auto GetLinkValues(LinkAddressType linkIndex) + { + auto& link = GetLinkDataPartReference(linkIndex); + return LinkType{linkIndex, link.Source, link.Target}; + } + +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkDataPartReference(first); + auto& secondLink = this->GetLinkDataPartReference(second); + return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) +public: + bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkDataPartReference(first); + auto& secondLink = this->GetLinkDataPartReference(second); + return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + secondLink.Target); + } + +public: + LinkAddressType operator[](LinkAddressType index) + { + auto root = GetTreeRoot(); + if (index >= this->object().GetSize(root)) { - auto& firstLink = this->GetLinkDataPartReference(first); - auto& secondLink = this->GetLinkDataPartReference(second); - return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + return 0; } - - public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + while (root != 0) { - auto& firstLink = this->GetLinkDataPartReference(first); - auto& secondLink = this->GetLinkDataPartReference(second); - return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + auto left = GetLeftOrDefault(root); + auto leftSize = GetSizeOrZero(left); + if (index < leftSize) + { + root = left; + continue; + } + if (AreEqual(index, leftSize)) + { + return root; + } + root = GetRightOrDefault(root); + index = index - (leftSize + 1); } + return 0; + } - public: LinkAddressType operator[](LinkAddressType index) +public: + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + auto root = this->GetTreeRoot(); + while (root != 0) { - auto root = GetTreeRoot(); - if (index >= this->object().GetSize(root)) - { - return 0; - } - while (root != 0) - { - auto left = GetLeftOrDefault(root); - auto leftSize = GetSizeOrZero(left); - if (index < leftSize) - { - root = left; - continue; - } - if (AreEqual(index, leftSize)) - { - return root; - } - root = GetRightOrDefault(root); - index = index - (leftSize + 1); - } - return 0; + auto& rootLink = this->GetLinkDataPartReference(root); + auto rootSource = rootLink.Source; + auto rootTarget = rootLink.Target; + if (this->FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget)) + { + root = this->GetLeftOrDefault(root); + } + else if (this->FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget)) + { + root = this->GetRightOrDefault(root); + } + else + { + return root; } + } + return 0; + } - public: LinkAddressType Search(LinkAddressType source, LinkAddressType target) +public: + LinkAddressType CountUsages(LinkAddressType link) + { + auto root = this->GetTreeRoot(); + auto total = this->object().GetSize(root); + auto totalRightIgnore = 0; + while (root != 0) { - auto root = this->GetTreeRoot(); - while (root != 0) + auto base = this->GetBasePartValue(root); + if (base <= link) { - auto& rootLink = this->GetLinkDataPartReference(root); - auto rootSource = rootLink.Source; - auto rootTarget = rootLink.Target; - if (this->FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget)) - { - root = this->GetLeftOrDefault(root); - } - else if (this->FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget)) - { - root = this->GetRightOrDefault(root); - } - else - { - return root; - } + root = this->GetRightOrDefault(root); + } + else + { + totalRightIgnore = totalRightIgnore + (this->GetRightSize(root) + 1); + root = this->GetLeftOrDefault(root); } - return 0; } - - public: LinkAddressType CountUsages(LinkAddressType link) + root = this->GetTreeRoot(); + auto totalLeftIgnore = 0; + while (root != 0) { - auto root = this->GetTreeRoot(); - auto total = this->object().GetSize(root); - auto totalRightIgnore = 0; - while (root != 0) + auto base = this->GetBasePartValue(root); + if (base >= link) { - auto base = this->GetBasePartValue(root); - if (base <= link) - { - root = this->GetRightOrDefault(root); - } - else - { - totalRightIgnore = totalRightIgnore + (this->GetRightSize(root) + 1); - root = this->GetLeftOrDefault(root); - } + root = this->GetLeftOrDefault(root); } - root = this->GetTreeRoot(); - auto totalLeftIgnore = 0; - while (root != 0) + else { - auto base = this->GetBasePartValue(root); - if (base >= link) - { - root = this->GetLeftOrDefault(root); - } - else - { - totalLeftIgnore = totalLeftIgnore + (this->GetLeftSize(root) + 1); - root = this->GetRightOrDefault(root); - } + totalLeftIgnore = totalLeftIgnore + (this->GetLeftSize(root) + 1); + root = this->GetRightOrDefault(root); } - return (total - totalRightIgnore) - totalLeftIgnore; } + return (total - totalRightIgnore) - totalLeftIgnore; + } - public: LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) { return this->EachUsageCore(base, this->GetTreeRoot(), handler); } +public: + LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) + { + return this->EachUsageCore(base, this->GetTreeRoot(), handler); + } - private: LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType link, const ReadHandlerType& handler) +private: + LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType link, const ReadHandlerType& handler) + { + if (link == 0) + { + return Continue; + } + auto linkBasePart = this->GetBasePartValue(link); + if (linkBasePart > (base)) + { + if ((this->EachUsageCore(base, this->GetLeftOrDefault(link), handler) == Break)) + { + return Break; + } + } + else if (linkBasePart < base) { - if (link == 0) + if ((this->EachUsageCore(base, this->GetRightOrDefault(link), handler) == Break)) { - return Continue; + return Break; } - auto linkBasePart = this->GetBasePartValue(link); - if (linkBasePart > (base)) + } + else + { + if (handler(this->GetLinkValues(link)) == Break) { - if ((this->EachUsageCore(base,this->GetLeftOrDefault(link), handler) == Break)) - { - return Break; - } + return Break; } - else if (linkBasePart < base) + if ((this->EachUsageCore(base, this->GetLeftOrDefault(link), handler) == Break)) { - if ((this->EachUsageCore(base,this->GetRightOrDefault(link), handler) == Break)) - { - return Break; - } + return Break; } - else + if ((this->EachUsageCore(base, this->GetRightOrDefault(link), handler) == Break)) { - if (handler(this->GetLinkValues(link)) == Break) - { - return Break; - } - if ((this->EachUsageCore(base,this->GetLeftOrDefault(link), handler) == Break)) - { - return Break; - } - if ((this->EachUsageCore(base,this->GetRightOrDefault(link), handler) == Break)) - { - return Break; - } + return Break; } - return Continue; } - }; -} + return Continue; + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSizeBalancedTreeMethodsBase.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSizeBalancedTreeMethodsBase.h index 392f0af2d..8548b3902 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSizeBalancedTreeMethodsBase.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSizeBalancedTreeMethodsBase.h @@ -1,221 +1,241 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class ExternalLinksSizeBalancedTreeMethodsBase : public Platform::Collections::Methods::Trees::SizeBalancedTreeMethods /* public ILinksTreeMethods, */ +template +class ExternalLinksSizeBalancedTreeMethodsBase + : public Platform::Collections::Methods::Trees::SizeBalancedTreeMethods< + TSelf, typename TLinksOptions::LinkAddressType> /* public ILinksTreeMethods, */ +{ +public: + using Polymorph::object; + using LinksOptionsType = TLinksOptions; + static constexpr auto Constants = LinksOptionsType::Constants; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + static constexpr LinkAddressType Break = Constants.Break; + static constexpr LinkAddressType Continue = Constants.Continue; + std::byte* LinksDataParts; + std::byte* LinksIndexParts; + std::byte* Header; + +public: + ExternalLinksSizeBalancedTreeMethodsBase(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) { - public: - using Polymorph::object; - using LinksOptionsType = TLinksOptions; - static constexpr auto Constants = LinksOptionsType::Constants; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - static constexpr LinkAddressType Break = Constants.Break; - static constexpr LinkAddressType Continue = Constants.Continue; - std::byte* LinksDataParts; - std::byte* LinksIndexParts; - std::byte* Header; - - public: ExternalLinksSizeBalancedTreeMethodsBase(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) - { - LinksDataParts = linksDataParts; - LinksIndexParts = linksIndexParts; - Header = header; - } + LinksDataParts = linksDataParts; + LinksIndexParts = linksIndexParts; + Header = header; + } - public: LinkAddressType GetTreeRoot() - { - return this->object().GetTreeRoot(); - }; +public: + LinkAddressType GetTreeRoot() { return this->object().GetTreeRoot(); }; - public: LinkAddressType GetBasePartValue(LinkAddressType link) - { - return this->object().GetBasePartValue(link); - }; +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->object().GetBasePartValue(link); }; - public: bool FirstIsToTheRightOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, LinkAddressType rootTarget) - { - return this->object().FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget); - }; +public: + bool FirstIsToTheRightOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, + LinkAddressType rootTarget) + { + return this->object().FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget); + }; - public: bool FirstIsToTheLeftOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, LinkAddressType rootTarget) - { - return this->object().FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget); - }; +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, + LinkAddressType rootTarget) + { + return this->object().FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget); + }; - public: auto&& GetHeaderReference() const - { - return *reinterpret_cast*>(Header); - } +public: + auto&& GetHeaderReference() const { return *reinterpret_cast*>(Header); } - public: const RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) const - { - return *reinterpret_cast*>(LinksDataParts + (RawLinkDataPart::SizeInBytes * (link))); - } +public: + const RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) const + { + return *reinterpret_cast*>( + LinksDataParts + (RawLinkDataPart::SizeInBytes * (link))); + } - public: RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) - { - return *reinterpret_cast*>(LinksDataParts + (RawLinkDataPart::SizeInBytes * (link))); - } +public: + RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) + { + return *reinterpret_cast*>( + LinksDataParts + (RawLinkDataPart::SizeInBytes * (link))); + } - public: const RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) const - { - return *reinterpret_cast*>(LinksIndexParts + (RawLinkIndexPart::SizeInBytes * (link))); - } +public: + const RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) const + { + return *reinterpret_cast*>( + LinksIndexParts + (RawLinkIndexPart::SizeInBytes * (link))); + } - public: RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) - { - return *reinterpret_cast*>(LinksIndexParts + (RawLinkIndexPart::SizeInBytes * (link))); - } +public: + RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) + { + return *reinterpret_cast*>( + LinksIndexParts + (RawLinkIndexPart::SizeInBytes * (link))); + } - public: auto GetLinkValues(LinkAddressType linkIndex) - { - auto& link = GetLinkDataPartReference(linkIndex); - return LinkType{linkIndex, link.Source, link.Target}; - } +public: + auto GetLinkValues(LinkAddressType linkIndex) + { + auto& link = GetLinkDataPartReference(linkIndex); + return LinkType{linkIndex, link.Source, link.Target}; + } + +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkDataPartReference(first); + auto& secondLink = this->GetLinkDataPartReference(second); + return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) +public: + bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkDataPartReference(first); + auto& secondLink = this->GetLinkDataPartReference(second); + return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + secondLink.Target); + } + +public: + LinkAddressType operator[](LinkAddressType index) + { + auto root = GetTreeRoot(); + if ((index >= this->object().GetSize(root))) { - auto& firstLink = this->GetLinkDataPartReference(first); - auto& secondLink = this->GetLinkDataPartReference(second); - return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + return 0; } - - public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + while (root != 0) { - auto& firstLink = this->GetLinkDataPartReference(first); - auto& secondLink = this->GetLinkDataPartReference(second); - return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + auto left = GetLeftOrDefault(root); + auto leftSize = GetSizeOrZero(left); + if ((index < leftSize)) + { + root = left; + continue; + } + if ((index == leftSize)) + { + return root; + } + root = GetRightOrDefault(root); + index = (index - (leftSize + 1)); } + return 0; + } - public: LinkAddressType operator[](LinkAddressType index) +public: + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + auto root = this->GetTreeRoot(); + while (root != 0) { - auto root = GetTreeRoot(); - if ((index >= this->object().GetSize(root))) + auto& rootLink = this->GetLinkDataPartReference(root); + auto rootSource = rootLink.Source; + auto rootTarget = rootLink.Target; + if (this->FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget)) { - return 0; + root = this->GetLeftOrDefault(root); } - while (root != 0) + else if (this->FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget)) { - auto left = GetLeftOrDefault(root); - auto leftSize = GetSizeOrZero(left); - if ((index < leftSize)) - { - root = left; - continue; - } - if ((index == leftSize)) - { - return root; - } - root = GetRightOrDefault(root); - index = (index - (leftSize + 1)); + root = this->GetRightOrDefault(root); + } + else + { + return root; } - return 0; - } + return 0; + } - public: LinkAddressType Search(LinkAddressType source, LinkAddressType target) +public: + LinkAddressType CountUsages(LinkAddressType link) + { + auto root = this->GetTreeRoot(); + auto total = this->object().GetSize(root); + auto totalRightIgnore = 0; + while (root != 0) { - auto root = this->GetTreeRoot(); - while (root != 0) + auto base = this->GetBasePartValue(root); + if (base <= link) { - auto& rootLink = this->GetLinkDataPartReference(root); - auto rootSource = rootLink.Source; - auto rootTarget = rootLink.Target; - if (this->FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget)) - { - root = this->GetLeftOrDefault(root); - } - else if (this->FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget)) - { - root = this->GetRightOrDefault(root); - } - else - { - return root; - } + root = this->GetRightOrDefault(root); + } + else + { + totalRightIgnore = totalRightIgnore + (this->GetRightSize(root) + 1); + root = this->GetLeftOrDefault(root); } - return 0; } - - public: LinkAddressType CountUsages(LinkAddressType link) + root = this->GetTreeRoot(); + auto totalLeftIgnore = 0; + while (root != 0) { - auto root = this->GetTreeRoot(); - auto total = this->object().GetSize(root); - auto totalRightIgnore = 0; - while (root != 0) + auto base = this->GetBasePartValue(root); + if (base >= link) { - auto base = this->GetBasePartValue(root); - if (base <= link) - { - root = this->GetRightOrDefault(root); - } - else - { - totalRightIgnore = totalRightIgnore + (this->GetRightSize(root) + 1); - root = this->GetLeftOrDefault(root); - } + root = this->GetLeftOrDefault(root); } - root = this->GetTreeRoot(); - auto totalLeftIgnore = 0; - while (root != 0) + else { - auto base = this->GetBasePartValue(root); - if (base >= link) - { - root = this->GetLeftOrDefault(root); - } - else - { - totalLeftIgnore = totalLeftIgnore + (this->GetLeftSize(root) + 1); - root = this->GetRightOrDefault(root); - } + totalLeftIgnore = totalLeftIgnore + (this->GetLeftSize(root) + 1); + root = this->GetRightOrDefault(root); } - return (total - totalRightIgnore) - totalLeftIgnore; } + return (total - totalRightIgnore) - totalLeftIgnore; + } - public: LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) { return this->EachUsageCore(base, this->GetTreeRoot(), handler); } +public: + LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) + { + return this->EachUsageCore(base, this->GetTreeRoot(), handler); + } - private: LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType link, const ReadHandlerType& handler) +private: + LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType link, const ReadHandlerType& handler) + { + if (link == 0) { - if (link == 0) + return Continue; + } + auto linkBasePart = this->GetBasePartValue(link); + if (linkBasePart > (base)) + { + if ((this->EachUsageCore(base, this->GetLeftOrDefault(link), handler) == Break)) { - return Continue; + return Break; } - auto linkBasePart = this->GetBasePartValue(link); - if (linkBasePart > (base)) + } + else if (linkBasePart < base) + { + if ((this->EachUsageCore(base, this->GetRightOrDefault(link), handler) == Break)) { - if ((this->EachUsageCore(base, this->GetLeftOrDefault(link), handler) == Break)) - { - return Break; - } + return Break; } - else if (linkBasePart < base) + } + else + { + if (handler(this->GetLinkValues(link)) == (Break)) { - if ((this->EachUsageCore(base, this->GetRightOrDefault(link), handler) == Break)) - { - return Break; - } + return Break; } - else + if ((this->EachUsageCore(base, this->GetLeftOrDefault(link), handler) == Break)) { - if (handler(this->GetLinkValues(link)) == (Break)) - { - return Break; - } - if ((this->EachUsageCore(base,this->GetLeftOrDefault(link), handler) == Break)) - { - return Break; - } - if ((this->EachUsageCore(base,this->GetRightOrDefault(link), handler) == Break)) - { - return Break; - } + return Break; + } + if ((this->EachUsageCore(base, this->GetRightOrDefault(link), handler) == Break)) + { + return Break; } - return Continue; } - }; -} + return Continue; + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods.h index 6c928ce19..5ac1e75fb 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods.h @@ -1,49 +1,100 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods : public ExternalLinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions> +template +class ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods + : public ExternalLinksRecursionlessSizeBalancedTreeMethodsBase< + ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, TLinksOptions> +{ + using base = ExternalLinksRecursionlessSizeBalancedTreeMethodsBase< + ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods, TLinksOptions>; + +public: + using LinksOptionsType = TLinksOptions; + +public: + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + +public: + static constexpr auto Constants = LinksOptionsType::Constants; + +public: + ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, + std::byte* header) + : base(linksDataParts, linksIndexParts, header) { - using base = ExternalLinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions>; - public: using LinksOptionsType = TLinksOptions; - public: using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - public: static constexpr auto Constants = LinksOptionsType::Constants; - public: ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) : base(linksDataParts, linksIndexParts, header) { } + } - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).LeftAsSource); } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).LeftAsSource); + } - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).RightAsSource); } +public: + LinkAddressType* GetRightReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).RightAsSource); + } - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsSource; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsSource; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsSource; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsSource; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkIndexPartReference(node).LeftAsSource = left; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) + { + this->GetLinkIndexPartReference(node).LeftAsSource = left; + } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkIndexPartReference(node).RightAsSource = right; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) + { + this->GetLinkIndexPartReference(node).RightAsSource = right; + } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsSource; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsSource; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkIndexPartReference(node).SizeAsSource = size; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) + { + this->GetLinkIndexPartReference(node).SizeAsSource = size; + } - public: LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsSource; } +public: + LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsSource; } - public: LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstSource < secondSource) || (firstSource == secondSource && (firstTarget < secondTarget)); } - using base::FirstIsToTheLeftOfSecond; +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstSource < secondSource) || (firstSource == secondSource && (firstTarget < secondTarget)); + } + using base::FirstIsToTheLeftOfSecond; - public: bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return firstSource > secondSource || (firstSource == secondSource && firstTarget > secondTarget); } - using base::FirstIsToTheRightOfSecond; +public: + bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return firstSource > secondSource || (firstSource == secondSource && firstTarget > secondTarget); + } + using base::FirstIsToTheRightOfSecond; - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkIndexPartReference(node); - link.LeftAsSource = 0; - link.RightAsSource = 0; - link.SizeAsSource = 0; - } - }; -} +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkIndexPartReference(node); + link.LeftAsSource = 0; + link.RightAsSource = 0; + link.SizeAsSource = 0; + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSourcesSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSourcesSizeBalancedTreeMethods.h index 3dbc710f6..fd5652dc4 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSourcesSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksSourcesSizeBalancedTreeMethods.h @@ -1,50 +1,95 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class ExternalLinksSourcesSizeBalancedTreeMethods : public ExternalLinksSizeBalancedTreeMethodsBase, TLinksOptions> +template +class ExternalLinksSourcesSizeBalancedTreeMethods + : public ExternalLinksSizeBalancedTreeMethodsBase, + TLinksOptions> +{ +public: + using base = ExternalLinksSizeBalancedTreeMethodsBase, + TLinksOptions>; + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + static constexpr auto Constants = LinksOptionsType::Constants; + +public: + ExternalLinksSourcesSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, + std::byte* header) + : base(linksDataParts, linksIndexParts, header) { - public: - using base = ExternalLinksSizeBalancedTreeMethodsBase, TLinksOptions>; - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - static constexpr auto Constants = LinksOptionsType::Constants; - public: ExternalLinksSourcesSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) : base(linksDataParts, linksIndexParts, header) { } + } - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).LeftAsSource); } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).LeftAsSource); + } - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).RightAsSource); } +public: + LinkAddressType* GetRightReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).RightAsSource); + } - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsSource; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsSource; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsSource; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsSource; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkIndexPartReference(node).LeftAsSource = left; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) + { + this->GetLinkIndexPartReference(node).LeftAsSource = left; + } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkIndexPartReference(node).RightAsSource = right; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) + { + this->GetLinkIndexPartReference(node).RightAsSource = right; + } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsSource; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsSource; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkIndexPartReference(node).SizeAsSource = size; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) + { + this->GetLinkIndexPartReference(node).SizeAsSource = size; + } - public: LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsSource; } +public: + LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsSource; } - public: LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstSource < secondSource) || (firstSource == secondSource && (firstTarget < secondTarget)); } - using base::FirstIsToTheLeftOfSecond; +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstSource < secondSource) || (firstSource == secondSource && (firstTarget < secondTarget)); + } + using base::FirstIsToTheLeftOfSecond; - public: bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return firstSource > secondSource || (firstSource == secondSource && firstTarget > secondTarget); } - using base::FirstIsToTheRightOfSecond; +public: + bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return firstSource > secondSource || (firstSource == secondSource && firstTarget > secondTarget); + } + using base::FirstIsToTheRightOfSecond; - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkIndexPartReference(node); - link.LeftAsSource = 0; - link.RightAsSource = 0; - link.SizeAsSource = 0; - } - }; -} +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkIndexPartReference(node); + link.LeftAsSource = 0; + link.RightAsSource = 0; + link.SizeAsSource = 0; + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods.h index 7beb0fdf7..3866ae865 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods.h @@ -1,49 +1,97 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods : public ExternalLinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions> +template +class ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods + : public ExternalLinksRecursionlessSizeBalancedTreeMethodsBase< + ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, TLinksOptions> +{ +public: + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + +public: + static constexpr auto Constants = LinksOptionsType::Constants; + using base = ExternalLinksRecursionlessSizeBalancedTreeMethodsBase< + ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods, TLinksOptions>; + +public: + ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, + std::byte* header) + : base(linksDataParts, linksIndexParts, header) { - public: using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - public: static constexpr auto Constants = LinksOptionsType::Constants; - using base = ExternalLinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions>; - public: ExternalLinksTargetsRecursionlessSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) : base(linksDataParts, linksIndexParts, header) { } + } - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).LeftAsTarget); } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).LeftAsTarget); + } - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).RightAsTarget); } +public: + LinkAddressType* GetRightReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).RightAsTarget); + } - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsTarget; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsTarget; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsTarget; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsTarget; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkIndexPartReference(node).LeftAsTarget = left; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) + { + this->GetLinkIndexPartReference(node).LeftAsTarget = left; + } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkIndexPartReference(node).RightAsTarget = right; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) + { + this->GetLinkIndexPartReference(node).RightAsTarget = right; + } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsTarget; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsTarget; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkIndexPartReference(node).SizeAsTarget = size; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) + { + this->GetLinkIndexPartReference(node).SizeAsTarget = size; + } - public: LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsTarget; } +public: + LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsTarget; } - public: LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstTarget < secondTarget) || (firstTarget == secondTarget && (firstSource < secondSource)); } - using base::FirstIsToTheLeftOfSecond; +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstTarget < secondTarget) || (firstTarget == secondTarget && (firstSource < secondSource)); + } + using base::FirstIsToTheLeftOfSecond; - public: bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstTarget > secondTarget) || (firstTarget == secondTarget && (firstSource > secondSource)); } - using base::FirstIsToTheRightOfSecond; +public: + bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstTarget > secondTarget) || (firstTarget == secondTarget && (firstSource > secondSource)); + } + using base::FirstIsToTheRightOfSecond; - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkIndexPartReference(node); - link.LeftAsTarget = 0; - link.RightAsTarget = 0; - link.SizeAsTarget = 0; - } - }; -} +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkIndexPartReference(node); + link.LeftAsTarget = 0; + link.RightAsTarget = 0; + link.SizeAsTarget = 0; + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksTargetsSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksTargetsSizeBalancedTreeMethods.h index 6088a2fd9..27743680c 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksTargetsSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/ExternalLinksTargetsSizeBalancedTreeMethods.h @@ -1,46 +1,91 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class ExternalLinksTargetsSizeBalancedTreeMethods : public ExternalLinksSizeBalancedTreeMethodsBase, TLinksOptions> +template +class ExternalLinksTargetsSizeBalancedTreeMethods + : public ExternalLinksSizeBalancedTreeMethodsBase, + TLinksOptions> +{ +public: + using LinksOptionsType = TLinksOptions; + using LinkAddressType = TLinksOptions::LinkAddressType; + using base = ExternalLinksSizeBalancedTreeMethodsBase, + TLinksOptions>; + +public: + ExternalLinksTargetsSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, + std::byte* header) + : base(linksDataParts, linksIndexParts, header) { - public: - using LinksOptionsType = TLinksOptions; - using LinkAddressType = TLinksOptions::LinkAddressType; - using base = ExternalLinksSizeBalancedTreeMethodsBase, TLinksOptions>; - public: ExternalLinksTargetsSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) : base(linksDataParts, linksIndexParts, header) { } + } - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).LeftAsTarget); } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).LeftAsTarget); + } - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).RightAsTarget); } +public: + LinkAddressType* GetRightReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).RightAsTarget); + } - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsTarget; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsTarget; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsTarget; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsTarget; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkIndexPartReference(node).LeftAsTarget = left; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) + { + this->GetLinkIndexPartReference(node).LeftAsTarget = left; + } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkIndexPartReference(node).RightAsTarget = right; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) + { + this->GetLinkIndexPartReference(node).RightAsTarget = right; + } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsTarget; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsTarget; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkIndexPartReference(node).SizeAsTarget = size; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) + { + this->GetLinkIndexPartReference(node).SizeAsTarget = size; + } - public: LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsTarget; } +public: + LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsTarget; } - public: LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstTarget < secondTarget) || (firstTarget == secondTarget && (firstSource< secondSource)); } - using base::FirstIsToTheLeftOfSecond; +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstTarget < secondTarget) || (firstTarget == secondTarget && (firstSource < secondSource)); + } + using base::FirstIsToTheLeftOfSecond; - public: bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return firstTarget > secondTarget || (firstTarget == secondTarget && firstSource > secondSource); } - using base::FirstIsToTheRightOfSecond; +public: + bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return firstTarget > secondTarget || (firstTarget == secondTarget && firstSource > secondSource); + } + using base::FirstIsToTheRightOfSecond; - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkIndexPartReference(node); - link.LeftAsTarget = 0; - link.RightAsTarget = 0; - link.SizeAsTarget = 0; - } - }; -} +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkIndexPartReference(node); + link.LeftAsTarget = 0; + link.RightAsTarget = 0; + link.SizeAsTarget = 0; + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksRecursionlessSizeBalancedTreeMethodsBase.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksRecursionlessSizeBalancedTreeMethodsBase.h index a69b1458f..f0a468a63 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksRecursionlessSizeBalancedTreeMethodsBase.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksRecursionlessSizeBalancedTreeMethodsBase.h @@ -1,132 +1,169 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class InternalLinksRecursionlessSizeBalancedTreeMethodsBase : public Platform::Collections::Methods::Trees::RecursionlessSizeBalancedTreeMethods /* public ILinksTreeMethods, */ - { - public: - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - public: static constexpr auto Constants = LinksOptionsType::Constants; - public: static constexpr LinkAddressType Break = Constants.Break; - public: static constexpr LinkAddressType Continue = Constants.Continue; - public: std::byte* LinksDataParts; - public: std::byte* LinksIndexParts; - public: std::byte* Header; - - public: InternalLinksRecursionlessSizeBalancedTreeMethodsBase(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) - { - LinksDataParts = linksDataParts; - LinksIndexParts = linksIndexParts; - Header = header; - } +template +class InternalLinksRecursionlessSizeBalancedTreeMethodsBase + : public Platform::Collections::Methods::Trees::RecursionlessSizeBalancedTreeMethods< + TSelf, typename TLinksOptions::LinkAddressType> /* public ILinksTreeMethods, */ +{ +public: + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - public: LinkAddressType GetTreeRoot(LinkAddressType linkAddress) - { - return this->object().GetTreeRoot(linkAddress); - }; +public: + static constexpr auto Constants = LinksOptionsType::Constants; - public: LinkAddressType GetBasePartValue(LinkAddressType link) - { - return this->object().GetBasePartValue(link); - }; +public: + static constexpr LinkAddressType Break = Constants.Break; - public: LinkAddressType GetKeyPartValue(LinkAddressType link) - { - return this->object().GetKeyPartValue(link); - }; +public: + static constexpr LinkAddressType Continue = Constants.Continue; - public: RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) { return *reinterpret_cast*>(LinksDataParts + (RawLinkDataPart::SizeInBytes * (link))); } +public: + std::byte* LinksDataParts; - public: RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) { return *reinterpret_cast*>(LinksIndexParts + (RawLinkIndexPart::SizeInBytes * (link))); } +public: + std::byte* LinksIndexParts; - public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) { return this->GetKeyPartValue(first) < this->GetKeyPartValue(second); } +public: + std::byte* Header; - public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) { return this->GetKeyPartValue(first) > this->GetKeyPartValue(second); } +public: + InternalLinksRecursionlessSizeBalancedTreeMethodsBase(std::byte* linksDataParts, std::byte* linksIndexParts, + std::byte* header) + { + LinksDataParts = linksDataParts; + LinksIndexParts = linksIndexParts; + Header = header; + } - public: CArray auto GetLinkValues(LinkAddressType linkIndex) - { - auto& link = GetLinkDataPartReference(linkIndex); - return LinkType{linkIndex, link.Source, link.Target}; - } +public: + LinkAddressType GetTreeRoot(LinkAddressType linkAddress) { return this->object().GetTreeRoot(linkAddress); }; -// public: LinkAddressType operator[](LinkAddressType link, LinkAddressType index) -// { -// auto root = GetTreeRoot(*link); -// if (index >= GetSize(root)) -// { -// return 0; -// } -// while (root != 0) -// { -// auto left = GetLeftOrDefault(root); -// auto leftSize = GetSizeOrZero(left); -// if (index < leftSize) -// { -// root = left; -// Continue; -// } -// if (index == leftSize) -// { -// return root; -// } -// root = GetRightOrDefault(root); -// index = index - (leftSize + 1)); -// } -// return 0; -// } - - public: LinkAddressType Search(LinkAddressType source, LinkAddressType target) - { - return this->object().Search(source, target); - }; +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->object().GetBasePartValue(link); }; - public: LinkAddressType SearchCore(LinkAddressType root, LinkAddressType key) - { - while (root != 0) - { - auto rootKey = this->GetKeyPartValue(root); - if (key < rootKey) - { - root = this->GetLeftOrDefault(root); - } - else if (key > rootKey) - { - root = this->GetRightOrDefault(root); - } - else - { - return root; - } - } - return 0; - } +public: + LinkAddressType GetKeyPartValue(LinkAddressType link) { return this->object().GetKeyPartValue(link); }; + +public: + RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) + { + return *reinterpret_cast*>( + LinksDataParts + (RawLinkDataPart::SizeInBytes * (link))); + } + +public: + RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) + { + return *reinterpret_cast*>( + LinksIndexParts + (RawLinkIndexPart::SizeInBytes * (link))); + } + +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + { + return this->GetKeyPartValue(first) < this->GetKeyPartValue(second); + } + +public: + bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + { + return this->GetKeyPartValue(first) > this->GetKeyPartValue(second); + } - public: LinkAddressType CountUsages(LinkAddressType link) { return this->GetSizeOrZero(this->GetTreeRoot(link)); } +public: + CArray auto GetLinkValues(LinkAddressType linkIndex) + { + auto& link = GetLinkDataPartReference(linkIndex); + return LinkType{linkIndex, link.Source, link.Target}; + } - public: LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) { return this->EachUsageCore(base, this->GetTreeRoot(base), handler); } + // public: LinkAddressType operator[](LinkAddressType link, LinkAddressType index) + // { + // auto root = GetTreeRoot(*link); + // if (index >= GetSize(root)) + // { + // return 0; + // } + // while (root != 0) + // { + // auto left = GetLeftOrDefault(root); + // auto leftSize = GetSizeOrZero(left); + // if (index < leftSize) + // { + // root = left; + // Continue; + // } + // if (index == leftSize) + // { + // return root; + // } + // root = GetRightOrDefault(root); + // index = index - (leftSize + 1)); + // } + // return 0; + // } - private: LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType link, const ReadHandlerType& handler) +public: + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + return this->object().Search(source, target); + }; + +public: + LinkAddressType SearchCore(LinkAddressType root, LinkAddressType key) + { + while (root != 0) { - if (link == 0) + auto rootKey = this->GetKeyPartValue(root); + if (key < rootKey) { - return Continue; + root = this->GetLeftOrDefault(root); } - if ((this->EachUsageCore(base,this->GetLeftOrDefault(link), handler) == Break)) + else if (key > rootKey) { - return Break; + root = this->GetRightOrDefault(root); } - if (handler(this->GetLinkValues(link)) == (Break)) + else { - return Break; - } - if ((this->EachUsageCore(base,this->GetRightOrDefault(link), handler) == Break)) - { - return Break; + return root; } + } + return 0; + } + +public: + LinkAddressType CountUsages(LinkAddressType link) { return this->GetSizeOrZero(this->GetTreeRoot(link)); } + +public: + LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) + { + return this->EachUsageCore(base, this->GetTreeRoot(base), handler); + } + +private: + LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType link, const ReadHandlerType& handler) + { + if (link == 0) + { return Continue; } - }; -} + if ((this->EachUsageCore(base, this->GetLeftOrDefault(link), handler) == Break)) + { + return Break; + } + if (handler(this->GetLinkValues(link)) == (Break)) + { + return Break; + } + if ((this->EachUsageCore(base, this->GetRightOrDefault(link), handler) == Break)) + { + return Break; + } + return Continue; + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSizeBalancedTreeMethodsBase.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSizeBalancedTreeMethodsBase.h index cb5a64377..77a3887e9 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSizeBalancedTreeMethodsBase.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSizeBalancedTreeMethodsBase.h @@ -1,147 +1,181 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class InternalLinksSizeBalancedTreeMethodsBase : public Platform::Collections::Methods::Trees::SizeBalancedTreeMethods /* public ILinksTreeMethods, */ - { - using LinksOptionsType = TLinksOptions; - public: static constexpr auto Constants = LinksOptionsType::Constants; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - public: static constexpr LinkAddressType Break = Constants.Break; - public: static constexpr LinkAddressType Continue = Constants.Continue; - public: std::byte* LinksDataParts; - public: std::byte* LinksIndexParts; - public: std::byte* Header; - - public: InternalLinksSizeBalancedTreeMethodsBase(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) - { - LinksDataParts = linksDataParts; - LinksIndexParts = linksIndexParts; - Header = header; - } +template +class InternalLinksSizeBalancedTreeMethodsBase + : public Platform::Collections::Methods::Trees::SizeBalancedTreeMethods< + TSelf, typename TLinksOptions::LinkAddressType> /* public ILinksTreeMethods, */ +{ + using LinksOptionsType = TLinksOptions; - public: LinkAddressType GetTreeRoot(LinkAddressType link) - { - return this->object().GetTreeRoot(link); - }; +public: + static constexpr auto Constants = LinksOptionsType::Constants; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - public: LinkAddressType GetBasePartValue(LinkAddressType link) - { - return this->object().GetBasePartValue(link); - }; +public: + static constexpr LinkAddressType Break = Constants.Break; - public: LinkAddressType GetKeyPartValue(LinkAddressType link) - { - return this->object().GetKeyPartValue(link); - }; +public: + static constexpr LinkAddressType Continue = Constants.Continue; - public: const RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) const - { - return *reinterpret_cast*>(LinksDataParts + (RawLinkDataPart::SizeInBytes * link)); - } +public: + std::byte* LinksDataParts; - public: RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) - { - return *reinterpret_cast*>(LinksDataParts + (RawLinkDataPart::SizeInBytes * link)); - } +public: + std::byte* LinksIndexParts; - public: const RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) const - { - return *reinterpret_cast*>(LinksIndexParts + (RawLinkIndexPart::SizeInBytes * link)); - } +public: + std::byte* Header; - public: RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) - { - return *reinterpret_cast*>(LinksIndexParts + (RawLinkIndexPart::SizeInBytes * link)); - } +public: + InternalLinksSizeBalancedTreeMethodsBase(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) + { + LinksDataParts = linksDataParts; + LinksIndexParts = linksIndexParts; + Header = header; + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) { return this->GetKeyPartValue(first) < this->GetKeyPartValue(second); } +public: + LinkAddressType GetTreeRoot(LinkAddressType link) { return this->object().GetTreeRoot(link); }; - public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) { return this->GetKeyPartValue(first) > this->GetKeyPartValue(second); } +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->object().GetBasePartValue(link); }; - public: auto GetLinkValues(LinkAddressType linkIndex) - { - auto& link = GetLinkDataPartReference(linkIndex); - return LinkType{linkIndex, link.Source, link.Target}; - } +public: + LinkAddressType GetKeyPartValue(LinkAddressType link) { return this->object().GetKeyPartValue(link); }; -// public: LinkAddressType operator[](LinkAddressType link, LinkAddressType index) -// { -// auto root = GetTreeRoot(*link); -// if (index >= GetSize(root)) -// { -// return 0; -// } -// while (root != 0) -// { -// auto left = GetLeftOrDefault(root); -// auto leftSize = GetSizeOrZero(left); -// if (index < leftSize) -// { -// root = left; -// continue; -// } -// if (index == leftSize) -// { -// return root; -// } -// root = GetRightOrDefault(root); -// index = index - (leftbSize + 1); -// } -// return 0; -// } - - public: LinkAddressType Search(LinkAddressType source, LinkAddressType target) - { - return this->object().Search(source, target); - }; - - public: LinkAddressType SearchCore(LinkAddressType root, LinkAddressType key) - { - while (root != 0) - { - auto rootKey = this->GetKeyPartValue(root); - if (key < rootKey) - { - root = this->GetLeftOrDefault(root); - } - else if (key > rootKey) - { - root = this->GetRightOrDefault(root); - } - else - { - return root; - } - } - return 0; - } +public: + const RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) const + { + return *reinterpret_cast*>( + LinksDataParts + (RawLinkDataPart::SizeInBytes * link)); + } + +public: + RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) + { + return *reinterpret_cast*>( + LinksDataParts + (RawLinkDataPart::SizeInBytes * link)); + } + +public: + const RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) const + { + return *reinterpret_cast*>( + LinksIndexParts + (RawLinkIndexPart::SizeInBytes * link)); + } - public: LinkAddressType CountUsages(LinkAddressType link) { return this->GetSizeOrZero(this->GetTreeRoot(link)); } +public: + RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) + { + return *reinterpret_cast*>( + LinksIndexParts + (RawLinkIndexPart::SizeInBytes * link)); + } - public: LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) { return this->EachUsageCore(base, this->GetTreeRoot(base), handler); } +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + { + return this->GetKeyPartValue(first) < this->GetKeyPartValue(second); + } + +public: + bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + { + return this->GetKeyPartValue(first) > this->GetKeyPartValue(second); + } - private: LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType link, const ReadHandlerType& handler) +public: + auto GetLinkValues(LinkAddressType linkIndex) + { + auto& link = GetLinkDataPartReference(linkIndex); + return LinkType{linkIndex, link.Source, link.Target}; + } + + // public: LinkAddressType operator[](LinkAddressType link, LinkAddressType index) + // { + // auto root = GetTreeRoot(*link); + // if (index >= GetSize(root)) + // { + // return 0; + // } + // while (root != 0) + // { + // auto left = GetLeftOrDefault(root); + // auto leftSize = GetSizeOrZero(left); + // if (index < leftSize) + // { + // root = left; + // continue; + // } + // if (index == leftSize) + // { + // return root; + // } + // root = GetRightOrDefault(root); + // index = index - (leftbSize + 1); + // } + // return 0; + // } + +public: + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + return this->object().Search(source, target); + }; + +public: + LinkAddressType SearchCore(LinkAddressType root, LinkAddressType key) + { + while (root != 0) { - if (link == 0) - { - return Continue; - } - if ((this->EachUsageCore(base,this->GetLeftOrDefault(link), handler) == Break)) + auto rootKey = this->GetKeyPartValue(root); + if (key < rootKey) { - return Break; + root = this->GetLeftOrDefault(root); } - if (handler(this->GetLinkValues(link)) == (Break)) + else if (key > rootKey) { - return Break; + root = this->GetRightOrDefault(root); } - if ((this->EachUsageCore(base,this->GetRightOrDefault(link), handler) == Break)) + else { - return Break; + return root; } + } + return 0; + } + +public: + LinkAddressType CountUsages(LinkAddressType link) { return this->GetSizeOrZero(this->GetTreeRoot(link)); } + +public: + LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) + { + return this->EachUsageCore(base, this->GetTreeRoot(base), handler); + } + +private: + LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType link, const ReadHandlerType& handler) + { + if (link == 0) + { return Continue; } - }; -} + if ((this->EachUsageCore(base, this->GetLeftOrDefault(link), handler) == Break)) + { + return Break; + } + if (handler(this->GetLinkValues(link)) == (Break)) + { + return Break; + } + if ((this->EachUsageCore(base, this->GetRightOrDefault(link), handler) == Break)) + { + return Break; + } + return Continue; + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesLinkedListMethods.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesLinkedListMethods.h index d1a5c7f00..c540287f8 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesLinkedListMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesLinkedListMethods.h @@ -1,129 +1,147 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class InternalLinksSourcesLinkedListMethods : public Platform::Collections::Methods::Lists::RelativeCircularDoublyLinkedListMethods, typename TLinksOptions::LinkAddressType> +template +class InternalLinksSourcesLinkedListMethods + : public Platform::Collections::Methods::Lists::RelativeCircularDoublyLinkedListMethods< + InternalLinksSourcesLinkedListMethods, typename TLinksOptions::LinkAddressType> +{ +public: + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + +public: + static constexpr auto Constants = LinksOptionsType::Constants; + +private: + std::byte* _linksDataParts; + std::byte* _linksIndexParts; + +public: + LinkAddressType Break = Constants.Break; + LinkAddressType Continue = Constants.Continue; + +public: + InternalLinksSourcesLinkedListMethods(std::byte* linksDataParts, std::byte* linksIndexParts) { - public: using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - public: static constexpr auto Constants = LinksOptionsType::Constants; - private: - std::byte* _linksDataParts; - std::byte* _linksIndexParts; - public: - LinkAddressType Break = Constants.Break; - LinkAddressType Continue = Constants.Continue; - - public: InternalLinksSourcesLinkedListMethods(std::byte* linksDataParts, std::byte* linksIndexParts) - { - _linksDataParts = linksDataParts; - _linksIndexParts = linksIndexParts; - } + _linksDataParts = linksDataParts; + _linksIndexParts = linksIndexParts; + } - public: const RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) const - { - return *reinterpret_cast*>(_linksDataParts + (RawLinkDataPart::SizeInBytes * link)); - } +public: + const RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) const + { + return *reinterpret_cast*>( + _linksDataParts + (RawLinkDataPart::SizeInBytes * link)); + } - public: RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) - { - return *reinterpret_cast*>(_linksDataParts + (RawLinkDataPart::SizeInBytes * link)); - } +public: + RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) + { + return *reinterpret_cast*>( + _linksDataParts + (RawLinkDataPart::SizeInBytes * link)); + } - public: const RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) const - { - return *reinterpret_cast*>(_linksDataParts + (RawLinkIndexPart::SizeInBytes * link)); - } +public: + const RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) const + { + return *reinterpret_cast*>( + _linksDataParts + (RawLinkIndexPart::SizeInBytes * link)); + } - public: RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) - { - return *reinterpret_cast*>(_linksDataParts + (RawLinkIndexPart::SizeInBytes * link)); - } +public: + RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType link) + { + return *reinterpret_cast*>( + _linksDataParts + (RawLinkIndexPart::SizeInBytes * link)); + } - public: LinkAddressType GetFirst(LinkAddressType head) - { - return this->GetLinkIndexPartReference(head).RootAsSource; - } +public: + LinkAddressType GetFirst(LinkAddressType head) { return this->GetLinkIndexPartReference(head).RootAsSource; } - public: LinkAddressType GetLast(LinkAddressType head) +public: + LinkAddressType GetLast(LinkAddressType head) + { + auto first = this->GetLinkIndexPartReference(head).RootAsSource; + if (0 == first) { - auto first = this->GetLinkIndexPartReference(head).RootAsSource; - if (0 == first) - { - return first; - } - else - { - return this->GetPrevious(first); - } + return first; } - - public: LinkAddressType GetPrevious(LinkAddressType element) + else { - return this->GetLinkIndexPartReference(element).LeftAsSource; + return this->GetPrevious(first); } + } - public: LinkAddressType GetNext(LinkAddressType element) - { - return this->GetLinkIndexPartReference(element).RightAsSource; - } +public: + LinkAddressType GetPrevious(LinkAddressType element) + { + return this->GetLinkIndexPartReference(element).LeftAsSource; + } - public: LinkAddressType GetSize(LinkAddressType head) - { - return this->GetLinkIndexPartReference(head).SizeAsSource; - } +public: + LinkAddressType GetNext(LinkAddressType element) { return this->GetLinkIndexPartReference(element).RightAsSource; } - public: void SetFirst(LinkAddressType head, LinkAddressType element) - { - this->GetLinkIndexPartReference(head).RootAsSource = element; - } +public: + LinkAddressType GetSize(LinkAddressType head) { return this->GetLinkIndexPartReference(head).SizeAsSource; } - public: void SetLast(LinkAddressType head, LinkAddressType element) - { - } +public: + void SetFirst(LinkAddressType head, LinkAddressType element) + { + this->GetLinkIndexPartReference(head).RootAsSource = element; + } - public: void SetPrevious(LinkAddressType element, LinkAddressType previous) - { - this->GetLinkIndexPartReference(element).LeftAsSource = previous; - } +public: + void SetLast(LinkAddressType head, LinkAddressType element) {} - public: void SetNext(LinkAddressType element, LinkAddressType next) - { - this->GetLinkIndexPartReference(element).RightAsSource = next; - } +public: + void SetPrevious(LinkAddressType element, LinkAddressType previous) + { + this->GetLinkIndexPartReference(element).LeftAsSource = previous; + } - public: void SetSize(LinkAddressType head, LinkAddressType size) - { - this->GetLinkIndexPartReference(head).SizeAsSource = size; - } +public: + void SetNext(LinkAddressType element, LinkAddressType next) + { + this->GetLinkIndexPartReference(element).RightAsSource = next; + } - public: LinkAddressType CountUsages(LinkAddressType head) { return this->GetSize(head); } +public: + void SetSize(LinkAddressType head, LinkAddressType size) + { + this->GetLinkIndexPartReference(head).SizeAsSource = size; + } - public: Interfaces::CArray auto GetLinkValues(LinkAddressType linkIndex) - { - auto& link = this->GetLinkDataPartReference(linkIndex); - return Link{ linkIndex, link.Source, link.Target }; - } +public: + LinkAddressType CountUsages(LinkAddressType head) { return this->GetSize(head); } + +public: + Interfaces::CArray auto GetLinkValues(LinkAddressType linkIndex) + { + auto& link = this->GetLinkDataPartReference(linkIndex); + return Link{linkIndex, link.Source, link.Target}; + } - public: LinkAddressType EachUsage(LinkAddressType source, const ReadHandlerType& handler) +public: + LinkAddressType EachUsage(LinkAddressType source, const ReadHandlerType& handler) + { + auto current = this->GetFirst(source); + auto first = current; + while (current != 0) { - auto current = this->GetFirst(source); - auto first = current; - while (current != 0) + if (handler(this->GetLinkValues(current)) == (Break)) + { + return Break; + } + current = this->GetNext(current); + if (current == first) { - if (handler(this->GetLinkValues(current)) == (Break)) - { - return Break; - } - current = this->GetNext(current); - if (current == first) - { - return Continue; - } + return Continue; } - return Continue; } - }; -} + return Continue; + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesRecursionlessSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesRecursionlessSizeBalancedTreeMethods.h index 9f466f4fc..bea55810a 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesRecursionlessSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesRecursionlessSizeBalancedTreeMethods.h @@ -1,48 +1,88 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class InternalLinksSourcesRecursionlessSizeBalancedTreeMethods : public InternalLinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions> +template +class InternalLinksSourcesRecursionlessSizeBalancedTreeMethods + : public InternalLinksRecursionlessSizeBalancedTreeMethodsBase< + InternalLinksSourcesRecursionlessSizeBalancedTreeMethods, TLinksOptions> +{ +public: + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + static constexpr auto Constants = LinksOptionsType::Constants; + using base = InternalLinksRecursionlessSizeBalancedTreeMethodsBase< + InternalLinksSourcesRecursionlessSizeBalancedTreeMethods, TLinksOptions>; + +public: + InternalLinksSourcesRecursionlessSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, + std::byte* header) + : base(linksDataParts, linksIndexParts, header) { - public: - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - static constexpr auto Constants = LinksOptionsType::Constants; - using base = InternalLinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions>; - public: InternalLinksSourcesRecursionlessSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) : base(linksDataParts, linksIndexParts, header) { } + } - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).LeftAsSource); } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).LeftAsSource); + } - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).RightAsSource); } +public: + LinkAddressType* GetRightReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).RightAsSource); + } - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsSource; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsSource; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsSource; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsSource; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkIndexPartReference(node).LeftAsSource = left; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) + { + this->GetLinkIndexPartReference(node).LeftAsSource = left; + } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkIndexPartReference(node).RightAsSource = right; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) + { + this->GetLinkIndexPartReference(node).RightAsSource = right; + } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsSource; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsSource; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkIndexPartReference(node).SizeAsSource = size; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) + { + this->GetLinkIndexPartReference(node).SizeAsSource = size; + } - public: LinkAddressType GetTreeRoot(LinkAddressType link) { return this->GetLinkIndexPartReference(link).RootAsSource; } +public: + LinkAddressType GetTreeRoot(LinkAddressType link) { return this->GetLinkIndexPartReference(link).RootAsSource; } - public: LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } - public: LinkAddressType GetKeyPartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } +public: + LinkAddressType GetKeyPartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkIndexPartReference(node); - link.LeftAsSource = 0; - link.RightAsSource = 0; - link.SizeAsSource = 0; - } +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkIndexPartReference(node); + link.LeftAsSource = 0; + link.RightAsSource = 0; + link.SizeAsSource = 0; + } - public: LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return this->SearchCore(this->GetTreeRoot(source), target); } - }; -} +public: + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + return this->SearchCore(this->GetTreeRoot(source), target); + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesSizeBalancedTreeMethods.h index 9e9bcd022..2b7b6d571 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksSourcesSizeBalancedTreeMethods.h @@ -1,48 +1,88 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class InternalLinksSourcesSizeBalancedTreeMethods : public InternalLinksSizeBalancedTreeMethodsBase, TLinksOptions> +template +class InternalLinksSourcesSizeBalancedTreeMethods + : public InternalLinksSizeBalancedTreeMethodsBase, + TLinksOptions> +{ +public: + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + static constexpr auto Constants = LinksOptionsType::Constants; + using base = InternalLinksSizeBalancedTreeMethodsBase, + TLinksOptions>; + +public: + InternalLinksSourcesSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, + std::byte* header) + : base(linksDataParts, linksIndexParts, header) { - public: - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - static constexpr auto Constants = LinksOptionsType::Constants; - using base = InternalLinksSizeBalancedTreeMethodsBase, TLinksOptions>; - public: InternalLinksSourcesSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) : base(linksDataParts, linksIndexParts, header) { } + } - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).LeftAsSource); } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).LeftAsSource); + } - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).RightAsSource); } +public: + LinkAddressType* GetRightReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).RightAsSource); + } - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsSource; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsSource; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsSource; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsSource; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkIndexPartReference(node).LeftAsSource = left; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) + { + this->GetLinkIndexPartReference(node).LeftAsSource = left; + } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkIndexPartReference(node).RightAsSource = right; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) + { + this->GetLinkIndexPartReference(node).RightAsSource = right; + } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsSource; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsSource; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkIndexPartReference(node).SizeAsSource = size; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) + { + this->GetLinkIndexPartReference(node).SizeAsSource = size; + } - public: LinkAddressType GetTreeRoot(LinkAddressType link) { return this->GetLinkIndexPartReference(link).RootAsSource; } +public: + LinkAddressType GetTreeRoot(LinkAddressType link) { return this->GetLinkIndexPartReference(link).RootAsSource; } - public: LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } - public: LinkAddressType GetKeyPartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } +public: + LinkAddressType GetKeyPartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkIndexPartReference(node); - link.LeftAsSource = 0; - link.RightAsSource = 0; - link.SizeAsSource = 0; - } +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkIndexPartReference(node); + link.LeftAsSource = 0; + link.RightAsSource = 0; + link.SizeAsSource = 0; + } - public: LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return this->SearchCore(this->GetTreeRoot(source), target); } - }; -} +public: + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + return this->SearchCore(this->GetTreeRoot(source), target); + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksTargetsRecursionlessSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksTargetsRecursionlessSizeBalancedTreeMethods.h index 045c8ef41..4a3f5904a 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksTargetsRecursionlessSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksTargetsRecursionlessSizeBalancedTreeMethods.h @@ -1,48 +1,90 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class InternalLinksTargetsRecursionlessSizeBalancedTreeMethods : public InternalLinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions> +template +class InternalLinksTargetsRecursionlessSizeBalancedTreeMethods + : public InternalLinksRecursionlessSizeBalancedTreeMethodsBase< + InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, TLinksOptions> +{ +public: + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + +public: + static constexpr auto Constants = LinksOptionsType::Constants; + using base = InternalLinksRecursionlessSizeBalancedTreeMethodsBase< + InternalLinksTargetsRecursionlessSizeBalancedTreeMethods, TLinksOptions>; + +public: + InternalLinksTargetsRecursionlessSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, + std::byte* header) + : base(linksDataParts, linksIndexParts, header) { - public: - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - public: static constexpr auto Constants = LinksOptionsType::Constants; - using base = InternalLinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions>; - public: InternalLinksTargetsRecursionlessSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) : base(linksDataParts, linksIndexParts, header) { } + } - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).LeftAsTarget); } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).LeftAsTarget); + } - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).RightAsTarget); } +public: + LinkAddressType* GetRightReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).RightAsTarget); + } - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsTarget; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsTarget; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsTarget; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsTarget; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkIndexPartReference(node).LeftAsTarget = left; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) + { + this->GetLinkIndexPartReference(node).LeftAsTarget = left; + } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkIndexPartReference(node).RightAsTarget = right; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) + { + this->GetLinkIndexPartReference(node).RightAsTarget = right; + } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsTarget; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsTarget; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkIndexPartReference(node).SizeAsTarget = size; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) + { + this->GetLinkIndexPartReference(node).SizeAsTarget = size; + } - public: LinkAddressType GetTreeRoot(LinkAddressType link) { return this->GetLinkIndexPartReference(link).RootAsTarget; } +public: + LinkAddressType GetTreeRoot(LinkAddressType link) { return this->GetLinkIndexPartReference(link).RootAsTarget; } - public: LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } - public: LinkAddressType GetKeyPartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } +public: + LinkAddressType GetKeyPartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkIndexPartReference(node); - link.LeftAsTarget = 0; - link.RightAsTarget = 0; - link.SizeAsTarget = 0; - } +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkIndexPartReference(node); + link.LeftAsTarget = 0; + link.RightAsTarget = 0; + link.SizeAsTarget = 0; + } - public: LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return this->SearchCore(this->GetTreeRoot(target), source); } - }; -} +public: + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + return this->SearchCore(this->GetTreeRoot(target), source); + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksTargetsSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksTargetsSizeBalancedTreeMethods.h index e64e6e491..9ddb62642 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksTargetsSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/InternalLinksTargetsSizeBalancedTreeMethods.h @@ -1,48 +1,90 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class InternalLinksTargetsSizeBalancedTreeMethods : public InternalLinksSizeBalancedTreeMethodsBase, TLinksOptions> +template +class InternalLinksTargetsSizeBalancedTreeMethods + : public InternalLinksSizeBalancedTreeMethodsBase, + TLinksOptions> +{ +public: + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + +public: + static constexpr auto Constants = LinksOptionsType::Constants; + using base = InternalLinksSizeBalancedTreeMethodsBase, + TLinksOptions>; + +public: + InternalLinksTargetsSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, + std::byte* header) + : base(linksDataParts, linksIndexParts, header) { - public: - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - public: static constexpr auto Constants = LinksOptionsType::Constants; - using base = InternalLinksSizeBalancedTreeMethodsBase, TLinksOptions>; - public: InternalLinksTargetsSizeBalancedTreeMethods(std::byte* linksDataParts, std::byte* linksIndexParts, std::byte* header) : base(linksDataParts, linksIndexParts, header) { } + } - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).LeftAsTarget); } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).LeftAsTarget); + } - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &(this->GetLinkIndexPartReference(node).RightAsTarget); } +public: + LinkAddressType* GetRightReference(LinkAddressType node) + { + return &(this->GetLinkIndexPartReference(node).RightAsTarget); + } - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsTarget; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkIndexPartReference(node).LeftAsTarget; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsTarget; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkIndexPartReference(node).RightAsTarget; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkIndexPartReference(node).LeftAsTarget = left; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) + { + this->GetLinkIndexPartReference(node).LeftAsTarget = left; + } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkIndexPartReference(node).RightAsTarget = right; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) + { + this->GetLinkIndexPartReference(node).RightAsTarget = right; + } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsTarget; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkIndexPartReference(node).SizeAsTarget; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkIndexPartReference(node).SizeAsTarget = size; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) + { + this->GetLinkIndexPartReference(node).SizeAsTarget = size; + } - public: LinkAddressType GetTreeRoot(LinkAddressType link) { return this->GetLinkIndexPartReference(link).RootAsTarget; } +public: + LinkAddressType GetTreeRoot(LinkAddressType link) { return this->GetLinkIndexPartReference(link).RootAsTarget; } - public: LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } +public: + LinkAddressType GetBasePartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Target; } - public: LinkAddressType GetKeyPartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } +public: + LinkAddressType GetKeyPartValue(LinkAddressType link) { return this->GetLinkDataPartReference(link).Source; } - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkIndexPartReference(node); - link.LeftAsTarget = 0; - link.RightAsTarget = 0; - link.SizeAsTarget = 0; - } +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkIndexPartReference(node); + link.LeftAsTarget = 0; + link.RightAsTarget = 0; + link.SizeAsTarget = 0; + } - public: LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return this->SearchCore(this->GetTreeRoot(target), source); } - }; -} +public: + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + return this->SearchCore(this->GetTreeRoot(target), source); + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinks.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinks.h index bfe03a7a6..49240ed75 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinks.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinks.h @@ -1,19 +1,30 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template< - typename TLinksOptions, - typename TMemory = Platform::Memory::FileMappedResizableDirectMemory, - typename TInternalSourcesTreeMethods = InternalLinksSourcesSizeBalancedTreeMethods, - typename TInternalLinksSourcesLinkedListMethods = InternalLinksSourcesLinkedListMethods, - typename TInternalTargetsTreeMethods = InternalLinksTargetsSizeBalancedTreeMethods, - typename TExternalSourcesTreeMethods = ExternalLinksSourcesSizeBalancedTreeMethods, - typename TExternalTargetsTreeMethods = ExternalLinksTargetsSizeBalancedTreeMethods, - typename TUnusedLinksListMethods = UnusedLinksListMethods, - typename... TBase> - struct SplitMemoryLinks : public SplitMemoryLinksBase, TLinksOptions, TMemory, TInternalSourcesTreeMethods, TInternalLinksSourcesLinkedListMethods, TInternalTargetsTreeMethods, TExternalSourcesTreeMethods, TExternalTargetsTreeMethods, TUnusedLinksListMethods, TBase...> - { - using base = SplitMemoryLinksBase, TLinksOptions, TMemory, TInternalSourcesTreeMethods, TInternalLinksSourcesLinkedListMethods, TInternalTargetsTreeMethods, TExternalSourcesTreeMethods, TExternalTargetsTreeMethods, TUnusedLinksListMethods, TBase...>; - public: - using base::base; - }; -} +template , + typename TInternalLinksSourcesLinkedListMethods = InternalLinksSourcesLinkedListMethods, + typename TInternalTargetsTreeMethods = InternalLinksTargetsSizeBalancedTreeMethods, + typename TExternalSourcesTreeMethods = ExternalLinksSourcesSizeBalancedTreeMethods, + typename TExternalTargetsTreeMethods = ExternalLinksTargetsSizeBalancedTreeMethods, + typename TUnusedLinksListMethods = UnusedLinksListMethods, typename... TBase> +struct SplitMemoryLinks + : public SplitMemoryLinksBase< + SplitMemoryLinks, + TLinksOptions, TMemory, TInternalSourcesTreeMethods, TInternalLinksSourcesLinkedListMethods, + TInternalTargetsTreeMethods, TExternalSourcesTreeMethods, TExternalTargetsTreeMethods, + TUnusedLinksListMethods, TBase...> +{ + using base = SplitMemoryLinksBase< + SplitMemoryLinks, + TLinksOptions, TMemory, TInternalSourcesTreeMethods, TInternalLinksSourcesLinkedListMethods, + TInternalTargetsTreeMethods, TExternalSourcesTreeMethods, TExternalTargetsTreeMethods, TUnusedLinksListMethods, + TBase...>; + +public: + using base::base; +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.h index c180989c5..a06a7cc78 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/SplitMemoryLinksBase.h @@ -1,290 +1,291 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template< - typename TSelf, - typename TLinksOptions, - typename TMemory, - typename TInternalSourcesTreeMethods, - typename TInternalLinksSourcesLinkedListMethods, - typename TInternalTargetsTreeMethods, - typename TExternalSourcesTreeMethods, - typename TExternalTargetsTreeMethods, - typename TUnusedLinksListMethods, - typename... TBase> - struct SplitMemoryLinksBase : public Interfaces::Polymorph +template +struct SplitMemoryLinksBase : public Interfaces::Polymorph +{ +public: + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + static constexpr LinksConstants Constants = LinksOptionsType::Constants; + static constexpr bool UseLinkedList = false; + +public: + TMemory _dataMemory; + TMemory _indexMemory; + std::uint64_t _dataMemoryReservationStepInBytes; + std::uint64_t _indexMemoryReservationStepInBytes; + TInternalSourcesTreeMethods* InternalSourcesTreeMethods; + TInternalLinksSourcesLinkedListMethods* InternalSourcesListMethods; + TInternalTargetsTreeMethods* InternalTargetsTreeMethods; + TExternalSourcesTreeMethods* ExternalSourcesTreeMethods; + TExternalTargetsTreeMethods* ExternalTargetsTreeMethods; + TUnusedLinksListMethods* UnusedLinksListMethods; + std::byte* _header; + std::byte* _linksDataParts; + std::byte* _linksIndexParts; + +public: + const RawLinkDataPart& GetLinkDataPartReference(LinkAddressType linkIndex) const + { + return *(reinterpret_cast*>(_linksDataParts + + (LinkDataPartSizeInBytes * linkIndex))); + } + + RawLinkDataPart& GetLinkDataPartReference(LinkAddressType linkIndex) + { + return *(reinterpret_cast*>(_linksDataParts + + (LinkDataPartSizeInBytes * linkIndex))); + } + + const RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType linkIndex) const { - public: - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - static constexpr LinksConstants Constants = LinksOptionsType::Constants; - static constexpr bool UseLinkedList = false; - public: - TMemory _dataMemory; - TMemory _indexMemory; - std::uint64_t _dataMemoryReservationStepInBytes; - std::uint64_t _indexMemoryReservationStepInBytes; - TInternalSourcesTreeMethods* InternalSourcesTreeMethods; - TInternalLinksSourcesLinkedListMethods* InternalSourcesListMethods; - TInternalTargetsTreeMethods* InternalTargetsTreeMethods; - TExternalSourcesTreeMethods* ExternalSourcesTreeMethods; - TExternalTargetsTreeMethods* ExternalTargetsTreeMethods; - TUnusedLinksListMethods* UnusedLinksListMethods; - std::byte* _header; - std::byte* _linksDataParts; - std::byte* _linksIndexParts; + return *(reinterpret_cast*>(_linksIndexParts + + (LinkIndexPartSizeInBytes * linkIndex))); + } - public: - const RawLinkDataPart& GetLinkDataPartReference(LinkAddressType linkIndex) const + RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType linkIndex) + { + return *(reinterpret_cast*>(_linksIndexParts + + (LinkIndexPartSizeInBytes * linkIndex))); + } + +public: + const LinksHeader& GetHeaderReference() const + { + return *reinterpret_cast*>(_header); + } + + LinksHeader& GetHeaderReference() + { + return *reinterpret_cast*>(_header); + } + + LinkAddressType Total() const + { + return this->GetHeaderReference().AllocatedLinks - this->GetHeaderReference().FreeLinks; + } + +public: + static constexpr std::size_t LinkDataPartSizeInBytes = sizeof(RawLinkDataPart); + + static constexpr std::size_t LinkIndexPartSizeInBytes = sizeof(RawLinkIndexPart); + + static constexpr std::size_t LinkHeaderSizeInBytes = sizeof(LinksHeader); + + static constexpr std::size_t DefaultLinksSizeStep = 1 * 1024 * 1024; + + SplitMemoryLinksBase(TMemory&& dataMemory, TMemory&& indexMemory) + : SplitMemoryLinksBase(std::move(dataMemory), std::move(indexMemory), DefaultLinksSizeStep) + { + } + + SplitMemoryLinksBase(TMemory&& dataMemory, TMemory&& indexMemory, std::uint64_t memoryReservationStep) + : _dataMemory{std::move(dataMemory)}, + _indexMemory{std::move(indexMemory)}, + _dataMemoryReservationStepInBytes{memoryReservationStep * LinkDataPartSizeInBytes}, + _indexMemoryReservationStepInBytes{memoryReservationStep * LinkIndexPartSizeInBytes} + { + + Init(_dataMemory, _indexMemory); + } + + void Init(TMemory& dataMemory, TMemory& indexMemory) + { + if (indexMemory.ReservedCapacity() < LinkHeaderSizeInBytes) { - return *(reinterpret_cast*>(_linksDataParts + (LinkDataPartSizeInBytes * linkIndex))); + indexMemory.ReservedCapacity(LinkHeaderSizeInBytes); } - - RawLinkDataPart& GetLinkDataPartReference(LinkAddressType linkIndex) + SetPointers(dataMemory, indexMemory); + auto allocatedLinks{this->GetHeaderReference().AllocatedLinks}; + auto minimumDataReservedCapacity = allocatedLinks * LinkDataPartSizeInBytes; + if (minimumDataReservedCapacity < dataMemory.UsedCapacity()) { - return *(reinterpret_cast*>(_linksDataParts + (LinkDataPartSizeInBytes * linkIndex))); + minimumDataReservedCapacity = dataMemory.UsedCapacity(); } - - const RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType linkIndex) const + if (minimumDataReservedCapacity < _dataMemoryReservationStepInBytes) { - return *(reinterpret_cast*>(_linksIndexParts + (LinkIndexPartSizeInBytes * linkIndex))); + minimumDataReservedCapacity = _dataMemoryReservationStepInBytes; } - - RawLinkIndexPart& GetLinkIndexPartReference(LinkAddressType linkIndex) + auto minimumIndexReservedCapacity = allocatedLinks * LinkDataPartSizeInBytes; + if (minimumIndexReservedCapacity < indexMemory.UsedCapacity()) { - return *(reinterpret_cast*>(_linksIndexParts + (LinkIndexPartSizeInBytes * linkIndex))); + minimumIndexReservedCapacity = indexMemory.UsedCapacity(); } - - public: - - const LinksHeader& GetHeaderReference() const + if (minimumIndexReservedCapacity < _indexMemoryReservationStepInBytes) { - return *reinterpret_cast*>(_header); + minimumIndexReservedCapacity = _indexMemoryReservationStepInBytes; } - - LinksHeader& GetHeaderReference() + // Check for alignment + if (minimumDataReservedCapacity % _dataMemoryReservationStepInBytes > 0) { - return *reinterpret_cast*>(_header); + minimumDataReservedCapacity = ((minimumDataReservedCapacity / _dataMemoryReservationStepInBytes) * + _dataMemoryReservationStepInBytes) + + _dataMemoryReservationStepInBytes; } - - LinkAddressType Total() const + if (minimumIndexReservedCapacity % _indexMemoryReservationStepInBytes > 0) { - return this->GetHeaderReference().AllocatedLinks - this->GetHeaderReference().FreeLinks; + minimumIndexReservedCapacity = ((minimumIndexReservedCapacity / _indexMemoryReservationStepInBytes) * + _indexMemoryReservationStepInBytes) + + _indexMemoryReservationStepInBytes; } - - public: - static constexpr std::size_t LinkDataPartSizeInBytes = sizeof(RawLinkDataPart); - - static constexpr std::size_t LinkIndexPartSizeInBytes = sizeof(RawLinkIndexPart); - - static constexpr std::size_t LinkHeaderSizeInBytes = sizeof(LinksHeader); - - static constexpr std::size_t DefaultLinksSizeStep = 1 * 1024 * 1024; - - SplitMemoryLinksBase(TMemory&& dataMemory, TMemory&& indexMemory) : SplitMemoryLinksBase(std::move(dataMemory), std::move(indexMemory), DefaultLinksSizeStep) + if (dataMemory.ReservedCapacity() != minimumDataReservedCapacity) { + dataMemory.ReservedCapacity(minimumDataReservedCapacity); } - - SplitMemoryLinksBase(TMemory&& dataMemory, TMemory&& indexMemory, std::uint64_t memoryReservationStep) : _dataMemory{ std::move(dataMemory) }, _indexMemory{ std::move(indexMemory) }, _dataMemoryReservationStepInBytes{ memoryReservationStep * LinkDataPartSizeInBytes }, _indexMemoryReservationStepInBytes{ memoryReservationStep * LinkIndexPartSizeInBytes } + if (indexMemory.ReservedCapacity() != minimumIndexReservedCapacity) { - - Init(_dataMemory, _indexMemory); + indexMemory.ReservedCapacity(minimumIndexReservedCapacity); } + SetPointers(dataMemory, indexMemory); + this->GetHeaderReference() = this->GetHeaderReference(); + // Ensure correctness _memory.UsedCapacity over _header->AllocatedLinks + dataMemory.UsedCapacity((this->GetHeaderReference().AllocatedLinks * LinkDataPartSizeInBytes) + + LinkDataPartSizeInBytes); // First link is read only zero link. + indexMemory.UsedCapacity((this->GetHeaderReference().AllocatedLinks * LinkIndexPartSizeInBytes) + + LinkHeaderSizeInBytes); + // Ensure correctness _memory.ReservedLinks over _header->ReservedCapacity + this->GetHeaderReference().ReservedLinks = + (dataMemory.ReservedCapacity() - LinkDataPartSizeInBytes) / LinkDataPartSizeInBytes; + } - void Init(TMemory& dataMemory, TMemory& indexMemory) + LinkAddressType Count(const LinkType& restriction) const + { + if (std::ranges::size(restriction) == 0) { - if(indexMemory.ReservedCapacity() < LinkHeaderSizeInBytes) - { - indexMemory.ReservedCapacity(LinkHeaderSizeInBytes); - } - SetPointers(dataMemory, indexMemory); - auto allocatedLinks { this->GetHeaderReference().AllocatedLinks }; - auto minimumDataReservedCapacity = allocatedLinks * LinkDataPartSizeInBytes; - if (minimumDataReservedCapacity < dataMemory.UsedCapacity()) - { - minimumDataReservedCapacity = dataMemory.UsedCapacity(); - } - if (minimumDataReservedCapacity < _dataMemoryReservationStepInBytes) - { - minimumDataReservedCapacity = _dataMemoryReservationStepInBytes; - } - auto minimumIndexReservedCapacity = allocatedLinks * LinkDataPartSizeInBytes; - if (minimumIndexReservedCapacity < indexMemory.UsedCapacity()) - { - minimumIndexReservedCapacity = indexMemory.UsedCapacity(); - } - if (minimumIndexReservedCapacity < _indexMemoryReservationStepInBytes) - { - minimumIndexReservedCapacity = _indexMemoryReservationStepInBytes; - } - // Check for alignment - if (minimumDataReservedCapacity % _dataMemoryReservationStepInBytes > 0) - { - minimumDataReservedCapacity = ((minimumDataReservedCapacity / _dataMemoryReservationStepInBytes) * _dataMemoryReservationStepInBytes) + _dataMemoryReservationStepInBytes; - } - if (minimumIndexReservedCapacity % _indexMemoryReservationStepInBytes > 0) - { - minimumIndexReservedCapacity = ((minimumIndexReservedCapacity / _indexMemoryReservationStepInBytes) * _indexMemoryReservationStepInBytes) + _indexMemoryReservationStepInBytes; - } - if (dataMemory.ReservedCapacity() != minimumDataReservedCapacity) - { - dataMemory.ReservedCapacity(minimumDataReservedCapacity); - } - if (indexMemory.ReservedCapacity() != minimumIndexReservedCapacity) - { - indexMemory.ReservedCapacity(minimumIndexReservedCapacity); - } - SetPointers(dataMemory, indexMemory); - this->GetHeaderReference() = this->GetHeaderReference(); - // Ensure correctness _memory.UsedCapacity over _header->AllocatedLinks - dataMemory.UsedCapacity((this->GetHeaderReference().AllocatedLinks * LinkDataPartSizeInBytes) + LinkDataPartSizeInBytes); // First link is read only zero link. - indexMemory.UsedCapacity((this->GetHeaderReference().AllocatedLinks * LinkIndexPartSizeInBytes) + LinkHeaderSizeInBytes); - // Ensure correctness _memory.ReservedLinks over _header->ReservedCapacity - this->GetHeaderReference().ReservedLinks = (dataMemory.ReservedCapacity() - LinkDataPartSizeInBytes) / LinkDataPartSizeInBytes; + return this->Total(); } - - LinkAddressType Count(const LinkType& restriction) const + auto index = GetIndex(*this, restriction); + auto any = Constants.Any; + if (std::ranges::size(restriction) == 1) { - if (std::ranges::size(restriction) == 0) + if (index == any) { return this->Total(); } - auto index = GetIndex(*this, restriction); - auto any = Constants.Any; - if (std::ranges::size(restriction) == 1) + return this->Exists(index) ? LinkAddressType{1} : LinkAddressType{0}; + } + if (std::ranges::size(restriction) == 2) + { + auto value = restriction[1]; + if (index == any) { - if (index == any) + if (value == any) { - return this->Total(); + return this->Total(); // Any - как отсутствие ограничения } - return this->Exists(index) ? LinkAddressType{1} : LinkAddressType{0}; - } - if (std::ranges::size(restriction) == 2) - { - auto value = restriction[1]; - if (index == any) + auto externalReferencesRange = Constants.ExternalReferencesRange; + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(value)) { - if (value == any) - { - return this->Total(); // Any - как отсутствие ограничения - } - auto externalReferencesRange = Constants.ExternalReferencesRange; - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(value)) + return ExternalSourcesTreeMethods->CountUsages(value) + + ExternalTargetsTreeMethods->CountUsages(value); + } + else + { + if (UseLinkedList) { - return ExternalSourcesTreeMethods->CountUsages(value) + ExternalTargetsTreeMethods->CountUsages(value); + return InternalSourcesListMethods->CountUsages(value) + + InternalTargetsTreeMethods->CountUsages(value); } else { - if (UseLinkedList) - { - return InternalSourcesListMethods->CountUsages(value) + InternalTargetsTreeMethods->CountUsages(value); - } - else - { - return InternalSourcesTreeMethods->CountUsages(value) + InternalTargetsTreeMethods->CountUsages(value); - } + return InternalSourcesTreeMethods->CountUsages(value) + + InternalTargetsTreeMethods->CountUsages(value); } } - else + } + else + { + if (!this->Exists(index)) { - if (!this->Exists(index)) - { - return LinkAddressType{0}; - } - if (value == any) + return LinkAddressType{0}; + } + if (value == any) + { + return LinkAddressType{1}; + } + auto& storedLinkValue = this->GetLinkDataPartReference(index); + if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) + { + return LinkAddressType{1}; + } + return LinkAddressType{0}; + } + } + if (std::ranges::size(restriction) == 3) + { + auto externalReferencesRange = Constants.ExternalReferencesRange; + auto source = GetSource(*this, restriction); + auto target = GetTarget(*this, restriction); + if (index == any) + { + if ((source == any) && (target == any)) + { + return this->Total(); + } + else if ((source == any)) + { + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(target)) { - return LinkAddressType{1}; + return ExternalTargetsTreeMethods->CountUsages(target); } - auto& storedLinkValue = this->GetLinkDataPartReference(index); - if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) + else { - return LinkAddressType{1}; + return InternalTargetsTreeMethods->CountUsages(target); } - return LinkAddressType{0}; } - } - if (std::ranges::size(restriction) == 3) - { - auto externalReferencesRange = Constants.ExternalReferencesRange; - auto source = GetSource(*this, restriction); - auto target = GetTarget(*this, restriction); - if (index == any) + else if ((target == any)) { - if ((source == any) && (target == any)) + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(source)) { - return this->Total(); + return ExternalSourcesTreeMethods->CountUsages(source); } - else if ((source == any)) + else { - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(target)) + if (UseLinkedList) { - return ExternalTargetsTreeMethods->CountUsages(target); + return InternalSourcesTreeMethods->CountUsages(source); } else { - return InternalTargetsTreeMethods->CountUsages(target); + return InternalSourcesTreeMethods->CountUsages(source); } } - else if ((target == any)) + } + else // if(source != Any && target != Any) + { + // Эквивалент Exists(source, target) => Count(Any, source, target) > 0 + LinkAddressType linkAddress; + if (Constants.IsExternalReferencesRangeEnabled) { - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(source)) + if (externalReferencesRange.Contains(source) && externalReferencesRange.Contains(target)) { - return ExternalSourcesTreeMethods->CountUsages(source); + linkAddress = ExternalSourcesTreeMethods->Search(source, target); } - else + else if (externalReferencesRange.Contains(source)) { - if (UseLinkedList) - { - return InternalSourcesTreeMethods->CountUsages(source); - } - else - { - return InternalSourcesTreeMethods->CountUsages(source); - } + linkAddress = InternalTargetsTreeMethods->Search(source, target); } - } - else //if(source != Any && target != Any) - { - // Эквивалент Exists(source, target) => Count(Any, source, target) > 0 - LinkAddressType linkAddress; - if (Constants.IsExternalReferencesRangeEnabled) + else if (externalReferencesRange.Contains(target)) { - if (externalReferencesRange.Contains(source) && externalReferencesRange.Contains(target)) + if (UseLinkedList) { linkAddress = ExternalSourcesTreeMethods->Search(source, target); } - else if (externalReferencesRange.Contains(source)) - { - linkAddress = InternalTargetsTreeMethods->Search(source, target); - } - else if (externalReferencesRange.Contains(target)) - { - if (UseLinkedList) - { - linkAddress = ExternalSourcesTreeMethods->Search(source, target); - } - else - { - linkAddress = InternalSourcesTreeMethods->Search(source, target); - } - } else { - if (UseLinkedList || InternalSourcesTreeMethods->CountUsages(source) > InternalTargetsTreeMethods->CountUsages(target)) - { - linkAddress = InternalTargetsTreeMethods->Search(source, target); - } - else - { - linkAddress = InternalSourcesTreeMethods->Search(source, target); - } + linkAddress = InternalSourcesTreeMethods->Search(source, target); } } else { - if (UseLinkedList || InternalSourcesTreeMethods->CountUsages(source) > InternalTargetsTreeMethods->CountUsages(target)) + if (UseLinkedList || InternalSourcesTreeMethods->CountUsages(source) > + InternalTargetsTreeMethods->CountUsages(target)) { linkAddress = InternalTargetsTreeMethods->Search(source, target); } @@ -293,211 +294,217 @@ namespace Platform::Data::Doublets::Memory::Split::Generic linkAddress = InternalSourcesTreeMethods->Search(source, target); } } - return (linkAddress == Constants.Null) ? LinkAddressType{0} : LinkAddressType{1}; } - } - else - { - if (!this->Exists(index)) - { - return LinkAddressType{0}; - } - if ((source == any) && (target == any)) - { - return LinkAddressType{1}; - } - auto& storedLinkValue = GetLinkDataPartReference(index); - if ((source != any) && (target != any)) + else { - if ((storedLinkValue.Source == source) && (storedLinkValue.Target == target)) + if (UseLinkedList || InternalSourcesTreeMethods->CountUsages(source) > + InternalTargetsTreeMethods->CountUsages(target)) { - return LinkAddressType{1}; + linkAddress = InternalTargetsTreeMethods->Search(source, target); + } + else + { + linkAddress = InternalSourcesTreeMethods->Search(source, target); } - return LinkAddressType{0}; - } - auto value = LinkAddressType{}; - if ((source == any)) - { - value = target; - } - if ((target == any)) - { - value = source; } - if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) + return (linkAddress == Constants.Null) ? LinkAddressType{0} : LinkAddressType{1}; + } + } + else + { + if (!this->Exists(index)) + { + return LinkAddressType{0}; + } + if ((source == any) && (target == any)) + { + return LinkAddressType{1}; + } + auto& storedLinkValue = GetLinkDataPartReference(index); + if ((source != any) && (target != any)) + { + if ((storedLinkValue.Source == source) && (storedLinkValue.Target == target)) { return LinkAddressType{1}; } return LinkAddressType{0}; } + auto value = LinkAddressType{}; + if ((source == any)) + { + value = target; + } + if ((target == any)) + { + value = source; + } + if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) + { + return LinkAddressType{1}; + } + return LinkAddressType{0}; } - throw Platform::Exceptions::NotSupportedException(); } -// - void SetPointers(TMemory& dataMemory, TMemory& indexMemory) + throw Platform::Exceptions::NotSupportedException(); + } + // + void SetPointers(TMemory& dataMemory, TMemory& indexMemory) + { + _linksDataParts = static_cast(dataMemory.Pointer()); + _linksIndexParts = static_cast(indexMemory.Pointer()); + _header = _linksIndexParts; + if (UseLinkedList) { - _linksDataParts = static_cast(dataMemory.Pointer()); - _linksIndexParts = static_cast(indexMemory.Pointer()); - _header = _linksIndexParts; - if (UseLinkedList) - { - // InternalSourcesTreeMethods = new TInternalLinksSourcesLinkedTreeMethods(_linksDataParts, _linksIndexParts); - } - else - { - InternalSourcesTreeMethods = new TInternalSourcesTreeMethods(_linksDataParts, _linksIndexParts, _header); - } - InternalTargetsTreeMethods = new TInternalTargetsTreeMethods(_linksDataParts, _linksIndexParts, _header); - ExternalTargetsTreeMethods = new TExternalTargetsTreeMethods(_linksDataParts, _linksIndexParts, _header); - ExternalSourcesTreeMethods = new TExternalSourcesTreeMethods(_linksDataParts, _linksIndexParts, _header); - ExternalTargetsTreeMethods = new TExternalTargetsTreeMethods(_linksDataParts, _linksIndexParts, _header); - UnusedLinksListMethods = new TUnusedLinksListMethods(_linksDataParts, _header); + // InternalSourcesTreeMethods = new TInternalLinksSourcesLinkedTreeMethods(_linksDataParts, + // _linksIndexParts); } + else + { + InternalSourcesTreeMethods = new TInternalSourcesTreeMethods(_linksDataParts, _linksIndexParts, _header); + } + InternalTargetsTreeMethods = new TInternalTargetsTreeMethods(_linksDataParts, _linksIndexParts, _header); + ExternalTargetsTreeMethods = new TExternalTargetsTreeMethods(_linksDataParts, _linksIndexParts, _header); + ExternalSourcesTreeMethods = new TExternalSourcesTreeMethods(_linksDataParts, _linksIndexParts, _header); + ExternalTargetsTreeMethods = new TExternalTargetsTreeMethods(_linksDataParts, _linksIndexParts, _header); + UnusedLinksListMethods = new TUnusedLinksListMethods(_linksDataParts, _header); + } - LinkAddressType Count(const LinkType& restriction) + LinkAddressType Count(const LinkType& restriction) + { + using namespace Platform::Exceptions; + auto length = std::ranges::size(restriction); + // Если нет ограничений, тогда возвращаем общее число связей находящихся в хранилище. + if (length == 0) { - using namespace Platform::Exceptions; - auto length = std::ranges::size(restriction); - // Если нет ограничений, тогда возвращаем общее число связей находящихся в хранилище. - if (length == 0) + return Total(); + } + auto constants = Constants; + auto any = constants.Any; + auto index = GetIndex(*this, restriction); + if (length == 1) + { + if (index == any) { return Total(); } - auto constants = Constants; - auto any = constants.Any; - auto index = GetIndex(*this, restriction); - if (length == 1) + return Exists(index) ? LinkAddressType{1} : LinkAddressType{0}; + } + if (length == 2) + { + auto value = restriction[1]; + if ((index == any)) { - if (index == any) + if ((value == any)) { - return Total(); + return Total(); // Any - как отсутствие ограничения } - return Exists(index) ? LinkAddressType{1} : LinkAddressType{0}; - } - if (length == 2) - { - auto value = restriction[1]; - if ((index == any)) + auto externalReferencesRange = constants.ExternalReferencesRange; + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(value)) { - if ((value == any)) - { - return Total(); // Any - как отсутствие ограничения - } - auto externalReferencesRange = constants.ExternalReferencesRange; - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(value)) + return (ExternalSourcesTreeMethods->CountUsages(value) + + ExternalTargetsTreeMethods->CountUsages(value)); + } + else + { + if (UseLinkedList) { - return (ExternalSourcesTreeMethods->CountUsages(value) + ExternalTargetsTreeMethods->CountUsages(value)); + return (InternalSourcesListMethods->CountUsages(value) + + InternalTargetsTreeMethods->CountUsages(value)); } else { - if (UseLinkedList) - { - return (InternalSourcesListMethods->CountUsages(value) + InternalTargetsTreeMethods->CountUsages(value)); - } - else - { - return (InternalSourcesTreeMethods->CountUsages(value) + InternalTargetsTreeMethods->CountUsages(value)); - } + return (InternalSourcesTreeMethods->CountUsages(value) + + InternalTargetsTreeMethods->CountUsages(value)); } } - else + } + else + { + if (!Exists(index)) { - if (!Exists(index)) - { - return LinkAddressType{0}; - } - if ((value == any)) + return LinkAddressType{0}; + } + if ((value == any)) + { + return LinkAddressType{1}; + } + auto& storedLinkValue = GetLinkDataPartReference(index); + if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) + { + return LinkAddressType{1}; + } + return LinkAddressType{0}; + } + } + if (length == 3) + { + auto externalReferencesRange = constants.ExternalReferencesRange; + auto source = GetSource(*this, restriction); + auto target = GetTarget(*this, restriction); + if ((index == any)) + { + if ((source == any) && (target == any)) + { + return Total(); + } + else if ((source == any)) + { + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(target)) { - return LinkAddressType{1}; + return ExternalTargetsTreeMethods->CountUsages(target); } - auto& storedLinkValue = GetLinkDataPartReference(index); - if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) + else { - return LinkAddressType{1}; + return InternalTargetsTreeMethods->CountUsages(target); } - return LinkAddressType{0}; } - } - if (length == 3) - { - auto externalReferencesRange = constants.ExternalReferencesRange; - auto source = GetSource(*this, restriction); - auto target = GetTarget(*this, restriction); - if ((index == any)) + else if ((target == any)) { - if ((source == any) && (target == any)) + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(source)) { - return Total(); + return ExternalSourcesTreeMethods->CountUsages(source); } - else if ((source == any)) + else { - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(target)) + if (UseLinkedList) { - return ExternalTargetsTreeMethods->CountUsages(target); + return InternalSourcesListMethods->CountUsages(source); } else { - return InternalTargetsTreeMethods->CountUsages(target); + return InternalSourcesTreeMethods->CountUsages(source); } } - else if ((target == any)) + } + else // if(source != Any && target != Any) + { + // Эквивалент Exists(source, target) => Count(Any, source, target) > 0 + LinkAddressType linkAddress; + if (Constants.IsExternalReferencesRangeEnabled) { - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(source)) + if (externalReferencesRange.Contains(source) && externalReferencesRange.Contains(target)) { - return ExternalSourcesTreeMethods->CountUsages(source); + linkAddress = ExternalSourcesTreeMethods->Search(source, target); } - else + else if (externalReferencesRange.Contains(source)) { - if (UseLinkedList) - { - return InternalSourcesListMethods->CountUsages(source); - } - else - { - return InternalSourcesTreeMethods->CountUsages(source); - } + linkAddress = InternalTargetsTreeMethods->Search(source, target); } - } - else //if(source != Any && target != Any) - { - // Эквивалент Exists(source, target) => Count(Any, source, target) > 0 - LinkAddressType linkAddress; - if (Constants.IsExternalReferencesRangeEnabled) + else if (externalReferencesRange.Contains(target)) { - if (externalReferencesRange.Contains(source) && externalReferencesRange.Contains(target)) + if (UseLinkedList) { linkAddress = ExternalSourcesTreeMethods->Search(source, target); } - else if (externalReferencesRange.Contains(source)) - { - linkAddress = InternalTargetsTreeMethods->Search(source, target); - } - else if (externalReferencesRange.Contains(target)) - { - if (UseLinkedList) - { - linkAddress = ExternalSourcesTreeMethods->Search(source, target); - } - else - { - linkAddress = InternalSourcesTreeMethods->Search(source, target); - } - } else { - if (UseLinkedList || (InternalSourcesTreeMethods->CountUsages(source) > InternalTargetsTreeMethods->CountUsages(target))) - { - linkAddress = InternalTargetsTreeMethods->Search(source, target); - } - else - { - linkAddress = InternalSourcesTreeMethods->Search(source, target); - } + linkAddress = InternalSourcesTreeMethods->Search(source, target); } } else { - if (UseLinkedList || (InternalSourcesTreeMethods->CountUsages(source) > InternalTargetsTreeMethods->CountUsages(target))) + if (UseLinkedList || (InternalSourcesTreeMethods->CountUsages(source) > + InternalTargetsTreeMethods->CountUsages(target))) { linkAddress = InternalTargetsTreeMethods->Search(source, target); } @@ -506,193 +513,195 @@ namespace Platform::Data::Doublets::Memory::Split::Generic linkAddress = InternalSourcesTreeMethods->Search(source, target); } } - return (linkAddress == constants.Null) ? LinkAddressType{0} : LinkAddressType{1}; } - } - else - { - if (!Exists(index)) - { - return LinkAddressType{0}; - } - if ((source == any) && (target == any)) - { - return LinkAddressType{1}; - } - auto& storedLinkValue = GetLinkDataPartReference(index); - if ((source != any) && (target != any)) + else { - if ((storedLinkValue.Source == source) && (storedLinkValue.Target == target)) + if (UseLinkedList || (InternalSourcesTreeMethods->CountUsages(source) > + InternalTargetsTreeMethods->CountUsages(target))) { - return LinkAddressType{1}; + linkAddress = InternalTargetsTreeMethods->Search(source, target); + } + else + { + linkAddress = InternalSourcesTreeMethods->Search(source, target); } - return LinkAddressType{0}; - } - auto value = LinkAddressType{0}; - if ((source == any)) - { - value = target; - } - if ((target == any)) - { - value = source; } - if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) + return (linkAddress == constants.Null) ? LinkAddressType{0} : LinkAddressType{1}; + } + } + else + { + if (!Exists(index)) + { + return LinkAddressType{0}; + } + if ((source == any) && (target == any)) + { + return LinkAddressType{1}; + } + auto& storedLinkValue = GetLinkDataPartReference(index); + if ((source != any) && (target != any)) + { + if ((storedLinkValue.Source == source) && (storedLinkValue.Target == target)) { return LinkAddressType{1}; } return LinkAddressType{0}; } + auto value = LinkAddressType{0}; + if ((source == any)) + { + value = target; + } + if ((target == any)) + { + value = source; + } + if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) + { + return LinkAddressType{1}; + } + return LinkAddressType{0}; } - throw Platform::Exceptions::NotSupportedException(); } + throw Platform::Exceptions::NotSupportedException(); + } - LinkAddressType Each(const LinkType& restriction, const ReadHandlerType& handler) const + LinkAddressType Each(const LinkType& restriction, const ReadHandlerType& handler) const + { + using namespace Platform::Exceptions; + auto constants = Constants; + auto $break = constants.Break; + auto length = std::ranges::size(restriction); + if (length == 0) { - using namespace Platform::Exceptions; - auto constants = Constants; - auto $break = constants.Break; - auto length = std::ranges::size(restriction); - if (length == 0) + for (auto linkAddress = LinkAddressType{1}; (linkAddress <= this->GetHeaderReference().AllocatedLinks); + ++linkAddress) { - for (auto linkAddress = LinkAddressType{1}; (linkAddress <= this->GetHeaderReference().AllocatedLinks); ++linkAddress) + if (Exists(linkAddress) && (handler(GetLinkStruct(linkAddress)) == $break)) { - if (Exists(linkAddress) && (handler(GetLinkStruct(linkAddress)) == $break)) - { - return $break; - } + return $break; } - return $break; } - auto $continue = constants.Continue; - auto any = constants.Any; - auto index = GetIndex(*this, restriction); - if (length == 1) + return $break; + } + auto $continue = constants.Continue; + auto any = constants.Any; + auto index = GetIndex(*this, restriction); + if (length == 1) + { + if ((index == any)) + { + return Each(LinkType{}, handler); + } + if (!Exists(index)) + { + return $continue; + } + return handler(GetLinkStruct(index)); + } + if (length == 2) + { + auto value = restriction[1]; + if (index == any) { - if ((index == any)) + if (value == any) { return Each(LinkType{}, handler); } + if (Each(LinkType{index, value, any}, handler) == $break) + { + return $break; + } + return Each(LinkType{index, any, value}, handler); + } + else + { if (!Exists(index)) { return $continue; } - return handler(GetLinkStruct(index)); + if ((value == any)) + { + return handler(GetLinkStruct(index)); + } + auto& storedLinkValue = GetLinkDataPartReference(index); + if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) + { + return handler(GetLinkStruct(index)); + } + return $continue; } - if (length == 2) + } + if (length == 3) + { + auto externalReferencesRange = constants.ExternalReferencesRange; + auto source = GetSource(*this, restriction); + auto target = GetTarget(*this, restriction); + if ((index == any)) { - auto value = restriction[1]; - if (index == any) + if ((source == any) && (target == any)) { - if (value == any) - { - return Each(LinkType{}, handler); - } - if (Each(LinkType{index, value, any}, handler) == $break) - { - return $break; - } - return Each(LinkType{index, any, value}, handler); + return Each(LinkType{}, handler); } - else + else if ((source == any)) { - if (!Exists(index)) + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(target)) { - return $continue; + return ExternalTargetsTreeMethods->EachUsage(target, handler); } - if ((value == any)) - { - return handler(GetLinkStruct(index)); - } - auto& storedLinkValue = GetLinkDataPartReference(index); - if ((storedLinkValue.Source == value) || - (storedLinkValue.Target == value)) + else { - return handler(GetLinkStruct(index)); + return InternalTargetsTreeMethods->EachUsage(target, handler); } - return $continue; } - } - if (length == 3) - { - auto externalReferencesRange = constants.ExternalReferencesRange; - auto source = GetSource(*this, restriction); - auto target = GetTarget(*this, restriction); - if ((index == any)) + else if ((target == any)) { - if ((source == any) && (target == any)) + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(source)) { - return Each(LinkType{}, handler); + return ExternalSourcesTreeMethods->EachUsage(source, handler); } - else if ((source == any)) + else { - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(target)) + if (UseLinkedList) { - return ExternalTargetsTreeMethods->EachUsage(target, handler); + return InternalSourcesListMethods->EachUsage(source, handler); } else { - return InternalTargetsTreeMethods->EachUsage(target, handler); + return InternalSourcesTreeMethods->EachUsage(source, handler); } } - else if ((target == any)) + } + else // if(source != Any && target != Any) + { + LinkAddressType linkAddress; + if (Constants.IsExternalReferencesRangeEnabled) { - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(source)) + if (externalReferencesRange.Contains(source) && externalReferencesRange.Contains(target)) { - return ExternalSourcesTreeMethods->EachUsage(source, handler); + linkAddress = ExternalSourcesTreeMethods->Search(source, target); } - else + else if (externalReferencesRange.Contains(source)) { - if (UseLinkedList) - { - return InternalSourcesListMethods->EachUsage(source, handler); - } - else - { - return InternalSourcesTreeMethods->EachUsage(source, handler); - } + linkAddress = InternalTargetsTreeMethods->Search(source, target); } - } - else //if(source != Any && target != Any) - { - LinkAddressType linkAddress; - if (Constants.IsExternalReferencesRangeEnabled) + else if (externalReferencesRange.Contains(target)) { - if (externalReferencesRange.Contains(source) && externalReferencesRange.Contains(target)) + if (UseLinkedList) { linkAddress = ExternalSourcesTreeMethods->Search(source, target); } - else if (externalReferencesRange.Contains(source)) - { - linkAddress = InternalTargetsTreeMethods->Search(source, target); - } - else if (externalReferencesRange.Contains(target)) - { - if (UseLinkedList) - { - linkAddress = ExternalSourcesTreeMethods->Search(source, target); - } - else - { - linkAddress = InternalSourcesTreeMethods->Search(source, target); - } - } else { - if (UseLinkedList || (InternalSourcesTreeMethods->CountUsages(source) == InternalTargetsTreeMethods->CountUsages(target))) - { - linkAddress = InternalTargetsTreeMethods->Search(source, target); - } - else - { - linkAddress = InternalSourcesTreeMethods->Search(source, target); - } + linkAddress = InternalSourcesTreeMethods->Search(source, target); } } else { - if (UseLinkedList || (InternalSourcesTreeMethods->CountUsages(source) > InternalTargetsTreeMethods->CountUsages(target))) + if (UseLinkedList || (InternalSourcesTreeMethods->CountUsages(source) == + InternalTargetsTreeMethods->CountUsages(target))) { linkAddress = InternalTargetsTreeMethods->Search(source, target); } @@ -701,214 +710,226 @@ namespace Platform::Data::Doublets::Memory::Split::Generic linkAddress = InternalSourcesTreeMethods->Search(source, target); } } - return (linkAddress == constants.Null) ? $continue : handler(GetLinkStruct(linkAddress)); - } - } - else - { - if (!Exists(index)) - { - return $continue; } - if ((source == any) && (target == any)) - { - return handler(GetLinkStruct(index)); - } - auto& storedLinkValue = GetLinkDataPartReference(index); - if ((source != any) && (target != any)) + else { - if ((storedLinkValue.Source == source) && - (storedLinkValue.Target == target)) + if (UseLinkedList || (InternalSourcesTreeMethods->CountUsages(source) > + InternalTargetsTreeMethods->CountUsages(target))) { - return handler(GetLinkStruct(index)); + linkAddress = InternalTargetsTreeMethods->Search(source, target); + } + else + { + linkAddress = InternalSourcesTreeMethods->Search(source, target); } - return $continue; - } - auto value = LinkAddressType{0}; - if (source == any) - { - value = target; - } - if (target == any) - { - value = source; - } - if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) - { - return handler(GetLinkStruct(index)); } - return $continue; + return (linkAddress == constants.Null) ? $continue : handler(GetLinkStruct(linkAddress)); } } - throw Platform::Exceptions::NotSupportedException(); - } - - - LinkAddressType Update(const LinkType& restriction, const LinkType& substitution, const WriteHandlerType& handler) - { - auto constants = Constants; - auto $null = constants.Null; - auto externalReferencesRange = constants.ExternalReferencesRange; - auto linkIndex = GetIndex(*this, restriction); - auto before = this->GetLinkStruct(linkIndex); - auto& link = this->GetLinkDataPartReference(linkIndex); - auto source = link.Source; - auto target = link.Target; - auto& rootAsSource = this->GetHeaderReference().RootAsSource; - auto& rootAsTarget = this->GetHeaderReference().RootAsTarget; - // Будет корректно работать только в том случае, если пространство выделенной связи предварительно заполнено нулями - if (source != $null) + else { - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(source)) + if (!Exists(index)) { - ExternalSourcesTreeMethods->Detach(&rootAsSource, linkIndex); + return $continue; } - else + if ((source == any) && (target == any)) { - if (UseLinkedList) - { - InternalSourcesListMethods->Detach(source, linkIndex); - } - else + return handler(GetLinkStruct(index)); + } + auto& storedLinkValue = GetLinkDataPartReference(index); + if ((source != any) && (target != any)) + { + if ((storedLinkValue.Source == source) && (storedLinkValue.Target == target)) { - InternalSourcesTreeMethods->Detach(&(GetLinkIndexPartReference(source).RootAsSource), linkIndex); + return handler(GetLinkStruct(index)); } + return $continue; } - } - if (target != $null) - { - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(target)) + auto value = LinkAddressType{0}; + if (source == any) { - ExternalTargetsTreeMethods->Detach(&rootAsTarget, linkIndex); + value = target; } - else + if (target == any) { - InternalTargetsTreeMethods->Detach(&(GetLinkIndexPartReference(target).RootAsTarget), linkIndex); + value = source; } - } - source = link.Source = GetSource(*this, substitution); - target = link.Target = GetTarget(*this, substitution); - if (source != $null) - { - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(source)) + if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) { - ExternalSourcesTreeMethods->Attach(&rootAsSource, linkIndex); - } - else - { - if (UseLinkedList) - { - InternalSourcesListMethods->AttachAsLast(source, linkIndex); - } - else - { - InternalSourcesTreeMethods->Attach(&(GetLinkIndexPartReference(source).RootAsSource), linkIndex); - } + return handler(GetLinkStruct(index)); } + return $continue; + } + } + throw Platform::Exceptions::NotSupportedException(); + } + + + LinkAddressType Update(const LinkType& restriction, const LinkType& substitution, const WriteHandlerType& handler) + { + auto constants = Constants; + auto $null = constants.Null; + auto externalReferencesRange = constants.ExternalReferencesRange; + auto linkIndex = GetIndex(*this, restriction); + auto before = this->GetLinkStruct(linkIndex); + auto& link = this->GetLinkDataPartReference(linkIndex); + auto source = link.Source; + auto target = link.Target; + auto& rootAsSource = this->GetHeaderReference().RootAsSource; + auto& rootAsTarget = this->GetHeaderReference().RootAsTarget; + // Будет корректно работать только в том случае, если пространство выделенной связи предварительно заполнено + // нулями + if (source != $null) + { + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(source)) + { + ExternalSourcesTreeMethods->Detach(&rootAsSource, linkIndex); } - if (target != $null) + else { - if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(target)) + if (UseLinkedList) { - ExternalTargetsTreeMethods->Attach(&rootAsTarget, linkIndex); + InternalSourcesListMethods->Detach(source, linkIndex); } else { - InternalTargetsTreeMethods->Attach(&(GetLinkIndexPartReference(target).RootAsTarget), linkIndex); + InternalSourcesTreeMethods->Detach(&(GetLinkIndexPartReference(source).RootAsSource), linkIndex); } } - return handler ? handler(before, LinkType{linkIndex, source, target}) : Constants.Continue; } - - - LinkAddressType Create(const LinkType& substitution, const WriteHandlerType& handler) + if (target != $null) { - using namespace Platform::Exceptions; - auto freeLink = this->GetHeaderReference().FirstFreeLink; - if (freeLink != Constants.Null) + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(target)) { - UnusedLinksListMethods->Detach(freeLink); + ExternalTargetsTreeMethods->Detach(&rootAsTarget, linkIndex); } else { - auto maximumPossibleInnerReference = Constants.InternalReferencesRange.Maximum; - if (this->GetHeaderReference().AllocatedLinks > maximumPossibleInnerReference) + InternalTargetsTreeMethods->Detach(&(GetLinkIndexPartReference(target).RootAsTarget), linkIndex); + } + } + source = link.Source = GetSource(*this, substitution); + target = link.Target = GetTarget(*this, substitution); + if (source != $null) + { + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(source)) + { + ExternalSourcesTreeMethods->Attach(&rootAsSource, linkIndex); + } + else + { + if (UseLinkedList) { - throw Platform::Exceptions::LinksLimitReachedException(); + InternalSourcesListMethods->AttachAsLast(source, linkIndex); } - if (this->GetHeaderReference().AllocatedLinks >= (this->GetHeaderReference().ReservedLinks - 1)) + else { - _dataMemory.ReservedCapacity( _dataMemory.ReservedCapacity() + _dataMemoryReservationStepInBytes); - _indexMemory.ReservedCapacity(_indexMemory.ReservedCapacity() + _indexMemoryReservationStepInBytes); - SetPointers(_dataMemory, _indexMemory); - this->GetHeaderReference() = this->GetHeaderReference(); - this->GetHeaderReference().ReservedLinks = _dataMemory.ReservedCapacity() / LinkDataPartSizeInBytes; + InternalSourcesTreeMethods->Attach(&(GetLinkIndexPartReference(source).RootAsSource), linkIndex); } - freeLink = ++this->GetHeaderReference().AllocatedLinks; - _dataMemory.UsedCapacity(_dataMemory.UsedCapacity() + LinkDataPartSizeInBytes); - _indexMemory.UsedCapacity(_indexMemory.UsedCapacity() + LinkIndexPartSizeInBytes); } - return handler ? handler(LinkType{}, GetLinkStruct(freeLink)) : Constants.Continue; } - - - LinkAddressType Delete(const LinkType& restriction, const WriteHandlerType& handler) + if (target != $null) { - auto linkAddress = GetIndex(*this, restriction); - auto before = GetLinkStruct(linkAddress); - if (linkAddress < this->GetHeaderReference().AllocatedLinks) + if (Constants.IsExternalReferencesRangeEnabled && externalReferencesRange.Contains(target)) { - UnusedLinksListMethods->AttachAsFirst(linkAddress); - return handler ? handler(before, LinkType{}) : Constants.Continue; + ExternalTargetsTreeMethods->Attach(&rootAsTarget, linkIndex); } - else if (linkAddress == this->GetHeaderReference().AllocatedLinks) + else { - --this->GetHeaderReference().AllocatedLinks; - _dataMemory.UsedCapacity(_dataMemory.UsedCapacity() - LinkDataPartSizeInBytes); - _indexMemory.UsedCapacity(_indexMemory.UsedCapacity() - LinkIndexPartSizeInBytes); - // Убираем все связи, находящиеся в списке свободных в конце файла, до тех пор, пока не дойдём до первой существующей связи - // Позволяет оптимизировать количество выделенных связей (AllocatedLinks) - while ((this->GetHeaderReference().AllocatedLinks > LinkAddressType{0}) && this->IsUnusedLink(this->GetHeaderReference().AllocatedLinks)) - { - UnusedLinksListMethods->Detach(this->GetHeaderReference().AllocatedLinks); - --this->GetHeaderReference().AllocatedLinks; - _dataMemory.UsedCapacity(_dataMemory.UsedCapacity() - LinkDataPartSizeInBytes); - _indexMemory.UsedCapacity(_indexMemory.UsedCapacity() - LinkIndexPartSizeInBytes); - } - return handler ? handler(before, LinkType{}) : Constants.Continue; + InternalTargetsTreeMethods->Attach(&(GetLinkIndexPartReference(target).RootAsTarget), linkIndex); } - return Constants.Continue; } + return handler ? handler(before, LinkType{linkIndex, source, target}) : Constants.Continue; + } - public: - bool IsUnusedLink(LinkAddressType linkIndex) const + + LinkAddressType Create(const LinkType& substitution, const WriteHandlerType& handler) + { + using namespace Platform::Exceptions; + auto freeLink = this->GetHeaderReference().FirstFreeLink; + if (freeLink != Constants.Null) + { + UnusedLinksListMethods->Detach(freeLink); + } + else { - if (GetHeaderReference().FirstFreeLink != linkIndex) // May be this check is not needed + auto maximumPossibleInnerReference = Constants.InternalReferencesRange.Maximum; + if (this->GetHeaderReference().AllocatedLinks > maximumPossibleInnerReference) { - // TODO: Reduce access to memory in different location (should be enough to use just linkIndexPart) - const auto& linkDataPart = this->GetLinkDataPartReference(linkIndex); - const auto& linkIndexPart = this->GetLinkIndexPartReference(linkIndex); - return (linkIndexPart.SizeAsTarget == LinkAddressType{0}) && (linkDataPart.Source != LinkAddressType{0}); + throw Platform::Exceptions::LinksLimitReachedException(); } - else + if (this->GetHeaderReference().AllocatedLinks >= (this->GetHeaderReference().ReservedLinks - 1)) { - return true; + _dataMemory.ReservedCapacity(_dataMemory.ReservedCapacity() + _dataMemoryReservationStepInBytes); + _indexMemory.ReservedCapacity(_indexMemory.ReservedCapacity() + _indexMemoryReservationStepInBytes); + SetPointers(_dataMemory, _indexMemory); + this->GetHeaderReference() = this->GetHeaderReference(); + this->GetHeaderReference().ReservedLinks = _dataMemory.ReservedCapacity() / LinkDataPartSizeInBytes; } + freeLink = ++this->GetHeaderReference().AllocatedLinks; + _dataMemory.UsedCapacity(_dataMemory.UsedCapacity() + LinkDataPartSizeInBytes); + _indexMemory.UsedCapacity(_indexMemory.UsedCapacity() + LinkIndexPartSizeInBytes); } + return handler ? handler(LinkType{}, GetLinkStruct(freeLink)) : Constants.Continue; + } + - bool Exists(LinkAddressType linkAddress) const + LinkAddressType Delete(const LinkType& restriction, const WriteHandlerType& handler) + { + auto linkAddress = GetIndex(*this, restriction); + auto before = GetLinkStruct(linkAddress); + if (linkAddress < this->GetHeaderReference().AllocatedLinks) + { + UnusedLinksListMethods->AttachAsFirst(linkAddress); + return handler ? handler(before, LinkType{}) : Constants.Continue; + } + else if (linkAddress == this->GetHeaderReference().AllocatedLinks) { - return (linkAddress >= Constants.InternalReferencesRange.Minimum) - && (linkAddress <= this->GetHeaderReference().AllocatedLinks) - && !IsUnusedLink(linkAddress); + --this->GetHeaderReference().AllocatedLinks; + _dataMemory.UsedCapacity(_dataMemory.UsedCapacity() - LinkDataPartSizeInBytes); + _indexMemory.UsedCapacity(_indexMemory.UsedCapacity() - LinkIndexPartSizeInBytes); + // Убираем все связи, находящиеся в списке свободных в конце файла, до тех пор, пока не дойдём до первой + // существующей связи Позволяет оптимизировать количество выделенных связей (AllocatedLinks) + while ((this->GetHeaderReference().AllocatedLinks > LinkAddressType{0}) && + this->IsUnusedLink(this->GetHeaderReference().AllocatedLinks)) + { + UnusedLinksListMethods->Detach(this->GetHeaderReference().AllocatedLinks); + --this->GetHeaderReference().AllocatedLinks; + _dataMemory.UsedCapacity(_dataMemory.UsedCapacity() - LinkDataPartSizeInBytes); + _indexMemory.UsedCapacity(_indexMemory.UsedCapacity() - LinkIndexPartSizeInBytes); + } + return handler ? handler(before, LinkType{}) : Constants.Continue; } + return Constants.Continue; + } - public: - LinkType GetLinkStruct(LinkAddressType linkIndex) const +public: + bool IsUnusedLink(LinkAddressType linkIndex) const + { + if (GetHeaderReference().FirstFreeLink != linkIndex) // May be this check is not needed + { + // TODO: Reduce access to memory in different location (should be enough to use just linkIndexPart) + const auto& linkDataPart = this->GetLinkDataPartReference(linkIndex); + const auto& linkIndexPart = this->GetLinkIndexPartReference(linkIndex); + return (linkIndexPart.SizeAsTarget == LinkAddressType{0}) && (linkDataPart.Source != LinkAddressType{0}); + } + else { - const auto& link = this->GetLinkDataPartReference(linkIndex); - return LinkType{linkIndex, link.Source, link.Target}; + return true; } + } - }; -} + bool Exists(LinkAddressType linkAddress) const + { + return (linkAddress >= Constants.InternalReferencesRange.Minimum) && + (linkAddress <= this->GetHeaderReference().AllocatedLinks) && !IsUnusedLink(linkAddress); + } + +public: + LinkType GetLinkStruct(LinkAddressType linkIndex) const + { + const auto& link = this->GetLinkDataPartReference(linkIndex); + return LinkType{linkIndex, link.Source, link.Target}; + } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/Generic/UnusedLinksListMethods.h b/cpp/Platform.Data.Doublets/Memory/Split/Generic/UnusedLinksListMethods.h index e37f1fd48..542d573c9 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/Generic/UnusedLinksListMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/Generic/UnusedLinksListMethods.h @@ -1,63 +1,96 @@ namespace Platform::Data::Doublets::Memory::Split::Generic { - template - class UnusedLinksListMethods : public Platform::Collections::Methods::Lists::AbsoluteCircularDoublyLinkedListMethods, typename TLinksOptions::LinkAddressType> /*, ILinksListMethods */ - { - public: - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - using base = Platform::Collections::Methods::Lists::AbsoluteCircularDoublyLinkedListMethods, typename TLinksOptions::LinkAddressType>; - public: static constexpr auto Constants = LinksOptionsType::Constants; - private: std::byte* _storage; - private: std::byte* _header; +template +class UnusedLinksListMethods + : public Platform::Collections::Methods::Lists::AbsoluteCircularDoublyLinkedListMethods< + UnusedLinksListMethods, + typename TLinksOptions::LinkAddressType> /*, ILinksListMethods */ +{ +public: + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + using base = Platform::Collections::Methods::Lists::AbsoluteCircularDoublyLinkedListMethods< + UnusedLinksListMethods, typename TLinksOptions::LinkAddressType>; + +public: + static constexpr auto Constants = LinksOptionsType::Constants; - public: UnusedLinksListMethods(std::byte* storage, std::byte* header) - { - _storage = storage; - _header = header; - } +private: + std::byte* _storage; + +private: + std::byte* _header; + +public: + UnusedLinksListMethods(std::byte* storage, std::byte* header) + { + _storage = storage; + _header = header; + } - public: const LinksHeader& GetHeaderReference() const - { - return *reinterpret_cast*>(_header); - } +public: + const LinksHeader& GetHeaderReference() const + { + return *reinterpret_cast*>(_header); + } - public: LinksHeader& GetHeaderReference() - { - return *reinterpret_cast*>(_header); - } +public: + LinksHeader& GetHeaderReference() + { + return *reinterpret_cast*>(_header); + } - public: const RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) const - { - return *reinterpret_cast*>(_storage + (RawLinkDataPart::SizeInBytes * (link))); - } +public: + const RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) const + { + return *reinterpret_cast*>( + _storage + (RawLinkDataPart::SizeInBytes * (link))); + } - public: RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) - { - return *reinterpret_cast*>(_storage + (RawLinkDataPart::SizeInBytes * (link))); - } +public: + RawLinkDataPart& GetLinkDataPartReference(LinkAddressType link) + { + return *reinterpret_cast*>( + _storage + (RawLinkDataPart::SizeInBytes * (link))); + } - public: LinkAddressType GetFirst() { return this->GetHeaderReference().FirstFreeLink; } +public: + LinkAddressType GetFirst() { return this->GetHeaderReference().FirstFreeLink; } - public: LinkAddressType GetLast() { return this->GetHeaderReference().LastFreeLink; } +public: + LinkAddressType GetLast() { return this->GetHeaderReference().LastFreeLink; } - public: LinkAddressType GetPrevious(LinkAddressType element) { return this->GetLinkDataPartReference(element).Source; } +public: + LinkAddressType GetPrevious(LinkAddressType element) { return this->GetLinkDataPartReference(element).Source; } - public: LinkAddressType GetNext(LinkAddressType element) { return this->GetLinkDataPartReference(element).Target; } +public: + LinkAddressType GetNext(LinkAddressType element) { return this->GetLinkDataPartReference(element).Target; } - public: LinkAddressType GetSize() { return this->GetHeaderReference().FreeLinks; } +public: + LinkAddressType GetSize() { return this->GetHeaderReference().FreeLinks; } - public: void SetFirst(LinkAddressType element) { this->GetHeaderReference().FirstFreeLink = element; } +public: + void SetFirst(LinkAddressType element) { this->GetHeaderReference().FirstFreeLink = element; } - public: void SetLast(LinkAddressType element) { this->GetHeaderReference().LastFreeLink = element; } +public: + void SetLast(LinkAddressType element) { this->GetHeaderReference().LastFreeLink = element; } - public: void SetPrevious(LinkAddressType element, LinkAddressType previous) { this->GetLinkDataPartReference(element).Source = previous; } +public: + void SetPrevious(LinkAddressType element, LinkAddressType previous) + { + this->GetLinkDataPartReference(element).Source = previous; + } - public: void SetNext(LinkAddressType element, LinkAddressType next) { this->GetLinkDataPartReference(element).Target = next; } +public: + void SetNext(LinkAddressType element, LinkAddressType next) + { + this->GetLinkDataPartReference(element).Target = next; + } - public: void SetSize(LinkAddressType size) { this->GetHeaderReference().FreeLinks = size; } - }; -} +public: + void SetSize(LinkAddressType size) { this->GetHeaderReference().FreeLinks = size; } +}; +} // namespace Platform::Data::Doublets::Memory::Split::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/Split/RawLinkDataPart.h b/cpp/Platform.Data.Doublets/Memory/Split/RawLinkDataPart.h index 1bd52f762..396c0861f 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/RawLinkDataPart.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/RawLinkDataPart.h @@ -1,45 +1,38 @@ namespace Platform::Data::Doublets::Memory::Split { - template struct RawLinkDataPart; - template struct RawLinkDataPart - { - public: - constexpr static std::size_t SizeInBytes = sizeof(RawLinkDataPart); +template +struct RawLinkDataPart; +template +struct RawLinkDataPart +{ +public: + constexpr static std::size_t SizeInBytes = sizeof(RawLinkDataPart); - TLinkAddress Source; - TLinkAddress Target; + TLinkAddress Source; + TLinkAddress Target; - bool operator =(RawLinkDataPart other) - { - return (Source == other.Source) && (Target == other.Target); - } + bool operator=(RawLinkDataPart other) { return (Source == other.Source) && (Target == other.Target); } - public: - std::int32_t GetHashCode() - { - return Platform::Hashing::Hash(Source, Target); - } +public: + std::int32_t GetHashCode() { return Platform::Hashing::Hash(Source, Target); } - bool operator ==(RawLinkDataPart other) - { - return (Source == other.Source) && (Target == other.Target); - } + bool operator==(RawLinkDataPart other) + { + return (Source == other.Source) && (Target == other.Target); + } - bool operator !=(RawLinkDataPart other) - { - return !(this == other); - } - }; -} + bool operator!=(RawLinkDataPart other) { return !(this == other); } +}; +} // namespace Platform::Data::Doublets::Memory::Split namespace std { - template - struct hash> +template +struct hash> +{ + std::size_t operator()(const Platform::Data::Doublets::Memory::Split::RawLinkDataPart& obj) const { - std::size_t operator()(const Platform::Data::Doublets::Memory::Split::RawLinkDataPart &obj) const - { - return obj.GetHashCode(); - } - }; -} + return obj.GetHashCode(); + } +}; +} // namespace std diff --git a/cpp/Platform.Data.Doublets/Memory/Split/RawLinkIndexPart.h b/cpp/Platform.Data.Doublets/Memory/Split/RawLinkIndexPart.h index 05a45e4db..ec6e0a4b0 100644 --- a/cpp/Platform.Data.Doublets/Memory/Split/RawLinkIndexPart.h +++ b/cpp/Platform.Data.Doublets/Memory/Split/RawLinkIndexPart.h @@ -1,49 +1,44 @@ namespace Platform::Data::Doublets::Memory::Split { - template - struct RawLinkIndexPart; +template +struct RawLinkIndexPart; - template - struct RawLinkIndexPart - { - public: inline static const std::uint64_t SizeInBytes = sizeof(RawLinkIndexPart); +template +struct RawLinkIndexPart +{ +public: + inline static const std::uint64_t SizeInBytes = sizeof(RawLinkIndexPart); - TLinkAddress RootAsSource; - TLinkAddress LeftAsSource; - TLinkAddress RightAsSource; - TLinkAddress SizeAsSource; - TLinkAddress RootAsTarget; - TLinkAddress LeftAsTarget; - TLinkAddress RightAsTarget; - TLinkAddress SizeAsTarget; + TLinkAddress RootAsSource; + TLinkAddress LeftAsSource; + TLinkAddress RightAsSource; + TLinkAddress SizeAsSource; + TLinkAddress RootAsTarget; + TLinkAddress LeftAsTarget; + TLinkAddress RightAsTarget; + TLinkAddress SizeAsTarget; - bool operator ==(RawLinkIndexPart other) - { - return RootAsSource == other.RootAsSource - && LeftAsSource == other.LeftAsSource - && RightAsSource == other.RightAsSource - && SizeAsSource == other.SizeAsSource - && RootAsTarget == other.RootAsTarget - && LeftAsTarget == other.LeftAsTarget - && RightAsTarget == other.RightAsTarget - && SizeAsTarget == other.SizeAsTarget; - } + bool operator==(RawLinkIndexPart other) + { + return RootAsSource == other.RootAsSource && LeftAsSource == other.LeftAsSource && + RightAsSource == other.RightAsSource && SizeAsSource == other.SizeAsSource && + RootAsTarget == other.RootAsTarget && LeftAsTarget == other.LeftAsTarget && + RightAsTarget == other.RightAsTarget && SizeAsTarget == other.SizeAsTarget; + } - bool operator !=(RawLinkIndexPart other) - { - return !(this == other); - } - }; -} + bool operator!=(RawLinkIndexPart other) { return !(this == other); } +}; +} // namespace Platform::Data::Doublets::Memory::Split namespace std { - template - struct hash> +template +struct hash> +{ + std::size_t operator()(const Platform::Data::Doublets::Memory::Split::RawLinkIndexPart& obj) const { - std::size_t operator()(const Platform::Data::Doublets::Memory::Split::RawLinkIndexPart& obj) const - { - return Platform::Hashing::Hash(obj.RootAsSource, obj.LeftAsSource, obj.RightAsSource, obj.SizeAsSource, obj.RootAsTarget, obj.LeftAsTarget, obj.RightAsTarget, obj.SizeAsTarget); - } - }; -} + return Platform::Hashing::Hash(obj.RootAsSource, obj.LeftAsSource, obj.RightAsSource, obj.SizeAsSource, + obj.RootAsTarget, obj.LeftAsTarget, obj.RightAsTarget, obj.SizeAsTarget); + } +}; +} // namespace std diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksAvlBalancedTreeMethodsBase.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksAvlBalancedTreeMethodsBase.h index f4498bf8d..0ffbc368c 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksAvlBalancedTreeMethodsBase.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksAvlBalancedTreeMethodsBase.h @@ -1,239 +1,279 @@ namespace Platform::Data::Doublets::Memory::United::Generic { -template -struct LinksAvlBalancedTreeMethodsBase : public Platform::Collections::Methods::Trees::SizedAndThreadedAVLBalancedTreeMethods/*, ILinksTreeMethods*/ - { - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - static constexpr LinksConstants Constants = LinksOptionsType::Constants; +template +struct LinksAvlBalancedTreeMethodsBase + : public Platform::Collections::Methods::Trees::SizedAndThreadedAVLBalancedTreeMethods< + Self, typename TLinksOptions::LinkAddressType> /*, ILinksTreeMethods*/ +{ + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + static constexpr LinksConstants Constants = LinksOptionsType::Constants; + +public: + static constexpr auto $break = Constants.Break; + +public: + static constexpr auto $continue = Constants.Continue; + +public: + using methods = + Platform::Collections::Methods::Trees::SizedAndThreadedAVLBalancedTreeMethods; + +public: + std::byte* const Links; - public: static constexpr auto $break = Constants.Break; - public: static constexpr auto $continue = Constants.Continue; - public: using methods = Platform::Collections::Methods::Trees::SizedAndThreadedAVLBalancedTreeMethods; - public: std::byte* const Links; - public: std::byte* const Header; +public: + std::byte* const Header; - public: LinksAvlBalancedTreeMethodsBase(std::byte* storage, std::byte* header) : Links(storage), Header(header) {} +public: + LinksAvlBalancedTreeMethodsBase(std::byte* storage, std::byte* header) : Links(storage), Header(header) {} - public: auto operator[](std::size_t index) +public: + auto operator[](std::size_t index) + { + auto root = this->object().GetTreeRoot(); + if (index >= GetSize(root)) + { + return 0; + } + while (!EqualToZero(root)) { - auto root = this->object().GetTreeRoot(); - if (index >= GetSize(root)) + auto left = GetLeftOrDefault(root); + auto leftSize = GetSizeOrZero(left); + if (index < leftSize) { - return 0; + root = left; + continue; } - while (!EqualToZero(root)) + if (AreEqual(index, leftSize)) { - auto left = GetLeftOrDefault(root); - auto leftSize = GetSizeOrZero(left); - if (index < leftSize) - { - root = left; - continue; - } - if (AreEqual(index, leftSize)) - { - return root; - } - root = GetRightOrDefault(root); - index = index - (leftSize + 1); + return root; } - return 0; + root = GetRightOrDefault(root); + index = index - (leftSize + 1); } + return 0; + } - public: LinkAddressType Search(LinkAddressType source, LinkAddressType target) +public: + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + auto root = this->object().GetTreeRoot(); + while (root != 0) { - auto root = this->object().GetTreeRoot(); - while (root != 0) + auto& rootLink = this->GetLinkReference(root); + auto rootSource = rootLink.Source; + auto rootTarget = rootLink.Target; + if (this->object().FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget)) { - auto& rootLink = this->GetLinkReference(root); - auto rootSource = rootLink.Source; - auto rootTarget = rootLink.Target; - if (this->object().FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget)) - { - root = this->GetLeftOrDefault(root); - } - else if (this->object().FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget)) - { - root = this->GetRightOrDefault(root); - } - else - { - return root; - } + root = this->GetLeftOrDefault(root); + } + else if (this->object().FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget)) + { + root = this->GetRightOrDefault(root); + } + else + { + return root; } - return 0; } + return 0; + } - public: LinkAddressType CountUsages(LinkAddressType link) +public: + LinkAddressType CountUsages(LinkAddressType link) + { + auto root = this->object().GetTreeRoot(); + auto total = this->object().GetSize(root); + auto totalRightIgnore = 0; + while (root != 0) { - auto root = this->object().GetTreeRoot(); - auto total = this->object().GetSize(root); - auto totalRightIgnore = 0; - while (root != 0) + auto base = this->object().GetBasePartValue(root); + if (base <= link) { - auto base = this->object().GetBasePartValue(root); - if (base <= link) - { - root = this->GetRightOrDefault(root); - } - else - { - totalRightIgnore = totalRightIgnore + (this->GetRightSize(root) + 1); - root = this->GetLeftOrDefault(root); - } + root = this->GetRightOrDefault(root); } - root = this->object().GetTreeRoot(); - auto totalLeftIgnore = 0; - while (root != 0) + else { - auto base = this->object().GetBasePartValue(root); - if (base >= link) - { - root = this->GetLeftOrDefault(root); - } - else - { - totalLeftIgnore = totalLeftIgnore + (this->GetLeftSize(root) + 1); - - root = this->GetRightOrDefault(root); - } + totalRightIgnore = totalRightIgnore + (this->GetRightSize(root) + 1); + root = this->GetLeftOrDefault(root); } - return (total - totalRightIgnore) - totalLeftIgnore; } - - public: LinkAddressType EachUsage(LinkAddressType link, std::function handler) + root = this->object().GetTreeRoot(); + auto totalLeftIgnore = 0; + while (root != 0) { - auto root = this->object().GetTreeRoot(); - if (root == 0) + auto base = this->object().GetBasePartValue(root); + if (base >= link) { - return $continue; + root = this->GetLeftOrDefault(root); } - LinkAddressType first = 0, current = root; - while (current != 0) + else { - auto base = this->object().GetBasePartValue(current); - if (base >= link) - { - if ((base) == link) - { - first = current; - } - current = this->GetLeftOrDefault(current); - } - else + totalLeftIgnore = totalLeftIgnore + (this->GetLeftSize(root) + 1); + + root = this->GetRightOrDefault(root); + } + } + return (total - totalRightIgnore) - totalLeftIgnore; + } + +public: + LinkAddressType EachUsage(LinkAddressType link, std::function handler) + { + auto root = this->object().GetTreeRoot(); + if (root == 0) + { + return $continue; + } + LinkAddressType first = 0, current = root; + while (current != 0) + { + auto base = this->object().GetBasePartValue(current); + if (base >= link) + { + if ((base) == link) { - current = this->GetRightOrDefault(current); + first = current; } + current = this->GetLeftOrDefault(current); } - if (first != 0) + else + { + current = this->GetRightOrDefault(current); + } + } + if (first != 0) + { + current = first; + while (true) { - current = first; - while (true) + if (handler(this->GetLinkValues(current)) == $break) + { + return $break; + } + current = this->GetNext(current); + if (current == 0 || this->object().GetBasePartValue(current) != link) { - if (handler(this->GetLinkValues(current)) == $break) - { - return $break; - } - current = this->GetNext(current); - if (current == 0 || this->object().GetBasePartValue(current) != link) - { - break; - } + break; } } - return $continue; } + return $continue; + } - public: auto& GetHeaderReference() const - { - return *reinterpret_cast*>(Header); - } +public: + auto& GetHeaderReference() const { return *reinterpret_cast*>(Header); } - public: auto& GetLinkReference(LinkAddressType linkAddress) { return *(reinterpret_cast*>(Links) + linkAddress); } +public: + auto& GetLinkReference(LinkAddressType linkAddress) + { + return *(reinterpret_cast*>(Links) + linkAddress); + } - public: LinkType GetLinkValues(LinkAddressType linkIndex) - { - auto& link = GetLinkReference(linkIndex); - return LinkType{linkIndex, link.Source, link.Target}; - } +public: + LinkType GetLinkValues(LinkAddressType linkIndex) + { + auto& link = GetLinkReference(linkIndex); + return LinkType{linkIndex, link.Source, link.Target}; + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) - { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->object().FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - } +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->object().FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + secondLink.Target); + } - public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) - { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->object().FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - } +public: + bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->object().FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + secondLink.Target); + } - public: LinkAddressType GetSizeValue(LinkAddressType value) { return Platform::Numbers::Bit::PartialRead(value, 5, -5); } +public: + LinkAddressType GetSizeValue(LinkAddressType value) + { + return Platform::Numbers::Bit::PartialRead(value, 5, -5); + } - public: void SetSizeValue(LinkAddressType* storedValue, LinkAddressType size) { *storedValue = Platform::Numbers::Bit::PartialWrite(*storedValue, size, 5, -5); } +public: + void SetSizeValue(LinkAddressType* storedValue, LinkAddressType size) + { + *storedValue = Platform::Numbers::Bit::PartialWrite(*storedValue, size, 5, -5); + } - public: bool GetLeftIsChildValue(LinkAddressType value) +public: + bool GetLeftIsChildValue(LinkAddressType value) + { { - { - return (bool)Platform::Numbers::Bit::PartialRead(value, 4, 1); - } + return (bool)Platform::Numbers::Bit::PartialRead(value, 4, 1); } + } - public: void SetLeftIsChildValue(LinkAddressType* storedValue, bool value) +public: + void SetLeftIsChildValue(LinkAddressType* storedValue, bool value) + { { - { - auto previousValue = *storedValue; - auto modified = Platform::Numbers::Bit::PartialWrite(previousValue, (LinkAddressType)value, 4, 1); - *storedValue = modified; - } + auto previousValue = *storedValue; + auto modified = + Platform::Numbers::Bit::PartialWrite(previousValue, (LinkAddressType)value, 4, 1); + *storedValue = modified; } + } - public: bool GetRightIsChildValue(LinkAddressType value) +public: + bool GetRightIsChildValue(LinkAddressType value) + { { - { - return (bool)Platform::Numbers::Bit::PartialRead(value, 3, 1); - } + return (bool)Platform::Numbers::Bit::PartialRead(value, 3, 1); } + } - public: void SetRightIsChildValue(LinkAddressType* storedValue, bool value) +public: + void SetRightIsChildValue(LinkAddressType* storedValue, bool value) + { { - { - auto previousValue = *storedValue; - auto modified = Platform::Numbers::Bit::PartialWrite(previousValue, (LinkAddressType)value, 3, 1); - *storedValue = modified; - } + auto previousValue = *storedValue; + auto modified = + Platform::Numbers::Bit::PartialWrite(previousValue, (LinkAddressType)value, 3, 1); + *storedValue = modified; } + } - public: bool IsChild(LinkAddressType parent, LinkAddressType possibleChild) - { - auto parentSize = this->GetSize(parent); - auto childSize = this->GetSizeOrZero(possibleChild); - return childSize > 0 && (childSize <= parentSize); - } +public: + bool IsChild(LinkAddressType parent, LinkAddressType possibleChild) + { + auto parentSize = this->GetSize(parent); + auto childSize = this->GetSizeOrZero(possibleChild); + return childSize > 0 && (childSize <= parentSize); + } - public: std::int8_t GetBalanceValue(LinkAddressType storedValue) +public: + std::int8_t GetBalanceValue(LinkAddressType storedValue) + { { - { - auto value = (std::int32_t)Platform::Numbers::Bit::PartialRead(storedValue, 0, 3); - value |= 0xF8 * ((value & 4) >> 2); - return (std::int8_t)value; - } + auto value = (std::int32_t)Platform::Numbers::Bit::PartialRead(storedValue, 0, 3); + value |= 0xF8 * ((value & 4) >> 2); + return (std::int8_t)value; } + } - public: void SetBalanceValue(LinkAddressType* storedValue, std::int8_t value) +public: + void SetBalanceValue(LinkAddressType* storedValue, std::int8_t value) + { { - { - auto packagedValue = (LinkAddressType)((((std::uint8_t)value >> 5) & 4) | (value & 3)); - auto modified = Platform::Numbers::Bit::PartialWrite(*storedValue, packagedValue, 0, 3); - *storedValue = modified; - } + auto packagedValue = (LinkAddressType)((((std::uint8_t)value >> 5) & 4) | (value & 3)); + auto modified = Platform::Numbers::Bit::PartialWrite(*storedValue, packagedValue, 0, 3); + *storedValue = modified; } - - }; -} \ No newline at end of file + } +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic \ No newline at end of file diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksRecursionlessSizeBalancedTreeMethodsBase.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksRecursionlessSizeBalancedTreeMethodsBase.h index ce6fa2201..7be787d23 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksRecursionlessSizeBalancedTreeMethodsBase.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksRecursionlessSizeBalancedTreeMethodsBase.h @@ -1,185 +1,225 @@ namespace Platform::Data::Doublets::Memory::United::Generic { - template - struct LinksRecursionlessSizeBalancedTreeMethodsBase : public Platform::Collections::Methods::Trees::RecursionlessSizeBalancedTreeMethods - { - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - static constexpr LinksConstants Constants = LinksOptionsType::Constants; +template +struct LinksRecursionlessSizeBalancedTreeMethodsBase + : public Platform::Collections::Methods::Trees::RecursionlessSizeBalancedTreeMethods< + Self, typename TLinksOptions::LinkAddressType> +{ + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + static constexpr LinksConstants Constants = LinksOptionsType::Constants; - public: using methods = Platform::Collections::Methods::Trees::RecursionlessSizeBalancedTreeMethods; +public: + using methods = Platform::Collections::Methods::Trees::RecursionlessSizeBalancedTreeMethods; - public: std::byte* const Links; - public: std::byte* const Header; +public: + std::byte* const Links; - public: LinksRecursionlessSizeBalancedTreeMethodsBase(std::byte* storage, std::byte* header) - : Links(storage), Header(header) {} +public: + std::byte* const Header; - public: LinkAddressType GetTreeRoot() { return this->object().GetTreeRoot(); } +public: + LinksRecursionlessSizeBalancedTreeMethodsBase(std::byte* storage, std::byte* header) + : Links(storage), Header(header) + { + } - public: LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->object().GetBasePartValue(linkAddress); } +public: + LinkAddressType GetTreeRoot() { return this->object().GetTreeRoot(); } - public: bool FirstIsToTheRightOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, LinkAddressType rootTarget) { return this->object().FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget); } +public: + LinkAddressType GetBasePartValue(LinkAddressType linkAddress) + { + return this->object().GetBasePartValue(linkAddress); + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, LinkAddressType rootTarget) { return this->object().FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget); } +public: + bool FirstIsToTheRightOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, + LinkAddressType rootTarget) + { + return this->object().FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget); + } - public: auto& GetHeaderReference() { return *reinterpret_cast*>(Header); } +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType source, LinkAddressType target, LinkAddressType rootSource, + LinkAddressType rootTarget) + { + return this->object().FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget); + } - public: auto& GetLinkReference(LinkAddressType linkAddress) { return *(reinterpret_cast*>(Links) + linkAddress); } +public: + auto& GetHeaderReference() { return *reinterpret_cast*>(Header); } - public: LinkType GetLinkValues(LinkAddressType linkIndex) - { - auto& link = GetLinkReference(linkIndex); - return LinkType{linkIndex, link.Source, link.Target}; - } +public: + auto& GetLinkReference(LinkAddressType linkAddress) + { + return *(reinterpret_cast*>(Links) + linkAddress); + } + +public: + LinkType GetLinkValues(LinkAddressType linkIndex) + { + auto& link = GetLinkReference(linkIndex); + return LinkType{linkIndex, link.Source, link.Target}; + } + +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) +public: + bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + secondLink.Target); + } + + auto operator[](std::size_t index) + { + auto root = GetTreeRoot(); + if (index >= this->object.GetSize(root)) { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + return 0; } - - public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + while (root != 0) { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + auto left = GetLeftOrDefault(root); + auto leftSize = GetSizeOrZero(left); + if (index < leftSize) + { + root = left; + continue; + } + if (index == leftSize) + { + return root; + } + root = GetRightOrDefault(root); + index = index - (leftSize + 1); } + return 0; + } - auto operator[](std::size_t index) +public: + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + auto root = this->GetTreeRoot(); + while (root != 0) { - auto root = GetTreeRoot(); - if (index >= this->object.GetSize(root)) + auto& rootLink = this->GetLinkReference(root); + auto rootSource = rootLink.Source; + auto rootTarget = rootLink.Target; + if (this->FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget)) { - return 0; + root = this->GetLeftOrDefault(root); } - while (root != 0) + else if (this->FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget)) { - auto left = GetLeftOrDefault(root); - auto leftSize = GetSizeOrZero(left); - if (index < leftSize) - { - root = left; - continue; - } - if (index == leftSize) - { - return root; - } - root = GetRightOrDefault(root); - index = index - (leftSize + 1); + root = this->GetRightOrDefault(root); + } + else + { + return root; } - return 0; } + return 0; + } - public: LinkAddressType Search(LinkAddressType source, LinkAddressType target) +public: + LinkAddressType CountUsages(LinkAddressType linkAddress) + { + auto root = this->GetTreeRoot(); + auto total = this->object().GetSize(root); + auto totalRightIgnore = 0; + while (root != 0) { - auto root = this->GetTreeRoot(); - while (root != 0) + auto base = this->GetBasePartValue(root); + if (base <= linkAddress) { - auto& rootLink = this->GetLinkReference(root); - auto rootSource = rootLink.Source; - auto rootTarget = rootLink.Target; - if (this->FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget)) - { - root = this->GetLeftOrDefault(root); - } - else if (this->FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget)) - { - root = this->GetRightOrDefault(root); - } - else - { - return root; - } + root = this->GetRightOrDefault(root); + } + else + { + totalRightIgnore = totalRightIgnore + (this->GetRightSize(root) + 1); + root = this->GetLeftOrDefault(root); } - return 0; } - - public: LinkAddressType CountUsages(LinkAddressType linkAddress) + root = this->GetTreeRoot(); + auto totalLeftIgnore = 0; + while (root != 0) { - auto root = this->GetTreeRoot(); - auto total = this->object().GetSize(root); - auto totalRightIgnore = 0; - while (root != 0) + auto base = this->GetBasePartValue(root); + if (base >= linkAddress) { - auto base = this->GetBasePartValue(root); - if (base <= linkAddress) - { - root = this->GetRightOrDefault(root); - } - else - { - totalRightIgnore = totalRightIgnore + (this->GetRightSize(root) + 1); - root = this->GetLeftOrDefault(root); - } + root = this->GetLeftOrDefault(root); } - root = this->GetTreeRoot(); - auto totalLeftIgnore = 0; - while (root != 0) + else { - auto base = this->GetBasePartValue(root); - if (base >= linkAddress) - { - root = this->GetLeftOrDefault(root); - } - else - { - totalLeftIgnore = totalLeftIgnore + (this->GetLeftSize(root) + 1); - root = this->GetRightOrDefault(root); - } + totalLeftIgnore = totalLeftIgnore + (this->GetLeftSize(root) + 1); + root = this->GetRightOrDefault(root); } - return total - totalRightIgnore - totalLeftIgnore; } + return total - totalRightIgnore - totalLeftIgnore; + } - public: LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) { return this->EachUsageCore(base, this->GetTreeRoot(), handler); } +public: + LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) + { + return this->EachUsageCore(base, this->GetTreeRoot(), handler); + } - private: LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType linkAddress, const ReadHandlerType& handler) - { - auto $continue = Constants.Continue; - auto $break = Constants.Break; +private: + LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType linkAddress, const ReadHandlerType& handler) + { + auto $continue = Constants.Continue; + auto $break = Constants.Break; - if (linkAddress == 0) + if (linkAddress == 0) + { + return $continue; + } + auto linkBasePart = this->GetBasePartValue(linkAddress); + if (linkBasePart > (base)) + { + if ((this->EachUsageCore(base, this->GetLeftOrDefault(linkAddress), handler) == $break)) + { + return $break; + } + } + else if (linkBasePart < base) + { + if ((this->EachUsageCore(base, this->GetRightOrDefault(linkAddress), handler) == $break)) { - return $continue; + return $break; } - auto linkBasePart = this->GetBasePartValue(linkAddress); - if (linkBasePart > (base)) + } + else + { + auto link = this->GetLinkValues(linkAddress); + if (handler(link) == ($break)) { - if ((this->EachUsageCore(base, this->GetLeftOrDefault(linkAddress), handler) == $break)) - { - return $break; - } + return $break; } - else if (linkBasePart < base) + if ((this->EachUsageCore(base, this->GetLeftOrDefault(linkAddress), handler) == $break)) { - if ((this->EachUsageCore(base, this->GetRightOrDefault(linkAddress), handler) == $break)) - { - return $break; - } + return $break; } - else + if ((this->EachUsageCore(base, this->GetRightOrDefault(linkAddress), handler) == $break)) { - auto link = this->GetLinkValues(linkAddress); - if (handler(link) == ($break)) - { - return $break; - } - if ((this->EachUsageCore(base, this->GetLeftOrDefault(linkAddress), handler) == $break)) - { - return $break; - } - if ((this->EachUsageCore(base, this->GetRightOrDefault(linkAddress), handler) == $break)) - { - return $break; - } + return $break; } - return $continue; } - }; -} \ No newline at end of file + return $continue; + } +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic \ No newline at end of file diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSizeBalancedTreeMethodsBase.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSizeBalancedTreeMethodsBase.h index 482e53c6b..8c6458fd7 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSizeBalancedTreeMethodsBase.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSizeBalancedTreeMethodsBase.h @@ -1,175 +1,198 @@ namespace Platform::Data::Doublets::Memory::United::Generic { - template - struct LinksSizeBalancedTreeMethodsBase : public Platform::Collections::Methods::Trees::SizeBalancedTreeMethods - { - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - static constexpr LinksConstants Constants = LinksOptionsType::Constants; +template +struct LinksSizeBalancedTreeMethodsBase + : public Platform::Collections::Methods::Trees::SizeBalancedTreeMethods +{ + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + static constexpr LinksConstants Constants = LinksOptionsType::Constants; - public: using methods = Platform::Collections::Methods::Trees::SizeBalancedTreeMethods; +public: + using methods = Platform::Collections::Methods::Trees::SizeBalancedTreeMethods; - public: std::byte* const Links; - public: std::byte* const Header; +public: + std::byte* const Links; - public: LinksSizeBalancedTreeMethodsBase(std::byte* storage, std::byte* header) - : Links(storage), Header(header) {} +public: + std::byte* const Header; - public: auto& GetHeaderReference() { return *reinterpret_cast*>(Header); } +public: + LinksSizeBalancedTreeMethodsBase(std::byte* storage, std::byte* header) : Links(storage), Header(header) {} - public: auto& GetLinkReference(LinkAddressType linkAddress) { return *(reinterpret_cast*>(Links) + linkAddress); } +public: + auto& GetHeaderReference() { return *reinterpret_cast*>(Header); } - public: LinkType GetLinkValues(LinkAddressType linkIndex) - { - auto& link = GetLinkReference(linkIndex); - return LinkType{linkIndex, link.Source, link.Target}; - } +public: + auto& GetLinkReference(LinkAddressType linkAddress) + { + return *(reinterpret_cast*>(Links) + linkAddress); + } + +public: + LinkType GetLinkValues(LinkAddressType linkIndex) + { + auto& link = GetLinkReference(linkIndex); + return LinkType{linkIndex, link.Source, link.Target}; + } + +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->object().FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + secondLink.Target); + } + +public: + bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->object().FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + secondLink.Target); + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + auto operator[](std::size_t index) + { + auto root = this->object().GetTreeRoot(); + if (index >= this->object().GetSize(root)) { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->object().FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + return 0; } - - public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + while (root != 0) { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->object().FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + auto left = GetLeftOrDefault(root); + auto leftSize = GetSizeOrZero(left); + if (index < leftSize) + { + root = left; + continue; + } + if (index == leftSize) + { + return root; + } + root = GetRightOrDefault(root); + index = index - (leftSize + 1); } + return 0; + } - auto operator[](std::size_t index) +public: + LinkAddressType Search(LinkAddressType source, LinkAddressType target) + { + auto root = this->object().GetTreeRoot(); + while (root != 0) { - auto root = this->object().GetTreeRoot(); - if (index >= this->object().GetSize(root)) + auto& rootLink = this->GetLinkReference(root); + auto rootSource = rootLink.Source; + auto rootTarget = rootLink.Target; + if (this->object().FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget)) { - return 0; + root = this->GetLeftOrDefault(root); } - while (root != 0) + else if (this->object().FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget)) { - auto left = GetLeftOrDefault(root); - auto leftSize = GetSizeOrZero(left); - if (index < leftSize) - { - root = left; - continue; - } - if (index == leftSize) - { - return root; - } - root = GetRightOrDefault(root); - index = index - (leftSize + 1); + root = this->GetRightOrDefault(root); + } + else + { + return root; } - return 0; } + return 0; + } - public: LinkAddressType Search(LinkAddressType source, LinkAddressType target) +public: + LinkAddressType CountUsages(LinkAddressType linkAddress) + { + auto root = this->object().GetTreeRoot(); + auto total = this->object().GetSize(root); + auto totalRightIgnore = 0; + while (root != 0) { - auto root = this->object().GetTreeRoot(); - while (root != 0) + auto base = this->object().GetBasePartValue(root); + if (base <= linkAddress) { - auto& rootLink = this->GetLinkReference(root); - auto rootSource = rootLink.Source; - auto rootTarget = rootLink.Target; - if (this->object().FirstIsToTheLeftOfSecond(source, target, rootSource, rootTarget)) - { - root = this->GetLeftOrDefault(root); - } - else if (this->object().FirstIsToTheRightOfSecond(source, target, rootSource, rootTarget)) - { - root = this->GetRightOrDefault(root); - } - else - { - return root; - } + root = this->GetRightOrDefault(root); + } + else + { + totalRightIgnore = totalRightIgnore + (this->GetRightSize(root) + 1); + root = this->GetLeftOrDefault(root); } - return 0; } - - public: LinkAddressType CountUsages(LinkAddressType linkAddress) + root = this->object().GetTreeRoot(); + auto totalLeftIgnore = 0; + while (root != 0) { - auto root = this->object().GetTreeRoot(); - auto total = this->object().GetSize(root); - auto totalRightIgnore = 0; - while (root != 0) + auto base = this->object().GetBasePartValue(root); + if (base >= linkAddress) { - auto base = this->object().GetBasePartValue(root); - if (base <= linkAddress) - { - root = this->GetRightOrDefault(root); - } - else - { - totalRightIgnore = totalRightIgnore + (this->GetRightSize(root) + 1); - root = this->GetLeftOrDefault(root); - } + root = this->GetLeftOrDefault(root); } - root = this->object().GetTreeRoot(); - auto totalLeftIgnore = 0; - while (root != 0) + else { - auto base = this->object().GetBasePartValue(root); - if (base >= linkAddress) - { - root = this->GetLeftOrDefault(root); - } - else - { - totalLeftIgnore = totalLeftIgnore + (this->GetLeftSize(root) + 1); - root = this->GetRightOrDefault(root); - } + totalLeftIgnore = totalLeftIgnore + (this->GetLeftSize(root) + 1); + root = this->GetRightOrDefault(root); } - return total - totalRightIgnore - totalLeftIgnore; } + return total - totalRightIgnore - totalLeftIgnore; + } - public: LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) { return this->EachUsageCore(base, this->object().GetTreeRoot(), handler); } +public: + LinkAddressType EachUsage(LinkAddressType base, const ReadHandlerType& handler) + { + return this->EachUsageCore(base, this->object().GetTreeRoot(), handler); + } - private: LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType linkAddress, const ReadHandlerType& handler) +private: + LinkAddressType EachUsageCore(LinkAddressType base, LinkAddressType linkAddress, const ReadHandlerType& handler) + { + auto $continue = Constants.Continue; + if (linkAddress == 0) { - auto $continue = Constants.Continue; - if (linkAddress == 0) + return $continue; + } + auto linkBasePart = this->object().GetBasePartValue(linkAddress); + auto $break = Constants.Break; + if (linkBasePart > (base)) + { + if ((this->EachUsageCore(base, this->GetLeftOrDefault(linkAddress), handler) == $break)) + { + return $break; + } + } + else if (linkBasePart < base) + { + if ((this->EachUsageCore(base, this->GetRightOrDefault(linkAddress), handler) == $break)) { - return $continue; + return $break; } - auto linkBasePart = this->object().GetBasePartValue(linkAddress); - auto $break = Constants.Break; - if (linkBasePart > (base)) + } + else + { + auto link = this->GetLinkValues(linkAddress); + if (handler(link) == ($break)) { - if ((this->EachUsageCore(base, this->GetLeftOrDefault(linkAddress), handler) == $break)) - { - return $break; - } + return $break; } - else if (linkBasePart < base) + if ((this->EachUsageCore(base, this->GetLeftOrDefault(linkAddress), handler) == $break)) { - if ((this->EachUsageCore(base, this->GetRightOrDefault(linkAddress), handler) == $break)) - { - return $break; - } + return $break; } - else + if ((this->EachUsageCore(base, this->GetRightOrDefault(linkAddress), handler) == $break)) { - auto link = this->GetLinkValues(linkAddress); - if (handler(link) == ($break)) - { - return $break; - } - if ((this->EachUsageCore(base, this->GetLeftOrDefault(linkAddress), handler) == $break)) - { - return $break; - } - if ((this->EachUsageCore(base, this->GetRightOrDefault(linkAddress), handler) == $break)) - { - return $break; - } + return $break; } - return $continue; } - }; -} + return $continue; + } +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesAvlBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesAvlBalancedTreeMethods.h index 625e7efe0..0b552b740 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesAvlBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesAvlBalancedTreeMethods.h @@ -1,97 +1,139 @@ namespace Platform::Data::Doublets::Memory::United::Generic { - template - struct LinksSourcesAvlBalancedTreeMethods : public LinksAvlBalancedTreeMethodsBase, TLinksOptions> - { - using base = LinksAvlBalancedTreeMethodsBase, TLinksOptions>; - using typename base::LinkAddressType; - using typename base::LinkType; - using typename base::ReadHandlerType; - using base::FirstIsToTheLeftOfSecond; - using base::FirstIsToTheRightOfSecond; - - public: LinksSourcesAvlBalancedTreeMethods(std::byte* storage, std::byte* header) : base(storage, header) { } - - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsSource; } - - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsSource; } - - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsSource; } - - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsSource; } +template +struct LinksSourcesAvlBalancedTreeMethods + : public LinksAvlBalancedTreeMethodsBase, TLinksOptions> +{ + using base = LinksAvlBalancedTreeMethodsBase, TLinksOptions>; + using base::FirstIsToTheLeftOfSecond; + using base::FirstIsToTheRightOfSecond; + using typename base::LinkAddressType; + using typename base::LinkType; + using typename base::ReadHandlerType; - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsSource = left; } +public: + LinksSourcesAvlBalancedTreeMethods(std::byte* storage, std::byte* header) : base(storage, header) {} - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsSource = right; } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsSource; } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetSizeValue(this->GetLinkReference(node).SizeAsSource); } +public: + LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsSource; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->SetSizeValue(&this->GetLinkReference(node).SizeAsSource, size); } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsSource; } - public: bool GetLeftIsChild(LinkAddressType node) { - return this->GetLeftIsChildValue(this->GetLinkReference(node).SizeAsSource); - } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsSource; } - public: void SetLeftIsChild(LinkAddressType node, bool value) { - this->SetLeftIsChildValue(&this->GetLinkReference(node).SizeAsSource, value); - } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsSource = left; } - public: bool GetRightIsChild(LinkAddressType node) { - return this->GetRightIsChildValue(this->GetLinkReference(node).SizeAsSource); - } - - public: void SetRightIsChild(LinkAddressType node, bool value) { - this->SetRightIsChildValue(&this->GetLinkReference(node).SizeAsSource, value); - } +public: + void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsSource = right; } - public: int8_t GetBalance(LinkAddressType node) { - return this->GetBalanceValue(this->GetLinkReference(node).SizeAsSource); - } +public: + LinkAddressType GetSize(LinkAddressType node) + { + return this->GetSizeValue(this->GetLinkReference(node).SizeAsSource); + } - public: void SetBalance(LinkAddressType node, int8_t value) { - this->SetBalanceValue(&this->GetLinkReference(node).SizeAsSource, value); - } +public: + void SetSize(LinkAddressType node, LinkAddressType size) + { + this->SetSizeValue(&this->GetLinkReference(node).SizeAsSource, size); + } - public: LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsSource; } +public: + bool GetLeftIsChild(LinkAddressType node) + { + return this->GetLeftIsChildValue(this->GetLinkReference(node).SizeAsSource); + } - public: LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Source; } +public: + void SetLeftIsChild(LinkAddressType node, bool value) + { + this->SetLeftIsChildValue(&this->GetLinkReference(node).SizeAsSource, value); + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstSource < secondSource) || (firstSource == secondSource && firstTarget < secondTarget); } +public: + bool GetRightIsChild(LinkAddressType node) + { + return this->GetRightIsChildValue(this->GetLinkReference(node).SizeAsSource); + } - public: bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return firstSource > secondSource || (firstSource == secondSource && firstTarget > secondTarget); } +public: + void SetRightIsChild(LinkAddressType node, bool value) + { + this->SetRightIsChildValue(&this->GetLinkReference(node).SizeAsSource, value); + } - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkReference(node); - link.LeftAsSource = 0; - link.RightAsSource = 0; - link.SizeAsSource = 0; - } +public: + int8_t GetBalance(LinkAddressType node) { return this->GetBalanceValue(this->GetLinkReference(node).SizeAsSource); } - // public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) - // { - // auto& firstLink = this->GetLinkReference(first); - // auto& secondLink = this->GetLinkReference(second); - // return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - // } +public: + void SetBalance(LinkAddressType node, int8_t value) + { + this->SetBalanceValue(&this->GetLinkReference(node).SizeAsSource, value); + } - // public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) - // { - // auto& firstLink = this->GetLinkReference(first); - // auto& secondLink = this->GetLinkReference(second); - // return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - // } +public: + LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsSource; } - public: +public: + LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Source; } - LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstSource < secondSource) || (firstSource == secondSource && firstTarget < secondTarget); + } - LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } +public: + bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return firstSource > secondSource || (firstSource == secondSource && firstTarget > secondTarget); + } - LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) { return base::EachUsage(root, handler); } +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkReference(node); + link.LeftAsSource = 0; + link.RightAsSource = 0; + link.SizeAsSource = 0; + } + + // public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + // { + // auto& firstLink = this->GetLinkReference(first); + // auto& secondLink = this->GetLinkReference(second); + // return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + // secondLink.Target); + // } + + // public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + // { + // auto& firstLink = this->GetLinkReference(first); + // auto& secondLink = this->GetLinkReference(second); + // return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + // secondLink.Target); + // } + +public: + LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } + + LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } + + LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) + { + return base::EachUsage(root, handler); + } - void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } + void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } - void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } - }; -} \ No newline at end of file + void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic \ No newline at end of file diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesRecursionlessSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesRecursionlessSizeBalancedTreeMethods.h index a16a39429..bcf119683 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesRecursionlessSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesRecursionlessSizeBalancedTreeMethods.h @@ -1,72 +1,102 @@ namespace Platform::Data::Doublets::Memory::United::Generic { - template - struct LinksSourcesRecursionlessSizeBalancedTreeMethods - : public LinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions> - { - using base = LinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions>; - using typename base::LinkAddressType; - using typename base::LinkType; - using typename base::ReadHandlerType; - - public: LinksSourcesRecursionlessSizeBalancedTreeMethods(std::byte* storage, std::byte* header) : base( storage, header) { } - - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsSource; } +template +struct LinksSourcesRecursionlessSizeBalancedTreeMethods + : public LinksRecursionlessSizeBalancedTreeMethodsBase< + LinksSourcesRecursionlessSizeBalancedTreeMethods, TLinksOptions> +{ + using base = + LinksRecursionlessSizeBalancedTreeMethodsBase, + TLinksOptions>; + using typename base::LinkAddressType; + using typename base::LinkType; + using typename base::ReadHandlerType; - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsSource; } +public: + LinksSourcesRecursionlessSizeBalancedTreeMethods(std::byte* storage, std::byte* header) : base(storage, header) {} - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsSource; } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsSource; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsSource; } +public: + LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsSource; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsSource = left; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsSource; } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsSource = right; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsSource; } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkReference(node).SizeAsSource; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsSource = left; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkReference(node).SizeAsSource = size; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsSource = right; } - public: LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsSource; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkReference(node).SizeAsSource; } - public: LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Source; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkReference(node).SizeAsSource = size; } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstSource < secondSource) || (firstSource == secondSource && firstTarget < secondTarget); } +public: + LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsSource; } - public: bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return firstSource > secondSource || (firstSource == secondSource && firstTarget > secondTarget); } +public: + LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Source; } - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkReference(node); - link.LeftAsSource = 0; - link.RightAsSource = 0; - link.SizeAsSource = 0; - } +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstSource < secondSource) || (firstSource == secondSource && firstTarget < secondTarget); + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) - { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - } +public: + bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return firstSource > secondSource || (firstSource == secondSource && firstTarget > secondTarget); + } - public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) - { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - } +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkReference(node); + link.LeftAsSource = 0; + link.RightAsSource = 0; + link.SizeAsSource = 0; + } + +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + } - public: +public: + bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + secondLink.Target); + } - LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } +public: + LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } - LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } + LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } - LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) { return base::EachUsage(root, handler); } + LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) + { + return base::EachUsage(root, handler); + } - void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } + void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } - void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } - }; -} \ No newline at end of file + void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic \ No newline at end of file diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesSizeBalancedTreeMethods.h index d53b1a010..c91aa6a36 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksSourcesSizeBalancedTreeMethods.h @@ -1,72 +1,99 @@ namespace Platform::Data::Doublets::Memory::United::Generic { - template - struct LinksSourcesSizeBalancedTreeMethods - : public LinksSizeBalancedTreeMethodsBase, TLinksOptions> - { - using base = LinksSizeBalancedTreeMethodsBase, TLinksOptions>; - using typename base::LinkAddressType; - using typename base::LinkType; - using typename base::ReadHandlerType; - - public: LinksSourcesSizeBalancedTreeMethods(std::byte* storage, std::byte* header) : base( storage, header) { } - - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsSource; } +template +struct LinksSourcesSizeBalancedTreeMethods + : public LinksSizeBalancedTreeMethodsBase, TLinksOptions> +{ + using base = LinksSizeBalancedTreeMethodsBase, TLinksOptions>; + using typename base::LinkAddressType; + using typename base::LinkType; + using typename base::ReadHandlerType; - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsSource; } +public: + LinksSourcesSizeBalancedTreeMethods(std::byte* storage, std::byte* header) : base(storage, header) {} - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsSource; } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsSource; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsSource; } +public: + LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsSource; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsSource = left; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsSource; } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsSource = right; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsSource; } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkReference(node).SizeAsSource; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsSource = left; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkReference(node).SizeAsSource = size; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsSource = right; } - public: LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsSource; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkReference(node).SizeAsSource; } - public: LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Source; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkReference(node).SizeAsSource = size; } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstSource < secondSource) || (firstSource == secondSource && firstTarget < secondTarget); } +public: + LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsSource; } - public: bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return firstSource > secondSource || (firstSource == secondSource && firstTarget > secondTarget); } +public: + LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Source; } - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkReference(node); - link.LeftAsSource = 0; - link.RightAsSource = 0; - link.SizeAsSource = 0; - } +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstSource < secondSource) || (firstSource == secondSource && firstTarget < secondTarget); + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) - { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - } +public: + bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return firstSource > secondSource || (firstSource == secondSource && firstTarget > secondTarget); + } - public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) - { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - } +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkReference(node); + link.LeftAsSource = 0; + link.RightAsSource = 0; + link.SizeAsSource = 0; + } + +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + } - public: +public: + bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + secondLink.Target); + } - LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } +public: + LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } - LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } + LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } - LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) { return base::EachUsage(root, handler); } + LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) + { + return base::EachUsage(root, handler); + } - void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } + void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } - void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } - }; -} + void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsAvlBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsAvlBalancedTreeMethods.h index b1465301e..113f62a4c 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsAvlBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsAvlBalancedTreeMethods.h @@ -1,97 +1,139 @@ namespace Platform::Data::Doublets::Memory::United::Generic { - template - struct LinksTargetsAvlBalancedTreeMethods : public LinksAvlBalancedTreeMethodsBase, TLinksOptions> - { - using base = LinksAvlBalancedTreeMethodsBase, TLinksOptions>; - using typename base::LinkAddressType; - using typename base::LinkType; - using typename base::ReadHandlerType; - using base::FirstIsToTheLeftOfSecond; - using base::FirstIsToTheRightOfSecond; +template +struct LinksTargetsAvlBalancedTreeMethods + : public LinksAvlBalancedTreeMethodsBase, TLinksOptions> +{ + using base = LinksAvlBalancedTreeMethodsBase, TLinksOptions>; + using base::FirstIsToTheLeftOfSecond; + using base::FirstIsToTheRightOfSecond; + using typename base::LinkAddressType; + using typename base::LinkType; + using typename base::ReadHandlerType; - public: LinksTargetsAvlBalancedTreeMethods(std::byte* storage, std::byte* header) : base(storage, header) { } +public: + LinksTargetsAvlBalancedTreeMethods(std::byte* storage, std::byte* header) : base(storage, header) {} - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsTarget; } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsTarget; } - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsTarget; } +public: + LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsTarget; } - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsTarget; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsTarget; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsTarget; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsTarget; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsTarget = left; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsTarget = left; } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsTarget = right; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsTarget = right; } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetSizeValue(this->GetLinkReference(node).SizeAsTarget); } +public: + LinkAddressType GetSize(LinkAddressType node) + { + return this->GetSizeValue(this->GetLinkReference(node).SizeAsTarget); + } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->SetSizeValue(&this->GetLinkReference(node).SizeAsTarget, size); } +public: + void SetSize(LinkAddressType node, LinkAddressType size) + { + this->SetSizeValue(&this->GetLinkReference(node).SizeAsTarget, size); + } - public: bool GetLeftIsChild(LinkAddressType node) { - return this->GetLeftIsChildValue(this->GetLinkReference(node).SizeAsTarget); - } +public: + bool GetLeftIsChild(LinkAddressType node) + { + return this->GetLeftIsChildValue(this->GetLinkReference(node).SizeAsTarget); + } - public: void SetLeftIsChild(LinkAddressType node, bool value) { - this->SetLeftIsChildValue(&this->GetLinkReference(node).SizeAsTarget, value); - } +public: + void SetLeftIsChild(LinkAddressType node, bool value) + { + this->SetLeftIsChildValue(&this->GetLinkReference(node).SizeAsTarget, value); + } - public: bool GetRightIsChild(LinkAddressType node) { - return this->GetRightIsChildValue(this->GetLinkReference(node).SizeAsTarget); - } +public: + bool GetRightIsChild(LinkAddressType node) + { + return this->GetRightIsChildValue(this->GetLinkReference(node).SizeAsTarget); + } - public: void SetRightIsChild(LinkAddressType node, bool value) { - this->SetRightIsChildValue(&this->GetLinkReference(node).SizeAsTarget, value); - } +public: + void SetRightIsChild(LinkAddressType node, bool value) + { + this->SetRightIsChildValue(&this->GetLinkReference(node).SizeAsTarget, value); + } - public: int8_t GetBalance(LinkAddressType node) { - return this->GetBalanceValue(this->GetLinkReference(node).SizeAsTarget); - } +public: + int8_t GetBalance(LinkAddressType node) { return this->GetBalanceValue(this->GetLinkReference(node).SizeAsTarget); } - public: void SetBalance(LinkAddressType node, int8_t value) { - this->SetBalanceValue(&this->GetLinkReference(node).SizeAsTarget, value); - } +public: + void SetBalance(LinkAddressType node, int8_t value) + { + this->SetBalanceValue(&this->GetLinkReference(node).SizeAsTarget, value); + } - public: LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsTarget; } +public: + LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsTarget; } - public: LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Target; } +public: + LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Target; } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstTarget < secondTarget) || (firstTarget == secondTarget && firstSource < secondSource); } +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstTarget < secondTarget) || (firstTarget == secondTarget && firstSource < secondSource); + } - public: bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstTarget > secondTarget) || (firstTarget == secondTarget && firstSource > secondSource); } +public: + bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstTarget > secondTarget) || (firstTarget == secondTarget && firstSource > secondSource); + } - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkReference(node); - link.LeftAsTarget = 0; - link.RightAsTarget = 0; - link.SizeAsTarget = 0; - } +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkReference(node); + link.LeftAsTarget = 0; + link.RightAsTarget = 0; + link.SizeAsTarget = 0; + } // public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) // { // auto& firstLink = this->GetLinkReference(first); // auto& secondLink = this->GetLinkReference(second); - // return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + // return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + // secondLink.Target); // } // public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) // { // auto& firstLink = this->GetLinkReference(first); // auto& secondLink = this->GetLinkReference(second); - // return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + // return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + // secondLink.Target); // } - public: - - LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } +public: + LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } - LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } + LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } - LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) { return base::EachUsage(root, handler); } + LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) + { + return base::EachUsage(root, handler); + } - void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } + void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } - void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } - }; -} + void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsRecursionlessSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsRecursionlessSizeBalancedTreeMethods.h index 81de600fc..d0b4c825b 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsRecursionlessSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsRecursionlessSizeBalancedTreeMethods.h @@ -1,72 +1,102 @@ namespace Platform::Data::Doublets::Memory::United::Generic { - template - class LinksTargetsRecursionlessSizeBalancedTreeMethods - : public LinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions> - { - using base = LinksRecursionlessSizeBalancedTreeMethodsBase, TLinksOptions>; - using typename base::LinkAddressType; - using typename base::LinkType; - using typename base::ReadHandlerType; - - public: LinksTargetsRecursionlessSizeBalancedTreeMethods(std::byte* storage, std::byte* header) : base(storage, header) { } - - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsTarget; } +template +class LinksTargetsRecursionlessSizeBalancedTreeMethods + : public LinksRecursionlessSizeBalancedTreeMethodsBase< + LinksTargetsRecursionlessSizeBalancedTreeMethods, TLinksOptions> +{ + using base = + LinksRecursionlessSizeBalancedTreeMethodsBase, + TLinksOptions>; + using typename base::LinkAddressType; + using typename base::LinkType; + using typename base::ReadHandlerType; - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsTarget; } +public: + LinksTargetsRecursionlessSizeBalancedTreeMethods(std::byte* storage, std::byte* header) : base(storage, header) {} - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsTarget; } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsTarget; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsTarget; } +public: + LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsTarget; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsTarget = left; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsTarget; } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsTarget = right; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsTarget; } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkReference(node).SizeAsTarget; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsTarget = left; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkReference(node).SizeAsTarget = size; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsTarget = right; } - public: LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsTarget; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkReference(node).SizeAsTarget; } - public: LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Target; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkReference(node).SizeAsTarget = size; } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstTarget < secondTarget) || (firstTarget == secondTarget && firstSource < secondSource); } +public: + LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsTarget; } - public: bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstTarget > secondTarget) || (firstTarget == secondTarget && firstSource > secondSource); } +public: + LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Target; } - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkReference(node); - link.LeftAsTarget = 0; - link.RightAsTarget = 0; - link.SizeAsTarget = 0; - } +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstTarget < secondTarget) || (firstTarget == secondTarget && firstSource < secondSource); + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) - { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - } +public: + bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstTarget > secondTarget) || (firstTarget == secondTarget && firstSource > secondSource); + } - public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) - { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - } +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkReference(node); + link.LeftAsTarget = 0; + link.RightAsTarget = 0; + link.SizeAsTarget = 0; + } + +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + } - public: +public: + bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + secondLink.Target); + } - LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } +public: + LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } - LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } + LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } - LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) { return base::EachUsage(root, handler); } + LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) + { + return base::EachUsage(root, handler); + } - void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } + void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } - void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } - }; -} \ No newline at end of file + void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic \ No newline at end of file diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsSizeBalancedTreeMethods.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsSizeBalancedTreeMethods.h index 2e19b965d..3c0c5ba71 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsSizeBalancedTreeMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/LinksTargetsSizeBalancedTreeMethods.h @@ -1,72 +1,99 @@ namespace Platform::Data::Doublets::Memory::United::Generic { - template - class LinksTargetsSizeBalancedTreeMethods - : public LinksSizeBalancedTreeMethodsBase, TLinksOptions> - { - using base = LinksSizeBalancedTreeMethodsBase, TLinksOptions>; - using typename base::LinkAddressType; - using typename base::LinkType; - using typename base::ReadHandlerType; - - public: LinksTargetsSizeBalancedTreeMethods(std::byte* storage, std::byte* header) : base(storage, header) { } - - public: LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsTarget; } +template +class LinksTargetsSizeBalancedTreeMethods + : public LinksSizeBalancedTreeMethodsBase, TLinksOptions> +{ + using base = LinksSizeBalancedTreeMethodsBase, TLinksOptions>; + using typename base::LinkAddressType; + using typename base::LinkType; + using typename base::ReadHandlerType; - public: LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsTarget; } +public: + LinksTargetsSizeBalancedTreeMethods(std::byte* storage, std::byte* header) : base(storage, header) {} - public: LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsTarget; } +public: + LinkAddressType* GetLeftReference(LinkAddressType node) { return &this->GetLinkReference(node).LeftAsTarget; } - public: LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsTarget; } +public: + LinkAddressType* GetRightReference(LinkAddressType node) { return &this->GetLinkReference(node).RightAsTarget; } - public: void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsTarget = left; } +public: + LinkAddressType GetLeft(LinkAddressType node) { return this->GetLinkReference(node).LeftAsTarget; } - public: void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsTarget = right; } +public: + LinkAddressType GetRight(LinkAddressType node) { return this->GetLinkReference(node).RightAsTarget; } - public: LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkReference(node).SizeAsTarget; } +public: + void SetLeft(LinkAddressType node, LinkAddressType left) { this->GetLinkReference(node).LeftAsTarget = left; } - public: void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkReference(node).SizeAsTarget = size; } +public: + void SetRight(LinkAddressType node, LinkAddressType right) { this->GetLinkReference(node).RightAsTarget = right; } - public: LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsTarget; } +public: + LinkAddressType GetSize(LinkAddressType node) { return this->GetLinkReference(node).SizeAsTarget; } - public: LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Target; } +public: + void SetSize(LinkAddressType node, LinkAddressType size) { this->GetLinkReference(node).SizeAsTarget = size; } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstTarget < secondTarget) || (firstTarget == secondTarget && firstSource < secondSource); } +public: + LinkAddressType GetTreeRoot() { return this->GetHeaderReference().RootAsTarget; } - public: bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, LinkAddressType secondSource, LinkAddressType secondTarget) { return (firstTarget > secondTarget) || (firstTarget == secondTarget && firstSource > secondSource); } +public: + LinkAddressType GetBasePartValue(LinkAddressType linkAddress) { return this->GetLinkReference(linkAddress).Target; } - public: void ClearNode(LinkAddressType node) - { - auto& link = this->GetLinkReference(node); - link.LeftAsTarget = 0; - link.RightAsTarget = 0; - link.SizeAsTarget = 0; - } +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstTarget < secondTarget) || (firstTarget == secondTarget && firstSource < secondSource); + } - public: bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) - { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - } +public: + bool FirstIsToTheRightOfSecond(LinkAddressType firstSource, LinkAddressType firstTarget, + LinkAddressType secondSource, LinkAddressType secondTarget) + { + return (firstTarget > secondTarget) || (firstTarget == secondTarget && firstSource > secondSource); + } - public: bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) - { - auto& firstLink = this->GetLinkReference(first); - auto& secondLink = this->GetLinkReference(second); - return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); - } +public: + void ClearNode(LinkAddressType node) + { + auto& link = this->GetLinkReference(node); + link.LeftAsTarget = 0; + link.RightAsTarget = 0; + link.SizeAsTarget = 0; + } + +public: + bool FirstIsToTheLeftOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->FirstIsToTheLeftOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, secondLink.Target); + } - public: +public: + bool FirstIsToTheRightOfSecond(LinkAddressType first, LinkAddressType second) + { + auto& firstLink = this->GetLinkReference(first); + auto& secondLink = this->GetLinkReference(second); + return this->FirstIsToTheRightOfSecond(firstLink.Source, firstLink.Target, secondLink.Source, + secondLink.Target); + } - LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } +public: + LinkAddressType CountUsages(LinkAddressType root) { return base::CountUsages(root); } - LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } + LinkAddressType Search(LinkAddressType source, LinkAddressType target) { return base::Search(source, target); } - LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) { return base::EachUsage(root, handler); } + LinkAddressType EachUsage(LinkAddressType root, const std::function& handler) + { + return base::EachUsage(root, handler); + } - void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } + void Detach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Detach(&root, linkIndex); } - void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } - }; -} + void Attach(LinkAddressType& root, LinkAddressType linkIndex) { base::methods::Attach(&root, linkIndex); } +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/UnitedMemoryLinks.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/UnitedMemoryLinks.h index c137b9a47..60b9fa690 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/UnitedMemoryLinks.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/UnitedMemoryLinks.h @@ -1,40 +1,41 @@ namespace Platform::Data::Doublets::Memory::United::Generic { - template< - typename TLinksOptions = Platform::Data::Doublets::LinksOptions<>, - typename TMemory = Platform::Memory::FileMappedResizableDirectMemory, - typename TSourceTreeMethods = LinksSourcesSizeBalancedTreeMethods, - typename TTargetTreeMethods = LinksTargetsSizeBalancedTreeMethods, - typename TUnusedLinks = UnusedLinksListMethods, - typename ...TBase> - struct UnitedMemoryLinks : public UnitedMemoryLinksBase, TLinksOptions, TMemory, TSourceTreeMethods, TTargetTreeMethods, TUnusedLinks, TBase...>, public std::enable_shared_from_this> - { - using base = UnitedMemoryLinksBase, TLinksOptions, TMemory, TSourceTreeMethods, TTargetTreeMethods, TUnusedLinks, TBase...>; - - using LinkAddressType = base::LinkAddressType; - using LinkType = base::LinkType; - using WriteHandlerType = base::WriteHandlerType; - using ReadHandlerType = base::ReadHandlerType; -// using base::Constants; - - public: - using base::DefaultLinksSizeStep; - - public: - using base::GetLinkStruct; +template , + typename TMemory = Platform::Memory::FileMappedResizableDirectMemory, + typename TSourceTreeMethods = LinksSourcesSizeBalancedTreeMethods, + typename TTargetTreeMethods = LinksTargetsSizeBalancedTreeMethods, + typename TUnusedLinks = UnusedLinksListMethods, typename... TBase> +struct UnitedMemoryLinks + : public UnitedMemoryLinksBase< + UnitedMemoryLinks, + TLinksOptions, TMemory, TSourceTreeMethods, TTargetTreeMethods, TUnusedLinks, TBase...>, + public std::enable_shared_from_this> +{ + using base = UnitedMemoryLinksBase< + UnitedMemoryLinks, + TLinksOptions, TMemory, TSourceTreeMethods, TTargetTreeMethods, TUnusedLinks, TBase...>; - public: - using base::Constants; + using LinkAddressType = base::LinkAddressType; + using LinkType = base::LinkType; + using WriteHandlerType = base::WriteHandlerType; + using ReadHandlerType = base::ReadHandlerType; + // using base::Constants; +public: + using base::DefaultLinksSizeStep; +public: + using base::GetLinkStruct; - // private: using base::_memory; +public: + using base::Constants; - // TODO: implicit constructor for Constants - public: - using base::base; + // private: using base::_memory; - }; -}// namespace Platform::Data::Doublets::Memory::United::Generic + // TODO: implicit constructor for Constants +public: + using base::base; +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/UnitedMemoryLinksBase.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/UnitedMemoryLinksBase.h index 1cf381a1a..2ab31bf4d 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/UnitedMemoryLinksBase.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/UnitedMemoryLinksBase.h @@ -1,480 +1,474 @@ namespace Platform::Data::Doublets::Memory::United::Generic { - template< - typename TSelf, - typename TLinkOptions, - typename TMemory, - typename TSourceTreeMethods, - typename TTargetTreeMethods, - typename TUnusedLinks, - typename... TBase> - struct UnitedMemoryLinksBase : public Interfaces::Polymorph - { - public: - using LinksOptionsType = TLinkOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - using LinkType = typename LinksOptionsType::LinkType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - static constexpr LinksConstants Constants = LinksOptionsType::Constants; +template +struct UnitedMemoryLinksBase : public Interfaces::Polymorph +{ +public: + using LinksOptionsType = TLinkOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + using LinkType = typename LinksOptionsType::LinkType; + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + static constexpr LinksConstants Constants = LinksOptionsType::Constants; - public: - static constexpr std::size_t LinkSizeInBytes = sizeof(RawLink); +public: + static constexpr std::size_t LinkSizeInBytes = sizeof(RawLink); - static constexpr std::size_t LinkHeaderSizeInBytes = sizeof(LinksHeader); + static constexpr std::size_t LinkHeaderSizeInBytes = sizeof(LinksHeader); - static constexpr std::size_t DefaultLinksSizeStep = LinkSizeInBytes * 1024 * 1024; + static constexpr std::size_t DefaultLinksSizeStep = LinkSizeInBytes * 1024 * 1024; - public: - TMemory _memory; +public: + TMemory _memory; - private: - std::byte* _header; +private: + std::byte* _header; - private: - std::byte* _links; +private: + std::byte* _links; - const std::size_t _memoryReservationStep; + const std::size_t _memoryReservationStep; - TTargetTreeMethods* _TargetsTreeMethods; + TTargetTreeMethods* _TargetsTreeMethods; - TSourceTreeMethods* _SourcesTreeMethods; + TSourceTreeMethods* _SourcesTreeMethods; - TUnusedLinks* _UnusedLinksListMethods; + TUnusedLinks* _UnusedLinksListMethods; - LinksHeader& GetHeaderReference() - { - return *reinterpret_cast*>(_header); - } + LinksHeader& GetHeaderReference() + { + return *reinterpret_cast*>(_header); + } - const LinksHeader& GetHeaderReference() const - { - return *reinterpret_cast*>(_header); - } + const LinksHeader& GetHeaderReference() const + { + return *reinterpret_cast*>(_header); + } - const RawLink& GetLinkReference(LinkAddressType linkIndex) const - { - return *(reinterpret_cast*>(_links) + linkIndex); - } + const RawLink& GetLinkReference(LinkAddressType linkIndex) const + { + return *(reinterpret_cast*>(_links) + linkIndex); + } - RawLink& GetLinkReference(LinkAddressType linkIndex) - { - return *(reinterpret_cast*>(_links) + linkIndex); - } + RawLink& GetLinkReference(LinkAddressType linkIndex) + { + return *(reinterpret_cast*>(_links) + linkIndex); + } - LinkAddressType GetTotal() const - { - auto& header = this->GetHeaderReference(); - return header.AllocatedLinks - header.FreeLinks; - } + LinkAddressType GetTotal() const + { + auto& header = this->GetHeaderReference(); + return header.AllocatedLinks - header.FreeLinks; + } - public: - public: - UnitedMemoryLinksBase(TMemory&& memory) : UnitedMemoryLinksBase(std::move(memory), DefaultLinksSizeStep) - { +public: +public: + UnitedMemoryLinksBase(TMemory&& memory) : UnitedMemoryLinksBase(std::move(memory), DefaultLinksSizeStep) {} - } + UnitedMemoryLinksBase(TMemory&& memory, std::uint64_t memoryReservationStep) + : _memory(std::move(memory)), _memoryReservationStep(memoryReservationStep) + { + Init(_memory, memoryReservationStep); + } - UnitedMemoryLinksBase(TMemory&& memory, std::uint64_t memoryReservationStep) : - _memory(std::move(memory)), _memoryReservationStep(memoryReservationStep) - { - Init(_memory, memoryReservationStep); - } + void Init(TMemory& memory, std::size_t memoryReservationStep) + { - void Init(TMemory& memory, std::size_t memoryReservationStep) + if (memory.ReservedCapacity() < memoryReservationStep) { + memory.ReservedCapacity(memoryReservationStep); + } + SetPointers(memory); - if (memory.ReservedCapacity() < memoryReservationStep) - { - memory.ReservedCapacity(memoryReservationStep); - } - SetPointers(memory); + auto& header = this->GetHeaderReference(); + memory.UsedCapacity((header.AllocatedLinks * LinkSizeInBytes) + LinkHeaderSizeInBytes); + header.ReservedLinks = (memory.ReservedCapacity() - LinkHeaderSizeInBytes) / LinkSizeInBytes; + } - auto& header = this->GetHeaderReference(); - memory.UsedCapacity((header.AllocatedLinks * LinkSizeInBytes) + LinkHeaderSizeInBytes); - header.ReservedLinks = (memory.ReservedCapacity() - LinkHeaderSizeInBytes) / LinkSizeInBytes; +public: + LinkAddressType Count(const LinkType& restriction) const + { + if (std::ranges::size(restriction) == 0) + { + return GetTotal(); } - - public: - LinkAddressType Count(const LinkType& restriction) const + auto any = Constants.Any; + auto index = restriction[Constants.IndexPart]; + if (std::ranges::size(restriction) == 1) { - if (std::ranges::size(restriction) == 0) + if (index == any) { return GetTotal(); } - auto any = Constants.Any; - auto index = restriction[Constants.IndexPart]; - if (std::ranges::size(restriction) == 1) + return Exists(index) ? LinkAddressType{1} : LinkAddressType{}; + } + if (std::ranges::size(restriction) == 2) + { + auto value = restriction[1]; + if (index == any) { - if (index == any) + if (value == any) { - return GetTotal(); + return GetTotal(); // Any - как отсутствие ограничения } - return Exists(index) ? LinkAddressType {1} : LinkAddressType {}; + return _SourcesTreeMethods->CountUsages(value) + _TargetsTreeMethods->CountUsages(value); } - if (std::ranges::size(restriction) == 2) + else { - auto value = restriction[1]; - if (index == any) + if (!Exists(index)) { - if (value == any) - { - return GetTotal();// Any - как отсутствие ограничения - } - return _SourcesTreeMethods->CountUsages(value) + _TargetsTreeMethods->CountUsages(value); + return LinkAddressType{}; } - else + if (value == any) { - if (!Exists(index)) - { - return LinkAddressType {}; - } - if (value == any) - { - return LinkAddressType {1}; - } - auto& storedLinkValue = GetLinkReference(index); - if (storedLinkValue.Source == value || storedLinkValue.Target == value) - { - return LinkAddressType {1}; - } - return LinkAddressType {}; - } - } - if (std::ranges::size(restriction) == 3) - { - auto source = restriction[Constants.SourcePart]; - auto target = restriction[Constants.TargetPart]; - if (index == any) - { - if (source == any && target == any) - { - return GetTotal(); - } - else if (source == any) - { - return _TargetsTreeMethods->CountUsages(target); - } - else if (target == any) - { - return _SourcesTreeMethods->CountUsages(source); - } - else// if(source != Any && target != Any) - { - auto link = _SourcesTreeMethods->Search(source, target); - return link == Constants.Null ? LinkAddressType {} : LinkAddressType {1}; - } + return LinkAddressType{1}; } - else + auto& storedLinkValue = GetLinkReference(index); + if (storedLinkValue.Source == value || storedLinkValue.Target == value) { - if (!Exists(index)) - { - return LinkAddressType {}; - } - if (source == any && target == any) - { - return LinkAddressType {1}; - } - auto& storedLinkValue = GetLinkReference(index); - if (!source == any && !target == any) - { - if ((storedLinkValue.Source == source) && (storedLinkValue.Target == target)) - { - return LinkAddressType {1}; - } - return LinkAddressType {}; - } - auto value = LinkAddressType(); - if (source == any) - { - value = target; - } - if (target == any) - { - value = source; - } - if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) - { - return LinkAddressType {1}; - } - return LinkAddressType {}; + return LinkAddressType{1}; } + return LinkAddressType{}; } - throw std::logic_error("Not supported exception."); } - - public: LinkAddressType Each(const LinkType& restriction, const ReadHandlerType& handler) const + if (std::ranges::size(restriction) == 3) { - auto $continue {Constants.Continue}; - auto $break = Constants.Break; - if (std::ranges::size(restriction) == 0) + auto source = restriction[Constants.SourcePart]; + auto target = restriction[Constants.TargetPart]; + if (index == any) { - for (auto link = LinkAddressType {1}; link <= this->GetHeaderReference().AllocatedLinks; ++link) + if (source == any && target == any) { - if (Exists(link) && (handler(GetLinkStruct(link)) == $break)) - { - return $break; - } + return GetTotal(); } - return $continue; - } - auto _continue = Constants.Continue; - auto any = Constants.Any; - auto index = restriction[Constants.IndexPart]; - if (std::ranges::size(restriction) == 1) - { - if (index == any) + else if (source == any) { - return Data::Each(*this, handler); + return _TargetsTreeMethods->CountUsages(target); } - if (!Exists(index)) + else if (target == any) { - return _continue; + return _SourcesTreeMethods->CountUsages(source); + } + else // if(source != Any && target != Any) + { + auto link = _SourcesTreeMethods->Search(source, target); + return link == Constants.Null ? LinkAddressType{} : LinkAddressType{1}; } - return handler(GetLinkStruct(index)); } - if (std::ranges::size(restriction) == 2) + else { - auto value = restriction[1]; - if (index == any) + if (!Exists(index)) { - if (value == any) - { - return Data::Each(*this, handler); - } - if (Each(LinkType{index, value, any}, handler) == $break) - { - return $break; - } - return Each(LinkType{index, any, value}, handler); + return LinkAddressType{}; } - else + if (source == any && target == any) { - if (!Exists(index)) - { - return _continue; - } - if (value == any) - { - return handler(GetLinkStruct(index)); - } - auto& storedLinkValue = GetLinkReference(index); - if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) - { - return handler(GetLinkStruct(index)); - } - return _continue; + return LinkAddressType{1}; } - } - if (std::ranges::size(restriction) == 3) - { - auto source = restriction[Constants.SourcePart]; - auto target = restriction[Constants.TargetPart]; - if (index == any) + auto& storedLinkValue = GetLinkReference(index); + if (!source == any && !target == any) { - if (source == any && target == any) - { - return Data::Each(*this, handler); - } - else if (source == any) - { - return _TargetsTreeMethods->EachUsage(target, handler); - } - else if (target == any) - { - return _SourcesTreeMethods->EachUsage(source, handler); - } - else// if(source != Any && target != Any) + if ((storedLinkValue.Source == source) && (storedLinkValue.Target == target)) { - auto link = _SourcesTreeMethods->Search(source, target); - return (link == Constants.Null) ? _continue : handler(GetLinkStruct(link)); + return LinkAddressType{1}; } + return LinkAddressType{}; } - else + auto value = LinkAddressType(); + if (source == any) { - if (!Exists(index)) - { - return _continue; - } - if (source == any && target == any) - { - return handler(GetLinkStruct(index)); - } - // TODO: 'ref locals' are not converted by C# to C++ Converter: - // ORIGINAL LINE: ref var storedLinkValue = ref GetLinkReference(index); - auto& storedLinkValue = GetLinkReference(index); - if (source != any && target != any) - { - if (storedLinkValue.Source == source && storedLinkValue.Target == target) - { - return handler(GetLinkStruct(index)); - } - return _continue; - } - auto value = LinkAddressType(); - if (source == any) - { - value = target; - } - if (target == any) - { - value = source; - } - if (storedLinkValue.Source == value || storedLinkValue.Target == value) - { - return handler(GetLinkStruct(index)); - } - return _continue; + value = target; + } + if (target == any) + { + value = source; + } + if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) + { + return LinkAddressType{1}; } + return LinkAddressType{}; } - throw std::logic_error("Not supported exception."); } + throw std::logic_error("Not supported exception."); + } - // / - // / TODO: Возможно можно перемещать значения, если указан индекс, но значение существует в другом месте (но не в менеджере памяти, а в логике Links) - // / - // NOTE: The following .NET attribute has no direct equivalent in C++: - // ORIGINAL LINE: [MethodImpl(MethodImplOptions.AggressiveInlining)] public LinkAddressType Update(IList restriction, IList substitution) - public: - LinkAddressType Update(const LinkType& restriction, const LinkType& substitution, const WriteHandlerType& handler) +public: + LinkAddressType Each(const LinkType& restriction, const ReadHandlerType& handler) const + { + auto $continue{Constants.Continue}; + auto $break = Constants.Break; + if (std::ranges::size(restriction) == 0) { - auto null = Constants.Null; - auto linkIndex = restriction[Constants.IndexPart]; - // TODO: 'ref locals' are not converted by C# to C++ Converter: - // ORIGINAL LINE: ref var link = ref GetLinkReference(linkIndex); - auto& link = GetLinkReference(linkIndex); - LinkType before {linkIndex, link.Source, link.Target}; - // TODO: 'ref locals' are not converted by C# to C++ Converter: - // ORIGINAL LINE: ref var header = ref GetHeaderReference(); - auto& header = this->GetHeaderReference(); - // TODO: 'ref locals' are not converted by C# to C++ Converter: - // ORIGINAL LINE: ref var firstAsSource = ref header.RootAsSource; - auto& firstAsSource = header.RootAsSource; - // TODO: 'ref locals' are not converted by C# to C++ Converter: - // ORIGINAL LINE: ref var firstAsTarget = ref header.RootAsTarget; - auto& firstAsTarget = header.RootAsTarget; - // Будет корректно работать только в том случае, если пространство выделенной связи предварительно заполнено нулями - if (link.Source != null) - { - _SourcesTreeMethods->Detach(firstAsSource, linkIndex); - } - if (link.Target != null) + for (auto link = LinkAddressType{1}; link <= this->GetHeaderReference().AllocatedLinks; ++link) { - _TargetsTreeMethods->Detach(firstAsTarget, linkIndex); + if (Exists(link) && (handler(GetLinkStruct(link)) == $break)) + { + return $break; + } } - link.Source = substitution[Constants.SourcePart]; - link.Target = substitution[Constants.TargetPart]; - if (link.Source != null) + return $continue; + } + auto _continue = Constants.Continue; + auto any = Constants.Any; + auto index = restriction[Constants.IndexPart]; + if (std::ranges::size(restriction) == 1) + { + if (index == any) { - _SourcesTreeMethods->Attach(firstAsSource, linkIndex); + return Data::Each(*this, handler); } - if (link.Target != null) + if (!Exists(index)) { - _TargetsTreeMethods->Attach(firstAsTarget, linkIndex); + return _continue; } - return handler(before, LinkType{linkIndex, link.Source, link.Target}); + return handler(GetLinkStruct(index)); } - - // TODO: Возможно нужно будет заполнение нулями, если внешнее API ими не заполняет пространство - public: - LinkAddressType Create(const LinkType& restriction, const WriteHandlerType& handler) + if (std::ranges::size(restriction) == 2) { - auto& header = this->GetHeaderReference(); - auto freeLink = header.FirstFreeLink; - if (freeLink != Constants.Null) + auto value = restriction[1]; + if (index == any) { - _UnusedLinksListMethods->Detach(freeLink); + if (value == any) + { + return Data::Each(*this, handler); + } + if (Each(LinkType{index, value, any}, handler) == $break) + { + return $break; + } + return Each(LinkType{index, any, value}, handler); } else { - auto maximumPossibleInnerReference = Constants.InternalReferencesRange.Maximum; - if (header.AllocatedLinks > maximumPossibleInnerReference) + if (!Exists(index)) + { + return _continue; + } + if (value == any) { - // TODO: !!!!! - // throw std::make_shared>(maximumPossibleInnerReference); + return handler(GetLinkStruct(index)); } - if (header.AllocatedLinks >= (header.ReservedLinks - 1)) + auto& storedLinkValue = GetLinkReference(index); + if ((storedLinkValue.Source == value) || (storedLinkValue.Target == value)) { - _memory.ReservedCapacity(_memory.ReservedCapacity() + _memoryReservationStep); - SetPointers(_memory); - header = this->GetHeaderReference(); - header.ReservedLinks = _memory.ReservedCapacity() / LinkSizeInBytes; + return handler(GetLinkStruct(index)); } - ++header.AllocatedLinks; - freeLink = header.AllocatedLinks; - _memory.UsedCapacity(_memory.UsedCapacity() + LinkSizeInBytes); + return _continue; } - return handler(LinkType{0, 0, 0}, LinkType{freeLink, 0, 0}); } - - public: - LinkAddressType Delete(const LinkType& restriction, const WriteHandlerType& handler) + if (std::ranges::size(restriction) == 3) { - auto& header = this->GetHeaderReference(); - auto linkAddress = restriction[Constants.IndexPart]; - auto before = GetLinkStruct(linkAddress); - if (linkAddress < header.AllocatedLinks) + auto source = restriction[Constants.SourcePart]; + auto target = restriction[Constants.TargetPart]; + if (index == any) { - _UnusedLinksListMethods->AttachAsFirst(linkAddress); - return handler ? handler(before, LinkType{}) : Constants.Continue; + if (source == any && target == any) + { + return Data::Each(*this, handler); + } + else if (source == any) + { + return _TargetsTreeMethods->EachUsage(target, handler); + } + else if (target == any) + { + return _SourcesTreeMethods->EachUsage(source, handler); + } + else // if(source != Any && target != Any) + { + auto link = _SourcesTreeMethods->Search(source, target); + return (link == Constants.Null) ? _continue : handler(GetLinkStruct(link)); + } } - else if ((linkAddress == header.AllocatedLinks)) + else { - --header.AllocatedLinks; - _memory.UsedCapacity(_memory.UsedCapacity() - LinkSizeInBytes); - while ((header.AllocatedLinks > LinkAddressType {}) && IsUnusedLink(header.AllocatedLinks)) + if (!Exists(index)) + { + return _continue; + } + if (source == any && target == any) { - _UnusedLinksListMethods->Detach(header.AllocatedLinks); - --header.AllocatedLinks; - _memory.UsedCapacity(_memory.UsedCapacity() - LinkSizeInBytes); + return handler(GetLinkStruct(index)); } - return handler ? handler(before, LinkType{}) : Constants.Continue; + // TODO: 'ref locals' are not converted by C# to C++ Converter: + // ORIGINAL LINE: ref var storedLinkValue = ref GetLinkReference(index); + auto& storedLinkValue = GetLinkReference(index); + if (source != any && target != any) + { + if (storedLinkValue.Source == source && storedLinkValue.Target == target) + { + return handler(GetLinkStruct(index)); + } + return _continue; + } + auto value = LinkAddressType(); + if (source == any) + { + value = target; + } + if (target == any) + { + value = source; + } + if (storedLinkValue.Source == value || storedLinkValue.Target == value) + { + return handler(GetLinkStruct(index)); + } + return _continue; } - return Constants.Continue; } + throw std::logic_error("Not supported exception."); + } - LinkType GetLinkStruct(LinkAddressType linkIndex) const + // / + // / TODO: Возможно можно перемещать значения, если указан индекс, но значение существует в другом месте (но не в + // менеджере памяти, а в логике Links) / NOTE: The following .NET attribute has no direct equivalent in + // C++: ORIGINAL LINE: [MethodImpl(MethodImplOptions.AggressiveInlining)] public LinkAddressType + // Update(IList restriction, IList substitution) +public: + LinkAddressType Update(const LinkType& restriction, const LinkType& substitution, const WriteHandlerType& handler) + { + auto null = Constants.Null; + auto linkIndex = restriction[Constants.IndexPart]; + // TODO: 'ref locals' are not converted by C# to C++ Converter: + // ORIGINAL LINE: ref var link = ref GetLinkReference(linkIndex); + auto& link = GetLinkReference(linkIndex); + LinkType before{linkIndex, link.Source, link.Target}; + // TODO: 'ref locals' are not converted by C# to C++ Converter: + // ORIGINAL LINE: ref var header = ref GetHeaderReference(); + auto& header = this->GetHeaderReference(); + // TODO: 'ref locals' are not converted by C# to C++ Converter: + // ORIGINAL LINE: ref var firstAsSource = ref header.RootAsSource; + auto& firstAsSource = header.RootAsSource; + // TODO: 'ref locals' are not converted by C# to C++ Converter: + // ORIGINAL LINE: ref var firstAsTarget = ref header.RootAsTarget; + auto& firstAsTarget = header.RootAsTarget; + // Будет корректно работать только в том случае, если пространство выделенной связи предварительно заполнено + // нулями + if (link.Source != null) { - auto& link = this->GetLinkReference(linkIndex); - return LinkType{linkIndex, link.Source, link.Target}; + _SourcesTreeMethods->Detach(firstAsSource, linkIndex); } - - // TODO: Возможно это должно быть событием, вызываемым из IMemory, в том случае, если адрес реально поменялся - // - // Указатель this.storage может быть в том же месте, - // так как 0-я связь не используется и имеет такой же размер как Header, - // поэтому header размещается в том же месте, что и 0-я связь - public: - void SetPointers(TMemory& memory) + if (link.Target != null) + { + _TargetsTreeMethods->Detach(firstAsTarget, linkIndex); + } + link.Source = substitution[Constants.SourcePart]; + link.Target = substitution[Constants.TargetPart]; + if (link.Source != null) + { + _SourcesTreeMethods->Attach(firstAsSource, linkIndex); + } + if (link.Target != null) { - _links = static_cast(memory.Pointer()); - _header = _links; - _SourcesTreeMethods = new TSourceTreeMethods(_links, _header); - _TargetsTreeMethods = new TTargetTreeMethods(_links, _header); - _UnusedLinksListMethods = new TUnusedLinks(_links, _header); + _TargetsTreeMethods->Attach(firstAsTarget, linkIndex); } + return handler(before, LinkType{linkIndex, link.Source, link.Target}); + } - bool Exists(LinkAddressType linkAddress) const + // TODO: Возможно нужно будет заполнение нулями, если внешнее API ими не заполняет пространство +public: + LinkAddressType Create(const LinkType& restriction, const WriteHandlerType& handler) + { + auto& header = this->GetHeaderReference(); + auto freeLink = header.FirstFreeLink; + if (freeLink != Constants.Null) + { + _UnusedLinksListMethods->Detach(freeLink); + } + else { - if (IsExternalReference(linkAddress)) + auto maximumPossibleInnerReference = Constants.InternalReferencesRange.Maximum; + if (header.AllocatedLinks > maximumPossibleInnerReference) { - return false; + // TODO: !!!!! + // throw std::make_shared>(maximumPossibleInnerReference); } - return (linkAddress >= Constants.InternalReferencesRange.Minimum) && (linkAddress <= this->GetHeaderReference().AllocatedLinks) && !IsUnusedLink(linkAddress); + if (header.AllocatedLinks >= (header.ReservedLinks - 1)) + { + _memory.ReservedCapacity(_memory.ReservedCapacity() + _memoryReservationStep); + SetPointers(_memory); + header = this->GetHeaderReference(); + header.ReservedLinks = _memory.ReservedCapacity() / LinkSizeInBytes; + } + ++header.AllocatedLinks; + freeLink = header.AllocatedLinks; + _memory.UsedCapacity(_memory.UsedCapacity() + LinkSizeInBytes); } + return handler(LinkType{0, 0, 0}, LinkType{freeLink, 0, 0}); + } - bool IsUnusedLink(LinkAddressType linkIndex) const +public: + LinkAddressType Delete(const LinkType& restriction, const WriteHandlerType& handler) + { + auto& header = this->GetHeaderReference(); + auto linkAddress = restriction[Constants.IndexPart]; + auto before = GetLinkStruct(linkAddress); + if (linkAddress < header.AllocatedLinks) { - if (GetHeaderReference().FirstFreeLink != linkIndex)// May be this check is not needed - { - auto& link = GetLinkReference(linkIndex); - return (link.SizeAsSource == LinkAddressType {}) && (link.Source != LinkAddressType {}); - } - else + _UnusedLinksListMethods->AttachAsFirst(linkAddress); + return handler ? handler(before, LinkType{}) : Constants.Continue; + } + else if ((linkAddress == header.AllocatedLinks)) + { + --header.AllocatedLinks; + _memory.UsedCapacity(_memory.UsedCapacity() - LinkSizeInBytes); + while ((header.AllocatedLinks > LinkAddressType{}) && IsUnusedLink(header.AllocatedLinks)) { - return true; + _UnusedLinksListMethods->Detach(header.AllocatedLinks); + --header.AllocatedLinks; + _memory.UsedCapacity(_memory.UsedCapacity() - LinkSizeInBytes); } + return handler ? handler(before, LinkType{}) : Constants.Continue; + } + return Constants.Continue; + } + + LinkType GetLinkStruct(LinkAddressType linkIndex) const + { + auto& link = this->GetLinkReference(linkIndex); + return LinkType{linkIndex, link.Source, link.Target}; + } + + // TODO: Возможно это должно быть событием, вызываемым из IMemory, в том случае, если адрес реально поменялся + // + // Указатель this.storage может быть в том же месте, + // так как 0-я связь не используется и имеет такой же размер как Header, + // поэтому header размещается в том же месте, что и 0-я связь +public: + void SetPointers(TMemory& memory) + { + _links = static_cast(memory.Pointer()); + _header = _links; + _SourcesTreeMethods = new TSourceTreeMethods(_links, _header); + _TargetsTreeMethods = new TTargetTreeMethods(_links, _header); + _UnusedLinksListMethods = new TUnusedLinks(_links, _header); + } + + bool Exists(LinkAddressType linkAddress) const + { + if (IsExternalReference(linkAddress)) + { + return false; + } + return (linkAddress >= Constants.InternalReferencesRange.Minimum) && + (linkAddress <= this->GetHeaderReference().AllocatedLinks) && !IsUnusedLink(linkAddress); + } + + bool IsUnusedLink(LinkAddressType linkIndex) const + { + if (GetHeaderReference().FirstFreeLink != linkIndex) // May be this check is not needed + { + auto& link = GetLinkReference(linkIndex); + return (link.SizeAsSource == LinkAddressType{}) && (link.Source != LinkAddressType{}); + } + else + { + return true; } - }; -}// namespace Platform::Data::Doublets::Memory::United::Generic + } +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/United/Generic/UnusedLinksListMethods.h b/cpp/Platform.Data.Doublets/Memory/United/Generic/UnusedLinksListMethods.h index ff17e9da4..fb1042706 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/Generic/UnusedLinksListMethods.h +++ b/cpp/Platform.Data.Doublets/Memory/United/Generic/UnusedLinksListMethods.h @@ -1,84 +1,68 @@ namespace Platform::Data::Doublets::Memory::United::Generic { - template - class UnusedLinksListMethods - : public Platform::Collections::Methods::Lists::AbsoluteCircularDoublyLinkedListMethods, typename TLinksOptions::LinkAddressType>, - public ILinksListMethods +template +class UnusedLinksListMethods : public Platform::Collections::Methods::Lists::AbsoluteCircularDoublyLinkedListMethods< + UnusedLinksListMethods, typename TLinksOptions::LinkAddressType>, + public ILinksListMethods +{ + using base = Platform::Collections::Methods::Lists::AbsoluteCircularDoublyLinkedListMethods< + UnusedLinksListMethods, typename TLinksOptions::LinkAddressType>; + using LinksOptionsType = TLinksOptions; + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + +private: + std::byte* _links; + +private: + std::byte* _header; + +public: + UnusedLinksListMethods(std::byte* storage, std::byte* header) : _links(storage), _header(header) {} + +public: + auto& GetHeaderReference() { return *reinterpret_cast*>(_header); } + +public: + auto& GetLinkReference(LinkAddressType linkIndex) { - using base = Platform::Collections::Methods::Lists::AbsoluteCircularDoublyLinkedListMethods, typename TLinksOptions::LinkAddressType>; - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - - private: std::byte* _links; - - private: std::byte* _header; - - public: UnusedLinksListMethods(std::byte* storage, std::byte* header) - : _links(storage), _header(header) {} - - public: auto& GetHeaderReference() - { - return *reinterpret_cast*>(_header); - } - - public: auto& GetLinkReference(LinkAddressType linkIndex) - { - return *(reinterpret_cast*>(_links) + linkIndex); - } - - public: LinkAddressType GetFirst() - { - return GetHeaderReference().FirstFreeLink; - } - - public: LinkAddressType GetLast() - { - return GetHeaderReference().LastFreeLink; - } - - public: LinkAddressType GetPrevious(LinkAddressType element) - { - return GetLinkReference(element).Source; - } - - public: LinkAddressType GetNext(LinkAddressType element) - { - return GetLinkReference(element).Target; - } - - public: LinkAddressType GetSize() - { - return GetHeaderReference().FreeLinks; - } - - public: void SetFirst(LinkAddressType element) - { - GetHeaderReference().FirstFreeLink = element; - } - - public: void SetLast(LinkAddressType element) - { - GetHeaderReference().LastFreeLink = element; - } - - public: void SetPrevious(LinkAddressType element, LinkAddressType previous) - { - GetLinkReference(element).Source = previous; - } - - public: void SetNext(LinkAddressType element, LinkAddressType next) - { - GetLinkReference(element).Target = next; - } - - public: void SetSize(LinkAddressType size) - { - GetHeaderReference().FreeLinks = size; - } - - public: void Detach(LinkAddressType link) { base::Detach(link); } - - public: void AttachAsFirst(LinkAddressType link) { base::AttachAsFirst(link); } - }; -} + return *(reinterpret_cast*>(_links) + linkIndex); + } + +public: + LinkAddressType GetFirst() { return GetHeaderReference().FirstFreeLink; } + +public: + LinkAddressType GetLast() { return GetHeaderReference().LastFreeLink; } + +public: + LinkAddressType GetPrevious(LinkAddressType element) { return GetLinkReference(element).Source; } + +public: + LinkAddressType GetNext(LinkAddressType element) { return GetLinkReference(element).Target; } + +public: + LinkAddressType GetSize() { return GetHeaderReference().FreeLinks; } + +public: + void SetFirst(LinkAddressType element) { GetHeaderReference().FirstFreeLink = element; } + +public: + void SetLast(LinkAddressType element) { GetHeaderReference().LastFreeLink = element; } + +public: + void SetPrevious(LinkAddressType element, LinkAddressType previous) { GetLinkReference(element).Source = previous; } + +public: + void SetNext(LinkAddressType element, LinkAddressType next) { GetLinkReference(element).Target = next; } + +public: + void SetSize(LinkAddressType size) { GetHeaderReference().FreeLinks = size; } + +public: + void Detach(LinkAddressType link) { base::Detach(link); } + +public: + void AttachAsFirst(LinkAddressType link) { base::AttachAsFirst(link); } +}; +} // namespace Platform::Data::Doublets::Memory::United::Generic diff --git a/cpp/Platform.Data.Doublets/Memory/United/RawLink.h b/cpp/Platform.Data.Doublets/Memory/United/RawLink.h index 22f32e090..c4d977479 100644 --- a/cpp/Platform.Data.Doublets/Memory/United/RawLink.h +++ b/cpp/Platform.Data.Doublets/Memory/United/RawLink.h @@ -1,30 +1,30 @@ namespace Platform::Data::Doublets::Memory::United { - template - struct RawLink - { - TLinkAddress Source; +template +struct RawLink +{ + TLinkAddress Source; - TLinkAddress Target; + TLinkAddress Target; - TLinkAddress LeftAsSource; + TLinkAddress LeftAsSource; - TLinkAddress RightAsSource; + TLinkAddress RightAsSource; - TLinkAddress SizeAsSource; + TLinkAddress SizeAsSource; - TLinkAddress LeftAsTarget; + TLinkAddress LeftAsTarget; - TLinkAddress RightAsTarget; + TLinkAddress RightAsTarget; - TLinkAddress SizeAsTarget; + TLinkAddress SizeAsTarget; - constexpr bool operator==(const RawLink&) const noexcept = default; - }; -} + constexpr bool operator==(const RawLink&) const noexcept = default; +}; +} // namespace Platform::Data::Doublets::Memory::United -template +template struct std::hash> { using Self = Platform::Data::Doublets::Memory::United::RawLink; @@ -32,15 +32,7 @@ struct std::hash auto operator()(const Self& self) const noexcept { using Platform::Hashing::Hash; - return Hash( - self.Source, - self.Target, - self.LeftAsSource, - self.RightAsSource, - self.SizeAsSource, - self.LeftAsTarget, - self.RightAsTarget, - self.SizeAsTarget - ); + return Hash(self.Source, self.Target, self.LeftAsSource, self.RightAsSource, self.SizeAsSource, + self.LeftAsTarget, self.RightAsTarget, self.SizeAsTarget); } }; diff --git a/cpp/Platform.Data.Doublets/Platform.Data.Doublets.h b/cpp/Platform.Data.Doublets/Platform.Data.Doublets.h index 5b1e1d4f0..774825016 100644 --- a/cpp/Platform.Data.Doublets/Platform.Data.Doublets.h +++ b/cpp/Platform.Data.Doublets/Platform.Data.Doublets.h @@ -4,50 +4,48 @@ #include #include #include -#include -#include #include +#include +#include #include #include -#include #include #include -#include #include +#include #include +#include #include #include "Doublet.h" +#include "ILinks.h" #include "Link.h" #include "LinksOptions.h" -#include "ILinks.h" -#include "Memory/LinksHeader.h" -#include "Memory/IndexTreeType.h" #include "Memory/ILinksListMethods.h" #include "Memory/ILinksTreeMethods.h" +#include "Memory/IndexTreeType.h" +#include "Memory/LinksHeader.h" -#include "Memory/United/RawLink.h" #include "Memory/United/Generic/UnusedLinksListMethods.h" +#include "Memory/United/RawLink.h" +#include "Memory/United/Generic/LinksAvlBalancedTreeMethodsBase.h" +#include "Memory/United/Generic/LinksRecursionlessSizeBalancedTreeMethodsBase.h" #include "Memory/United/Generic/LinksSizeBalancedTreeMethodsBase.h" -#include "Memory/United/Generic/LinksTargetsSizeBalancedTreeMethods.h" +#include "Memory/United/Generic/LinksSourcesAvlBalancedTreeMethods.h" +#include "Memory/United/Generic/LinksSourcesRecursionlessSizeBalancedTreeMethods.h" #include "Memory/United/Generic/LinksSourcesSizeBalancedTreeMethods.h" -#include "Memory/United/Generic/LinksRecursionlessSizeBalancedTreeMethodsBase.h" +#include "Memory/United/Generic/LinksTargetsAvlBalancedTreeMethods.h" #include "Memory/United/Generic/LinksTargetsRecursionlessSizeBalancedTreeMethods.h" -#include "Memory/United/Generic/LinksSourcesRecursionlessSizeBalancedTreeMethods.h" -#include "Memory/United/Generic/UnitedMemoryLinksBase.h" +#include "Memory/United/Generic/LinksTargetsSizeBalancedTreeMethods.h" #include "Memory/United/Generic/UnitedMemoryLinks.h" -#include "Memory/United/Generic/LinksAvlBalancedTreeMethodsBase.h" -#include "Memory/United/Generic/LinksTargetsAvlBalancedTreeMethods.h" -#include "Memory/United/Generic/LinksSourcesAvlBalancedTreeMethods.h" -//#include "Ffi/LinksBase.h" -//#include "Ffi/Links.h" +#include "Memory/United/Generic/UnitedMemoryLinksBase.h" +// #include "Ffi/LinksBase.h" +// #include "Ffi/Links.h" -#include "Memory/Split/RawLinkDataPart.h" -#include "Memory/Split/RawLinkIndexPart.h" #include "Memory/Split/Generic/ExternalLinksRecursionlessSizeBalancedTreeMethodsBase.h" #include "Memory/Split/Generic/ExternalLinksSizeBalancedTreeMethodsBase.h" #include "Memory/Split/Generic/ExternalLinksSourcesRecursionlessSizeBalancedTreeMethods.h" @@ -61,16 +59,18 @@ #include "Memory/Split/Generic/InternalLinksSourcesSizeBalancedTreeMethods.h" #include "Memory/Split/Generic/InternalLinksTargetsRecursionlessSizeBalancedTreeMethods.h" #include "Memory/Split/Generic/InternalLinksTargetsSizeBalancedTreeMethods.h" -#include "Memory/Split/Generic/UnusedLinksListMethods.h" -#include "Memory/Split/Generic/SplitMemoryLinksBase.h" #include "Memory/Split/Generic/SplitMemoryLinks.h" +#include "Memory/Split/Generic/SplitMemoryLinksBase.h" +#include "Memory/Split/Generic/UnusedLinksListMethods.h" +#include "Memory/Split/RawLinkDataPart.h" +#include "Memory/Split/RawLinkIndexPart.h" #include "ILinksExtensions.h" -#include "Decorators/LinksUniquenessResolver.h" +#include "Decorators/Decorators.h" #include "Decorators/LinksCascadeUniquenessAndUsagesResolver.h" #include "Decorators/LinksCascadeUsagesResolver.h" +#include "Decorators/LinksUniquenessResolver.h" #include "Decorators/NonNullContentsLinkDeletionResolver.h" -#include "Decorators/Decorators.h" #endif diff --git a/cpp/Platform.Data.Doublets/PropertyOperators/PropertiesOperator.h b/cpp/Platform.Data.Doublets/PropertyOperators/PropertiesOperator.h index ba6523a09..8d00cf1e7 100644 --- a/cpp/Platform.Data.Doublets/PropertyOperators/PropertiesOperator.h +++ b/cpp/Platform.Data.Doublets/PropertyOperators/PropertiesOperator.h @@ -1,35 +1,41 @@ namespace Platform::Data::Doublets::PropertyOperators { - template class PropertiesOperator; - template class PropertiesOperator : public LinksOperatorBase, IProperties - { - public: PropertiesOperator(ILinks &storage) : base(storage) { } +template +class PropertiesOperator; +template +class PropertiesOperator : public LinksOperatorBase, + IProperties +{ +public: + PropertiesOperator(ILinks& storage) : base(storage) {} - public: TLinkAddress GetValue(TLinkAddress object, TLinkAddress property) +public: + TLinkAddress GetValue(TLinkAddress object, TLinkAddress property) + { + auto storage = _links; + auto objectProperty = storage.SearchOrDefault(object, property); + if (objectProperty == 0) { - auto storage = _links; - auto objectProperty = storage.SearchOrDefault(object, property); - if (objectProperty == 0) - { - return 0; - } - constexpr auto constants = storage.Constants; - auto any = constants.Any; - auto query = Link(any, objectProperty, any); - auto valueLink = storage.SingleOrDefault(query); - if (valueLink == nullptr) - { - return 0; - } - return storage.GetTarget(valueLink[constants.IndexPart]); + return 0; } - - public: void SetValue(TLinkAddress object, TLinkAddress property, TLinkAddress value) + constexpr auto constants = storage.Constants; + auto any = constants.Any; + auto query = Link(any, objectProperty, any); + auto valueLink = storage.SingleOrDefault(query); + if (valueLink == nullptr) { - auto storage = _links; - auto objectProperty = storage.GetOrCreate(object, property); - storage.DeleteMany(storage.AllIndices(storage.Constants.Any, objectProperty)); - storage.GetOrCreate(objectProperty, value); + return 0; } - }; -} + return storage.GetTarget(valueLink[constants.IndexPart]); + } + +public: + void SetValue(TLinkAddress object, TLinkAddress property, TLinkAddress value) + { + auto storage = _links; + auto objectProperty = storage.GetOrCreate(object, property); + storage.DeleteMany(storage.AllIndices(storage.Constants.Any, objectProperty)); + storage.GetOrCreate(objectProperty, value); + } +}; +} // namespace Platform::Data::Doublets::PropertyOperators diff --git a/cpp/Platform.Data.Doublets/PropertyOperators/PropertyOperator.h b/cpp/Platform.Data.Doublets/PropertyOperators/PropertyOperator.h index 6ab16125a..b5d5dd4fc 100644 --- a/cpp/Platform.Data.Doublets/PropertyOperators/PropertyOperator.h +++ b/cpp/Platform.Data.Doublets/PropertyOperators/PropertyOperator.h @@ -1,65 +1,78 @@ namespace Platform::Data::Doublets::PropertyOperators { - template class PropertyOperator; - template class PropertyOperator : public LinksOperatorBase, IProperty - { - private: TLinkAddress _propertyMarker = 0; - private: TLinkAddress _propertyValueMarker = 0; +template +class PropertyOperator; +template +class PropertyOperator : public LinksOperatorBase, IProperty +{ +private: + TLinkAddress _propertyMarker = 0; - public: PropertyOperator(ILinks &storage, TLinkAddress propertyMarker, TLinkAddress propertyValueMarker) : base(storage) - { - _propertyMarker = propertyMarker; - _propertyValueMarker = propertyValueMarker; - } +private: + TLinkAddress _propertyValueMarker = 0; - public: TLinkAddress Get(TLinkAddress link) - { - auto property = _links.SearchOrDefault(link, _propertyMarker); - return this->GetValue(this->GetContainer(property)); - } +public: + PropertyOperator(ILinks& storage, TLinkAddress propertyMarker, TLinkAddress propertyValueMarker) + : base(storage) + { + _propertyMarker = propertyMarker; + _propertyValueMarker = propertyValueMarker; + } - private: TLinkAddress GetContainer(TLinkAddress property) +public: + TLinkAddress Get(TLinkAddress link) + { + auto property = _links.SearchOrDefault(link, _propertyMarker); + return this->GetValue(this->GetContainer(property)); + } + +private: + TLinkAddress GetContainer(TLinkAddress property) + { + auto valueContainer = this->0(TLinkAddress); + if (property == 0) { - auto valueContainer = this->0(TLinkAddress); - if (property == 0) - { - return valueContainer; - } - auto storage = _links; - constexpr auto constants = storage.Constants; - auto countinueConstant = constants.Continue; - auto breakConstant = constants.Break; - auto anyConstant = constants.Any; - auto query = Link(anyConstant, property, anyConstant); - storage.Each(candidate => - { - auto candidateTarget = storage.GetTarget(candidate); - auto valueTarget = storage.GetTarget(candidateTarget); - if (valueTarget == _propertyValueMarker) - { - valueContainer = storage.GetIndex(candidate); - return breakConstant; - } - return countinueConstant; - }, query); return valueContainer; } + auto storage = _links; + constexpr auto constants = storage.Constants; + auto countinueConstant = constants.Continue; + auto breakConstant = constants.Break; + auto anyConstant = constants.Any; + auto query = Link(anyConstant, property, anyConstant); + storage.Each( + candidate = > + { + auto candidateTarget = storage.GetTarget(candidate); + auto valueTarget = storage.GetTarget(candidateTarget); + if (valueTarget == _propertyValueMarker) + { + valueContainer = storage.GetIndex(candidate); + return breakConstant; + } + return countinueConstant; + }, + query); + return valueContainer; + } - private: TLinkAddress GetValue(TLinkAddress container) { return container == 0 ? 0 : _links.GetTarget(container); } +private: + TLinkAddress GetValue(TLinkAddress container) { return container == 0 ? 0 : _links.GetTarget(container); } - public: void Set(TLinkAddress link, TLinkAddress value) +public: + void Set(TLinkAddress link, TLinkAddress value) + { + auto storage = _links; + auto property = storage.GetOrCreate(link, _propertyMarker); + auto container = this->GetContainer(property); + if (container == 0) + { + storage.GetOrCreate(property, value); + } + else { - auto storage = _links; - auto property = storage.GetOrCreate(link, _propertyMarker); - auto container = this->GetContainer(property); - if (container == 0) - { - storage.GetOrCreate(property, value); - } - else - { - storage.Update(container, property, value); - } + storage.Update(container, property, value); } - }; -} + } +}; +} // namespace Platform::Data::Doublets::PropertyOperators diff --git a/cpp/Platform.Data.Doublets/Stacks/Stack.h b/cpp/Platform.Data.Doublets/Stacks/Stack.h index 0abab9dc3..cdeb25e4e 100644 --- a/cpp/Platform.Data.Doublets/Stacks/Stack.h +++ b/cpp/Platform.Data.Doublets/Stacks/Stack.h @@ -1,36 +1,46 @@ namespace Platform::Data::Doublets::Stacks { - template class Stack; - template class Stack : public LinksOperatorBase, IStack - { - private: TLinkAddress _stack = 0; +template +class Stack; +template +class Stack : public LinksOperatorBase, IStack +{ +private: + TLinkAddress _stack = 0; - public: bool IsEmpty() - { - return this->Peek() == _stack; - } +public: + bool IsEmpty() { return this->Peek() == _stack; } - public: Stack(ILinks &storage, TLinkAddress stack) : base(storage) { return _stack = stack; } +public: + Stack(ILinks& storage, TLinkAddress stack) : base(storage) { return _stack = stack; } - private: TLinkAddress GetStackMarker() { return _links.GetSource(_stack); } +private: + TLinkAddress GetStackMarker() { return _links.GetSource(_stack); } - private: TLinkAddress GetTop() { return _links.GetTarget(_stack); } +private: + TLinkAddress GetTop() { return _links.GetTarget(_stack); } - public: TLinkAddress Peek() { return _links.GetTarget(this->GetTop()); } +public: + TLinkAddress Peek() { return _links.GetTarget(this->GetTop()); } - public: TLinkAddress Pop() +public: + TLinkAddress Pop() + { + auto element = this->Peek(); + if (!element == _stack) { - auto element = this->Peek(); - if (!element == _stack) - { - auto top = this->GetTop(); - auto previousTop = _links.GetSource(top); - _links.Update(_stack, this->GetStackMarker(), previousTop); - _links.Delete(top); - } - return element; + auto top = this->GetTop(); + auto previousTop = _links.GetSource(top); + _links.Update(_stack, this->GetStackMarker(), previousTop); + _links.Delete(top); } + return element; + } - public: void Push(TLinkAddress element) { _links.Update(_stack, this->GetStackMarker(), _links.GetOrCreate(this->GetTop(), element)); } - }; -} +public: + void Push(TLinkAddress element) + { + _links.Update(_stack, this->GetStackMarker(), _links.GetOrCreate(this->GetTop(), element)); + } +}; +} // namespace Platform::Data::Doublets::Stacks diff --git a/cpp/Platform.Data.Doublets/Stacks/StackExtensions.h b/cpp/Platform.Data.Doublets/Stacks/StackExtensions.h index 9b6c93bc4..a18ee9d44 100644 --- a/cpp/Platform.Data.Doublets/Stacks/StackExtensions.h +++ b/cpp/Platform.Data.Doublets/Stacks/StackExtensions.h @@ -1,12 +1,14 @@ namespace Platform::Data::Doublets::Stacks { - class StackExtensions +class StackExtensions +{ +public: + template + static TLinkAddress CreateStack(ILinks& storage, TLinkAddress stackMarker) { - public: template static TLinkAddress CreateStack(ILinks &storage, TLinkAddress stackMarker) - { - auto stackPoint = storage.CreatePoint(); - auto stack = storage.Update(stackPoint, stackMarker, stackPoint); - return stack; - } - }; -} + auto stackPoint = storage.CreatePoint(); + auto stack = storage.Update(stackPoint, stackMarker, stackPoint); + return stack; + } +}; +} // namespace Platform::Data::Doublets::Stacks diff --git a/cpp/Platform.Data.Doublets/SynchronizedLinks.h b/cpp/Platform.Data.Doublets/SynchronizedLinks.h index 4f23e5961..319df9237 100644 --- a/cpp/Platform.Data.Doublets/SynchronizedLinks.h +++ b/cpp/Platform.Data.Doublets/SynchronizedLinks.h @@ -1,34 +1,58 @@ namespace Platform::Data::Doublets { - template class SynchronizedLinks; - template class SynchronizedLinks : public ISynchronizedLinks - { - public: const LinksConstants Constants; - - public: const ISynchronization *SyncRoot; +template +class SynchronizedLinks; +template +class SynchronizedLinks : public ISynchronizedLinks +{ +public: + const LinksConstants Constants; - public: const ILinks *Sync; +public: + const ISynchronization* SyncRoot; - public: const ILinks *Unsync; +public: + const ILinks* Sync; - public: SynchronizedLinks(ILinks &storage) : this(ReaderWriterLockSynchronization(), storage) { } +public: + const ILinks* Unsync; - public: SynchronizedLinks(ISynchronization &synchronization, ILinks &storage) - { - SyncRoot = synchronization; - Sync = this; - Unsync = storage; - Constants = storage.Constants; - } +public: + SynchronizedLinks(ILinks& storage) : this(ReaderWriterLockSynchronization(), storage) {} - public: TLinkAddress Count(IList &restriction) { return SyncRoot.ExecuteReadOperation(restriction, Unsync.Count()); } +public: + SynchronizedLinks(ISynchronization& synchronization, ILinks& storage) + { + SyncRoot = synchronization; + Sync = this; + Unsync = storage; + Constants = storage.Constants; + } + +public: + TLinkAddress Count(IList& restriction) + { + return SyncRoot.ExecuteReadOperation(restriction, Unsync.Count()); + } - public: TLinkAddress Each(Func, TLinkAddress> handler, IList &restriction) { return SyncRoot.ExecuteReadOperation(handler, restriction, (handler1, restriction1) { return Unsync.Each(restriction1, handler1)); } } +public: + TLinkAddress Each(Func, TLinkAddress> handler, IList& restriction) + { return SyncRoot.ExecuteReadOperation(handler, restriction, (handler1, restriction1) { return Unsync.Each(restriction1, handler1)); } + } - public: TLinkAddress Create(IList &restriction) { return SyncRoot.ExecuteWriteOperation(restriction, Unsync.Create); } +public: + TLinkAddress Create(IList& restriction) + { + return SyncRoot.ExecuteWriteOperation(restriction, Unsync.Create); + } - public: TLinkAddress Update(IList &restriction, IList &substitution) { return SyncRoot.ExecuteWriteOperation(restriction, substitution, Unsync.Update); } +public: + TLinkAddress Update(IList& restriction, IList& substitution) + { + return SyncRoot.ExecuteWriteOperation(restriction, substitution, Unsync.Update); + } - public: void Delete(IList &restriction) { SyncRoot.ExecuteWriteOperation(restriction, Unsync.Delete); } - }; -} +public: + void Delete(IList& restriction) { SyncRoot.ExecuteWriteOperation(restriction, Unsync.Delete); } +}; +} // namespace Platform::Data::Doublets diff --git a/cpp/Platform.Data.Doublets/UInt64LinksExtensions.h b/cpp/Platform.Data.Doublets/UInt64LinksExtensions.h index b33f85331..f4ff5aba4 100644 --- a/cpp/Platform.Data.Doublets/UInt64LinksExtensions.h +++ b/cpp/Platform.Data.Doublets/UInt64LinksExtensions.h @@ -1,115 +1,128 @@ namespace Platform::Data::Doublets { - class UInt64LinksExtensions - { - public: static LinksConstants Constants = Default>.Instance; +class UInt64LinksExtensions +{ +public: + static LinksConstants Constants = Default>.Instance; - public: static bool AnyLinkIsAny(ILinks &storage, params std::uint64_t sequence[]) +public: + static bool AnyLinkIsAny(ILinks& storage, params std::uint64_t sequence[]) + { + if (sequence == nullptr) { - if (sequence == nullptr) - { - return false; - } - constexpr auto constants = storage.Constants; - for (auto i = 0; i < sequence.Length; i++) + return false; + } + constexpr auto constants = storage.Constants; + for (auto i = 0; i < sequence.Length; i++) + { + if (sequence[i] == constants.Any) { - if (sequence[i] == constants.Any) - { - return true; - } + return true; } - return false; } + return false; + } - public: static std::string FormatStructure(ILinks &storage, std::uint64_t linkIndex, Func, bool> isElement, bool renderIndex = false, bool renderDebug = false) - { - std::string sb; - auto visited = HashSet(); +public: + static std::string FormatStructure(ILinks& storage, std::uint64_t linkIndex, + Func, bool> isElement, bool renderIndex = false, + bool renderDebug = false) + { + std::string sb; + auto visited = HashSet(); storage.AppendStructure(sb, visited, linkIndex, isElement, (innerSb, link) { return innerSb.Append(link.Index), renderIndex, renderDebug); } return sb; - } + } + +public: + static std::string FormatStructure(ILinks& storage, std::uint64_t linkIndex, + Func, bool> isElement, + Action> appendElement, + bool renderIndex = false, bool renderDebug = false) + { + std::string sb; + auto visited = HashSet(); + storage.AppendStructure(sb, visited, linkIndex, isElement, appendElement, renderIndex, renderDebug); + return sb; + } - public: static std::string FormatStructure(ILinks &storage, std::uint64_t linkIndex, Func, bool> isElement, Action> appendElement, bool renderIndex = false, bool renderDebug = false) +public: + static void AppendStructure(ILinks& storage, std::string& sb, HashSet visited, + std::uint64_t linkIndex, Func, bool> isElement, + Action> appendElement, bool renderIndex = false, + bool renderDebug = false) + { + if (sb == nullptr) { - std::string sb; - auto visited = HashSet(); - storage.AppendStructure(sb, visited, linkIndex, isElement, appendElement, renderIndex, renderDebug); - return sb; + throw std::invalid_argument("sb"); } - - public: static void AppendStructure(ILinks &storage, std::string& sb, HashSet visited, std::uint64_t linkIndex, Func, bool> isElement, Action> appendElement, bool renderIndex = false, bool renderDebug = false) + if (linkIndex == Constants.Null || linkIndex == Constants.Any || linkIndex == Constants.Itself) { - if (sb == nullptr) - { - throw std::invalid_argument("sb"); - } - if (linkIndex == Constants.Null || linkIndex == Constants.Any || linkIndex == Constants.Itself) - { - return; - } - if (storage.Exists(linkIndex)) + return; + } + if (storage.Exists(linkIndex)) + { + if (visited.Add(linkIndex)) { - if (visited.Add(linkIndex)) + sb.append(Platform::Converters::To('(')); + auto link = Link(storage.GetLink(linkIndex)); + if (renderIndex) { - sb.append(Platform::Converters::To('(')); - auto link = Link(storage.GetLink(linkIndex)); - if (renderIndex) - { - sb.append(Platform::Converters::To(link.Index)); - sb.append(Platform::Converters::To(':')); - } - if (link.Source == link.Index) - { - sb.append(Platform::Converters::To(link.Index)); - } - else - { - auto source = Link(storage.GetLink(link.Source)); - if (isElement(source)) - { - appendElement(sb, source); - } - else - { - storage.AppendStructure(sb, visited, source.Index, isElement, appendElement, renderIndex); - } - } - sb.append(Platform::Converters::To(' ')); - if (link.Target == link.Index) + sb.append(Platform::Converters::To(link.Index)); + sb.append(Platform::Converters::To(':')); + } + if (link.Source == link.Index) + { + sb.append(Platform::Converters::To(link.Index)); + } + else + { + auto source = Link(storage.GetLink(link.Source)); + if (isElement(source)) { - sb.append(Platform::Converters::To(link.Index)); + appendElement(sb, source); } else { - auto target = Link(storage.GetLink(link.Target)); - if (isElement(target)) - { - appendElement(sb, target); - } - else - { - storage.AppendStructure(sb, visited, target.Index, isElement, appendElement, renderIndex); - } + storage.AppendStructure(sb, visited, source.Index, isElement, appendElement, renderIndex); } - sb.append(Platform::Converters::To('))'); + } + sb.append(Platform::Converters::To(' ')); + if (link.Target == link.Index) + { + sb.append(Platform::Converters::To(link.Index)); } else { - if (renderDebug) + auto target = Link(storage.GetLink(link.Target)); + if (isElement(target)) + { + appendElement(sb, target); + } + else { - sb.append(Platform::Converters::To('*')); + storage.AppendStructure(sb, visited, target.Index, isElement, appendElement, renderIndex); } - sb.append(Platform::Converters::To(linkIndex)); } + sb.append(Platform::Converters::To('))'); } else { if (renderDebug) { - sb.append(Platform::Converters::To('~')); + sb.append(Platform::Converters::To('*')); } sb.append(Platform::Converters::To(linkIndex)); } } - }; -} + else + { + if (renderDebug) + { + sb.append(Platform::Converters::To('~')); + } + sb.append(Platform::Converters::To(linkIndex)); + } + } +}; +} // namespace Platform::Data::Doublets diff --git a/cpp/Platform.Data.Doublets/UInt64LinksTransactionsLayer.h b/cpp/Platform.Data.Doublets/UInt64LinksTransactionsLayer.h index d08423caf..4be239807 100644 --- a/cpp/Platform.Data.Doublets/UInt64LinksTransactionsLayer.h +++ b/cpp/Platform.Data.Doublets/UInt64LinksTransactionsLayer.h @@ -1,272 +1,354 @@ namespace Platform::Data::Doublets { - class UInt64LinksTransactionsLayer : public LinksDisposableDecoratorBase +class UInt64LinksTransactionsLayer : public LinksDisposableDecoratorBase +{ + struct Transition : public IEquatable { - struct Transition : public IEquatable - { - public: inline static const std::uint64_t Size = Structure.Size; + public: + inline static const std::uint64_t Size = Structure.Size; - public: std::uint64_t TransactionId = 0; - public: Link Before; - public: Link After; - public: Timestamp Timestamp = 0; + public: + std::uint64_t TransactionId = 0; - public: Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId, Link before, Link after) - { - TransactionId = transactionId; - Before = before; - After = after; - Timestamp = uniqueTimestampFactory.Create(); - } + public: + Link Before; - public: Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId, Link before) : this(uniqueTimestampFactory, transactionId, before, 0) { } + public: + Link After; - public: Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId) : this(uniqueTimestampFactory, transactionId, 0, 0) { } + public: + Timestamp Timestamp = 0; - public: std::string ToString() { return std::string("").append(Platform::Converters::To(Timestamp)).append(1, ' ').append(Platform::Converters::To(TransactionId)).append(": ").append(Platform::Converters::To(Before)).append(" => ").append(Platform::Converters::To(After)).append(""); } + public: + Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId, + Link before, Link after) + { + TransactionId = transactionId; + Before = before; + After = after; + Timestamp = uniqueTimestampFactory.Create(); + } - public: std::int32_t GetHashCode() { return Platform::Hashing::Hash(TransactionId, Before, After, Timestamp); } + public: + Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId, + Link before) + : this(uniqueTimestampFactory, transactionId, before, 0) + { + } - public: bool operator ==(const Transition &other) const { return TransactionId == other.TransactionId && Before == other.Before && After == other.After && Timestamp == other.Timestamp; } + public: + Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId) + : this(uniqueTimestampFactory, transactionId, 0, 0) + { } - class Transaction : public DisposableBase + public: + std::string ToString() { - private: Queue _transitions; - private: UInt64LinksTransactionsLayer _layer = 0; - public: inline bool IsCommitted; - public: inline bool IsReverted; + return std::string("") + .append(Platform::Converters::To(Timestamp)) + .append(1, ' ') + .append(Platform::Converters::To(TransactionId)) + .append(": ") + .append(Platform::Converters::To(Before)) + .append(" => ") + .append(Platform::Converters::To(After)) + .append(""); + } - public: Transaction(UInt64LinksTransactionsLayer layer) - { - _layer = layer; - if (_layer._currentTransactionId != 0) - { - throw throw std::logic_error("Not supported exception."); - } - IsCommitted = false; - IsReverted = false; - _transitions = Queue(); - this->SetCurrentTransaction(layer, this); - } + public: + std::int32_t GetHashCode() { return Platform::Hashing::Hash(TransactionId, Before, After, Timestamp); } - public: void Commit() - { - this->EnsureTransactionAllowsWriteOperations(this); - while (_transitions.Count() > 0) - { - auto transition = _transitions.Dequeue(); - _layer._transitions.Enqueue(transition); - } - _layer._lastCommitedTransactionId = _layer._currentTransactionId; - IsCommitted = true; - } + public: + bool operator==(const Transition& other) const + { + return TransactionId == other.TransactionId && Before == other.Before && After == other.After && + Timestamp == other.Timestamp; + } + } - private: void Revert() - { - this->EnsureTransactionAllowsWriteOperations(this); - auto transitionsToRevert = Transition[_transitions.Count()]; - _transitions.CopyTo(transitionsToRevert, 0); - for (auto i = transitionsToRevert.Length - 1; i >= 0; i--) - { - _layer.RevertTransition(transitionsToRevert[i]); - } - IsReverted = true; - } + class Transaction : public DisposableBase + { + private: + Queue _transitions; + + private: + UInt64LinksTransactionsLayer _layer = 0; + + public: + inline bool IsCommitted; + + public: + inline bool IsReverted; - public: static void SetCurrentTransaction(UInt64LinksTransactionsLayer layer, Transaction transaction) + public: + Transaction(UInt64LinksTransactionsLayer layer) + { + _layer = layer; + if (_layer._currentTransactionId != 0) { - layer._currentTransactionId = layer._lastCommitedTransactionId + 1; - layer._currentTransactionTransitions = transaction._transitions; - layer._currentTransaction = transaction; + throw throw std::logic_error("Not supported exception."); } + IsCommitted = false; + IsReverted = false; + _transitions = Queue(); + this->SetCurrentTransaction(layer, this); + } - public: static void EnsureTransactionAllowsWriteOperations(Transaction transaction) + public: + void Commit() + { + this->EnsureTransactionAllowsWriteOperations(this); + while (_transitions.Count() > 0) { - if (transaction.IsReverted) - { - throw std::runtime_error("Transation is reverted."); - } - if (transaction.IsCommitted) - { - throw std::runtime_error("Transation is commited."); - } + auto transition = _transitions.Dequeue(); + _layer._transitions.Enqueue(transition); } + _layer._lastCommitedTransactionId = _layer._currentTransactionId; + IsCommitted = true; + } - public: void Dispose(bool manual, bool wasDisposed) + private: + void Revert() + { + this->EnsureTransactionAllowsWriteOperations(this); + auto transitionsToRevert = Transition[_transitions.Count()]; + _transitions.CopyTo(transitionsToRevert, 0); + for (auto i = transitionsToRevert.Length - 1; i >= 0; i--) { - if (!wasDisposed && _layer != nullptr && !_layer.Disposable.IsDisposed) - { - if (!IsCommitted && !IsReverted) - { - this->Revert(); - } - _layer.ResetCurrentTransation(); - } + _layer.RevertTransition(transitionsToRevert[i]); } + IsReverted = true; } - public: inline static const TimeSpan DefaultPushDelay = TimeSpan.FromSeconds(0.1); - - private: std::string _logAddress = 0; - private: FileStream _log = 0; - private: Queue _transitions; - private: UniqueTimestampFactory _uniqueTimestampFactory = 0; - private: Task _transitionsPusher = 0; - private: Transition _lastCommitedTransition = 0; - private: std::uint64_t _currentTransactionId = 0; - private: Queue _currentTransactionTransitions; - private: Transaction _currentTransaction = 0; - private: std::uint64_t _lastCommitedTransactionId = 0; - - public: UInt64LinksTransactionsLayer(ILinks &storage, std::string logAddress) - : base(storage) + public: + static void SetCurrentTransaction(UInt64LinksTransactionsLayer layer, Transaction transaction) { - if (std::string.IsNullOrWhiteSpace(logAddress)) + layer._currentTransactionId = layer._lastCommitedTransactionId + 1; + layer._currentTransactionTransitions = transaction._transitions; + layer._currentTransaction = transaction; + } + + public: + static void EnsureTransactionAllowsWriteOperations(Transaction transaction) + { + if (transaction.IsReverted) { - throw std::invalid_argument("logAddress"); + throw std::runtime_error("Transation is reverted."); } - auto lastCommitedTransition = FileHelpers.ReadFirstOrDefault(logAddress); - auto lastWrittenTransition = FileHelpers.ReadLastOrDefault(logAddress); - if (!lastCommitedTransition.Equals(lastWrittenTransition)) + if (transaction.IsCommitted) { - this->Dispose(); - throw throw std::logic_error("Not supported exception."); + throw std::runtime_error("Transation is commited."); } - if (lastCommitedTransition == 0) + } + + public: + void Dispose(bool manual, bool wasDisposed) + { + if (!wasDisposed && _layer != nullptr && !_layer.Disposable.IsDisposed) { - FileHelpers.WriteFirst(logAddress, lastCommitedTransition); + if (!IsCommitted && !IsReverted) + { + this->Revert(); + } + _layer.ResetCurrentTransation(); } - _lastCommitedTransition = lastCommitedTransition; - auto allTransitions = FileHelpers.ReadAll(logAddress); - _lastCommitedTransactionId = allTransitions.Length > 0 ? allTransitions.Max(x => x.TransactionId) : 0; - _uniqueTimestampFactory = this->UniqueTimestampFactory(); - _logAddress = logAddress; - _log = FileHelpers.Append(logAddress); - _transitions = Queue(); - _transitionsPusher = this->Task(TransitionsPusher); - _transitionsPusher.Start(); } + } + + public : inline static const TimeSpan DefaultPushDelay = TimeSpan.FromSeconds(0.1); + +private: + std::string _logAddress = 0; + +private: + FileStream _log = 0; - public: IList GetLinkValue(std::uint64_t link) { return _links.GetLink(link); } +private: + Queue _transitions; - public: std::uint64_t Create(IList &restriction) +private: + UniqueTimestampFactory _uniqueTimestampFactory = 0; + +private: + Task _transitionsPusher = 0; + +private: + Transition _lastCommitedTransition = 0; + +private: + std::uint64_t _currentTransactionId = 0; + +private: + Queue _currentTransactionTransitions; + +private: + Transaction _currentTransaction = 0; + +private: + std::uint64_t _lastCommitedTransactionId = 0; + +public: + UInt64LinksTransactionsLayer(ILinks& storage, std::string logAddress) : base(storage) + { + if (std::string.IsNullOrWhiteSpace(logAddress)) { - auto createdLinkIndex = _links.Create(); - auto createdLink = Link(_links.GetLink(createdLinkIndex)); - this->CommitTransition(this->Transition(_uniqueTimestampFactory, _currentTransactionId, 0, createdLink)); - return createdLinkIndex; + throw std::invalid_argument("logAddress"); } - - public: std::uint64_t Update(IList &restriction, IList &substitution) + auto lastCommitedTransition = FileHelpers.ReadFirstOrDefault(logAddress); + auto lastWrittenTransition = FileHelpers.ReadLastOrDefault(logAddress); + if (!lastCommitedTransition.Equals(lastWrittenTransition)) { - auto linkIndex = restriction[_constants.IndexPart]; - auto beforeLink = Link(_links.GetLink(linkIndex)); - linkIndex = _links.Update(restriction, substitution); - auto afterLink = Link(_links.GetLink(linkIndex)); - this->CommitTransition(this->Transition(_uniqueTimestampFactory, _currentTransactionId, beforeLink, afterLink)); - return linkIndex; + this->Dispose(); + throw throw std::logic_error("Not supported exception."); } - - public: void Delete(IList &restriction) + if (lastCommitedTransition == 0) { - auto link = restriction[_constants.IndexPart]; - auto deletedLink = Link(_links.GetLink(link)); - _links.Delete(link); - this->CommitTransition(this->Transition(_uniqueTimestampFactory, _currentTransactionId, deletedLink, 0)); + FileHelpers.WriteFirst(logAddress, lastCommitedTransition); } + _lastCommitedTransition = lastCommitedTransition; + auto allTransitions = FileHelpers.ReadAll(logAddress); + _lastCommitedTransactionId = allTransitions.Length > 0 ? allTransitions.Max(x = > x.TransactionId) : 0; + _uniqueTimestampFactory = this->UniqueTimestampFactory(); + _logAddress = logAddress; + _log = FileHelpers.Append(logAddress); + _transitions = Queue(); + _transitionsPusher = this->Task(TransitionsPusher); + _transitionsPusher.Start(); + } + +public: + IList GetLinkValue(std::uint64_t link) { return _links.GetLink(link); } + +public: + std::uint64_t Create(IList& restriction) + { + auto createdLinkIndex = _links.Create(); + auto createdLink = Link(_links.GetLink(createdLinkIndex)); + this->CommitTransition(this->Transition(_uniqueTimestampFactory, _currentTransactionId, 0, createdLink)); + return createdLinkIndex; + } + +public: + std::uint64_t Update(IList& restriction, IList& substitution) + { + auto linkIndex = restriction[_constants.IndexPart]; + auto beforeLink = Link(_links.GetLink(linkIndex)); + linkIndex = _links.Update(restriction, substitution); + auto afterLink = Link(_links.GetLink(linkIndex)); + this->CommitTransition(this->Transition(_uniqueTimestampFactory, _currentTransactionId, beforeLink, afterLink)); + return linkIndex; + } + +public: + void Delete(IList& restriction) + { + auto link = restriction[_constants.IndexPart]; + auto deletedLink = Link(_links.GetLink(link)); + _links.Delete(link); + this->CommitTransition(this->Transition(_uniqueTimestampFactory, _currentTransactionId, deletedLink, 0)); + } - private: Queue GetCurrentTransitions() { return _currentTransactionTransitions ?? _transitions; } +private: + Queue GetCurrentTransitions() { return _currentTransactionTransitions ? ? _transitions; } - private: void CommitTransition(Transition transition) +private: + void CommitTransition(Transition transition) + { + if (_currentTransaction != nullptr) { - if (_currentTransaction != nullptr) - { - Transaction.EnsureTransactionAllowsWriteOperations(_currentTransaction); - } - auto transitions = this->GetCurrentTransitions(); - transitions.Enqueue(transition); + Transaction.EnsureTransactionAllowsWriteOperations(_currentTransaction); } + auto transitions = this->GetCurrentTransitions(); + transitions.Enqueue(transition); + } - private: void RevertTransition(Transition transition) +private: + void RevertTransition(Transition transition) + { + if (transition.After.IsNull()) { - if (transition.After.IsNull()) - { - _links.Create(); - } - else if (transition.Before.IsNull()) - { - _links.Delete(transition.After.Index); - } - else - { - _links.Update(new[] { transition.After.Index, transition.Before.Source, transition.Before.Target }); - } + _links.Create(); } - - private: void ResetCurrentTransation() + else if (transition.Before.IsNull()) { - _currentTransactionId = 0; - _currentTransactionTransitions = {}; - _currentTransaction = {}; + _links.Delete(transition.After.Index); } + else + { + _links.Update(new[]{transition.After.Index, transition.Before.Source, transition.Before.Target}); + } + } + +private: + void ResetCurrentTransation() + { + _currentTransactionId = 0; + _currentTransactionTransitions = {}; + _currentTransaction = {}; + } - private: void PushTransitions() +private: + void PushTransitions() + { + if (_log == nullptr || _transitions == nullptr) { - if (_log == nullptr || _transitions == nullptr) - { - return; - } - for (auto i = 0; i < _transitions.Count(); i++) - { - auto transition = _transitions.Dequeue(); + return; + } + for (auto i = 0; i < _transitions.Count(); i++) + { + auto transition = _transitions.Dequeue(); - _log.Write(transition); - _lastCommitedTransition = transition; - } + _log.Write(transition); + _lastCommitedTransition = transition; } + } - private: void TransitionsPusher() +private: + void TransitionsPusher() + { + while (!Disposable.IsDisposed && _transitionsPusher != nullptr) { - while (!Disposable.IsDisposed && _transitionsPusher != nullptr) - { - Thread.Sleep(DefaultPushDelay); - this->PushTransitions(); - } + Thread.Sleep(DefaultPushDelay); + this->PushTransitions(); } + } - public: Transaction BeginTransaction() { return this->Transaction(this); } +public: + Transaction BeginTransaction() { return this->Transaction(this); } - private: void DisposeTransitions() +private: + void DisposeTransitions() + { + try { - try + auto pusher = _transitionsPusher; + if (pusher != nullptr) { - auto pusher = _transitionsPusher; - if (pusher != nullptr) - { - _transitionsPusher = {}; - pusher.Wait(); - } - if (_transitions != nullptr) - { - this->PushTransitions(); - } - _log.DisposeIfPossible(); - FileHelpers.WriteFirst(_logAddress, _lastCommitedTransition); + _transitionsPusher = {}; + pusher.Wait(); } - catch (const std::exception& ex) + if (_transitions != nullptr) { - Platform::Exceptions::ExceptionExtensions::Ignore(ex); + this->PushTransitions(); } + _log.DisposeIfPossible(); + FileHelpers.WriteFirst(_logAddress, _lastCommitedTransition); + } + catch (const std::exception& ex) + { + Platform::Exceptions::ExceptionExtensions::Ignore(ex); } + } - public: void Dispose(bool manual, bool wasDisposed) +public: + void Dispose(bool manual, bool wasDisposed) + { + if (!wasDisposed) { - if (!wasDisposed) - { - this->DisposeTransitions(); - } - base.Dispose(manual, wasDisposed); + this->DisposeTransitions(); } - }; -} + base.Dispose(manual, wasDisposed); + } +}; +} // namespace Platform::Data::Doublets