From 34fdda2e43c429cea4eb3193cdbac1120a1b19cc Mon Sep 17 00:00:00 2001 From: cyber-pc Date: Sat, 30 Mar 2024 21:09:45 +0700 Subject: [PATCH] Added collection's replace element and its unittest. --- src/smart_contracts/qpi.h | 8 +++- test/qpi.cpp | 78 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/src/smart_contracts/qpi.h b/src/smart_contracts/qpi.h index d7f54791..69176f71 100644 --- a/src/smart_contracts/qpi.h +++ b/src/smart_contracts/qpi.h @@ -5891,9 +5891,15 @@ namespace QPI } // Replace *existing* element, do nothing otherwise + // - The element exists: replace its value. + // - The element has been removed: replace the value of the new element that fills this position after removal. + // - The index is out of bounds: no action is taken. void replace(sint64 oldElementIndex, T newElement) { - // TODO + if (oldElementIndex < _population) + { + _elements[oldElementIndex & (L - 1)].value = newElement; + } } // Reinitialize as empty collection. diff --git a/test/qpi.cpp b/test/qpi.cpp index 31b94153..402a4ae9 100644 --- a/test/qpi.cpp +++ b/test/qpi.cpp @@ -1071,6 +1071,84 @@ TEST(TestCoreQPI, CollectionSubCollectionsRandom) { } } +TEST(TestCoreQPI, CollectionReplaceElements) { + QPI::id pov(1, 2, 3, 4); + + QPI::collection coll; + coll.reset(); + + const int seed = 246357; + std::mt19937_64 gen64(seed); + + // init a collection for test + const size_t numElements = 1000; + std::vector priorities(numElements); + for (size_t i = 0; i < numElements; i++) + { + priorities[i] = std::abs((QPI::sint64)gen64()) % 0xFFFF; + coll.add(pov, i, priorities[i]); + } + checkPriorityQueue(coll, pov, false); + + // test for special cases out of bound element index + size_t replaceElement = 999; + + // out of collection's capacity + coll.replace(coll.capacity(), replaceElement); + for (size_t i = 0; i < numElements; i++) + { + EXPECT_EQ(coll.element(i), i); + } + + // out of collection's size + coll.replace(numElements, replaceElement); + for (size_t i = 0; i < numElements; i++) + { + EXPECT_EQ(coll.element(i), i); + } + + // generate random replace indices + const size_t numTests = 500; + std::vector replaceIndices(numTests); + for (size_t i = 0; i < numTests; i++) + { + replaceIndices[i] = std::abs((QPI::sint64)gen64()) % numElements; + // remove some of indices in the list + if (i % 4) + { + coll.remove(replaceIndices[i]); + } + } + + // get the new priorities list + size_t numRemainedElements = coll.population(); + priorities.resize(numRemainedElements); + for (size_t i = 0; i < numRemainedElements; i++) + { + priorities[i] = coll.priority(i); + } + + // run the test on the list + for (size_t i = 0; i < numTests; i++) + { + QPI::sint64 replaceElement = i; + QPI::sint64 replaceIndex = replaceIndices[i]; + + QPI::sint64 nextElementIndex = coll.nextElementIndex(replaceIndex); + QPI::sint64 prevElementIndex = coll.prevElementIndex(replaceIndex); + + coll.replace(replaceIndex, replaceElement); + + if (replaceIndex < numRemainedElements) + { + EXPECT_EQ(coll.element(replaceIndex), replaceElement); + EXPECT_EQ(coll.priority(replaceIndex), priorities[replaceIndex]); + EXPECT_EQ(coll.nextElementIndex(replaceIndex), nextElementIndex); + EXPECT_EQ(coll.prevElementIndex(replaceIndex), prevElementIndex); + } + } +} + template void testCollectionCleanupPseudoRandom(int povs, int seed, bool povCollisions) {