Skip to content

Commit

Permalink
Add move constructor to VaultRecordSet
Browse files Browse the repository at this point in the history
  • Loading branch information
mrognor committed Dec 13, 2024
1 parent f3d5756 commit 8e2e948
Show file tree
Hide file tree
Showing 6 changed files with 280 additions and 6 deletions.
6 changes: 4 additions & 2 deletions Source/Vault.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ namespace mvlt
}
}

Vault& Vault::operator= (const Vault& other) noexcept
Vault& Vault::operator=(const Vault& other) noexcept
{
if (&other != this)
{
Expand Down Expand Up @@ -271,10 +271,12 @@ namespace mvlt
RecordSetsSet = std::move(other.RecordSetsSet);
}

Vault& Vault::operator= (Vault&& other) noexcept
Vault& Vault::operator=(Vault&& other) noexcept
{
if (this != &other)
{
DropVault();

ReadLock<RecursiveReadWriteMutex> otherReadLock(other.RecursiveReadWriteMtx);

VaultDerivedClass = VaultDerivedClasses::VaultBase;
Expand Down
4 changes: 2 additions & 2 deletions Source/Vault.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ namespace mvlt
\return reference to copied object
*/
Vault& operator= (const Vault& other) noexcept;
Vault& operator=(const Vault& other) noexcept;

/**
\brief Move constructor
Expand All @@ -265,7 +265,7 @@ namespace mvlt
\return reference to moved object
*/
Vault& operator= (Vault&& other) noexcept;
Vault& operator=(Vault&& other) noexcept;

/**
\brief Template method to add new key with default value to Vault
Expand Down
57 changes: 56 additions & 1 deletion Source/VaultRecordSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,42 @@ namespace mvlt
RecursiveReadWriteMtx.Disable();
}

void VaultRecordSet::MoveSet(VaultRecordSet& other) noexcept
{
WriteLock<RecursiveReadWriteMutex> writeLock(other.ParentVault->RecursiveReadWriteMtx);

VaultDerivedClass = VaultDerivedClasses::VaultRecordSetDerived;

ParentVault = other.ParentVault;
other.ParentVault = nullptr;

RecordTemplate = std::move(other.RecordTemplate);
VaultHashMapStructure = std::move(other.VaultHashMapStructure);
VaultMapStructure = std::move(other.VaultMapStructure);
KeysTypes = std::move(other.KeysTypes);
VaultRecordAdders = std::move(other.VaultRecordAdders);
VaultRecordClearers = std::move(other.VaultRecordClearers);
VaultRecordErasers = std::move(other.VaultRecordErasers);
VaultRecordSorters = std::move(other.VaultRecordSorters);
VaultKeyCopiers = std::move(other.VaultKeyCopiers);
KeysOrder = std::move(other.KeysOrder);
UniqueKeys = std::move(other.UniqueKeys);
InvalidFileRecords = std::move(other.InvalidFileRecords);
RecordsSet = std::move(other.RecordsSet);
RecordSetsSet = std::move(other.RecordSetsSet);

ParentVault->RecordSetsSet.erase(&other);
ParentVault->RecordSetsSet.emplace(this);

for (VaultRecord* record : other.RecordsSet)
{
record->EraseDependentSet(&other);
record->AddToDependentSets(this);
}

RecursiveReadWriteMtx.Disable();
}

VaultRecordSet::VaultRecordSet() noexcept
{
VaultDerivedClass = VaultDerivedClasses::VaultRecordSetDerived;
Expand All @@ -42,7 +78,7 @@ namespace mvlt

VaultRecordSet::VaultRecordSet(const VaultRecordSet& other) noexcept
{
if (&other != this && other.GetIsParentVaultValid())
if (other.GetIsParentVaultValid())
CopySet(other);
}

Expand All @@ -58,6 +94,25 @@ namespace mvlt
return *this;
}

VaultRecordSet::VaultRecordSet(VaultRecordSet&& other) noexcept
{
if (other.GetIsParentVaultValid())
MoveSet(other);
}

VaultRecordSet& VaultRecordSet::operator=(VaultRecordSet&& other) noexcept
{
if (&other != this)
{
if (other.GetIsParentVaultValid())
MoveSet(other);
else
Reset();
}

return *this;
}

bool VaultRecordSet::GetIsParentVaultValid() const noexcept
{
return ParentVault != nullptr;
Expand Down
27 changes: 26 additions & 1 deletion Source/VaultRecordSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ namespace mvlt
*/
void CopySet(const VaultRecordSet& other) noexcept;

/**
\brief An internal method for moving objects
\param [in] other object to move
*/
void MoveSet(VaultRecordSet& other) noexcept;

public:

/// Make Vault class friend
Expand All @@ -81,9 +88,27 @@ namespace mvlt
\brief Operator assignment
\param [in] other object to copy
\return reference to copied object
*/
VaultRecordSet& operator=(const VaultRecordSet& other) noexcept;


/**
\brief Move constructor
\param [in] other object to move
*/
VaultRecordSet(VaultRecordSet&& other) noexcept;

/**
\brief Move assignment perator
\param [in] other object to move
\return reference to moveed object
*/
VaultRecordSet& operator=(VaultRecordSet&& other) noexcept;

/// Making operator comparison function friendly
friend bool operator==(const VaultRecordSet& a, const VaultRecordSet& b);

Expand Down
186 changes: 186 additions & 0 deletions Tests/VaultRecordSetUnitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,190 @@ void VaultRecordSet_OperatorAssignment_Test()
TEST_ASSERT(vrs2 == vrs1, "Failed to assign vault record set");
}

void VaultRecordSet_MoveConstructor_Test()
{
Vault* vlt = new Vault;

vlt->AddKey<int>("A", -1);
vlt->AddKey<std::string>("B", "none");
vlt->AddUniqueKey<std::size_t>("C");

for (std::size_t i = 0; i < 10; ++i)
vlt->CreateRecord({{"A", static_cast<int>(i * i * i)}, {"B", "test" + std::to_string(i)}, {"C", i}});

VaultRecordSet vrs1;

vlt->RequestInterval<std::size_t>("C", 2, 8, vrs1);

std::vector<int> vecA1;
std::vector<std::string> vecB1;
std::vector<std::size_t> vecC1;
std::vector<std::string> pointers1;

vrs1.SortBy("A", [&](const VaultRecordRef& ref)
{
int A;
std::string B;
std::size_t C;

ref.GetData("A", A);
ref.GetData("B", B);
ref.GetData("C", C);

vecA1.emplace_back(std::move(A));
vecB1.emplace_back(std::move(B));
vecC1.emplace_back(std::move(C));
pointers1.emplace_back(ref.GetRecordUniqueId());

return true;
});

std::vector<std::string> keys = vrs1.GetKeys();

VaultRecordSet vrs2(std::move(vrs1));

TEST_ASSERT(vrs1.Size() == 0,"Failed to move Vault");
TEST_ASSERT(vrs1.GetKeys().empty(),"Failed to move Vault");

TEST_ASSERT(vrs2.Size() == 7,"Failed to move Vault");
TEST_ASSERT(keys == vrs2.GetKeys(),"Failed to move Vault");

std::type_index keyType = typeid(void);
vrs2.GetKeyType("A", keyType);
TEST_ASSERT(keyType == typeid(int),"Failed to move Vault");
vrs2.GetKeyType("B", keyType);
TEST_ASSERT(keyType == typeid(std::string),"Failed to move Vault");
vrs2.GetKeyType("C", keyType);
TEST_ASSERT(keyType == typeid(std::size_t),"Failed to move Vault");

std::vector<int> vecA2;
std::vector<std::string> vecB2;
std::vector<std::size_t> vecC2;
std::vector<std::string> pointers2;

vrs2.SortBy("A", [&](const VaultRecordRef& ref)
{
int A;
std::string B;
std::size_t C;

ref.GetData("A", A);
ref.GetData("B", B);
ref.GetData("C", C);

vecA2.emplace_back(std::move(A));
vecB2.emplace_back(std::move(B));
vecC2.emplace_back(std::move(C));
pointers2.emplace_back(ref.GetRecordUniqueId());

return true;
});

TEST_ASSERT(vecA1 == vecA2, "Failed to move Vault");
TEST_ASSERT(vecB1 == vecB2, "Failed to move Vault");
TEST_ASSERT(vecC1 == vecC2, "Failed to move Vault");
TEST_ASSERT(pointers1 == pointers2, "Failed to move Vault");

delete vlt;

TEST_ASSERT(vrs2.GetParentVaultUniqueId() == "null", "Failed to move Vault");
}

void VaultRecordSet_MoveAssignment_Test()
{
Vault* vlt = new Vault;

vlt->AddKey<int>("A", -1);
vlt->AddKey<std::string>("B", "none");
vlt->AddUniqueKey<std::size_t>("C");

for (std::size_t i = 0; i < 10; ++i)
vlt->CreateRecord({{"A", static_cast<int>(i * i * i)}, {"B", "test" + std::to_string(i)}, {"C", i}});

VaultRecordSet vrs1;

vlt->RequestInterval<std::size_t>("C", 2, 8, vrs1);

std::vector<int> vecA1;
std::vector<std::string> vecB1;
std::vector<std::size_t> vecC1;
std::vector<std::string> pointers1;

vrs1.SortBy("A", [&](const VaultRecordRef& ref)
{
int A;
std::string B;
std::size_t C;

ref.GetData("A", A);
ref.GetData("B", B);
ref.GetData("C", C);

vecA1.emplace_back(std::move(A));
vecB1.emplace_back(std::move(B));
vecC1.emplace_back(std::move(C));
pointers1.emplace_back(ref.GetRecordUniqueId());

return true;
});

std::vector<std::string> keys = vrs1.GetKeys();

VaultRecordSet vrs2 = std::move(vrs1);

TEST_ASSERT(vrs1.Size() == 0,"Failed to move Vault");
TEST_ASSERT(vrs1.GetKeys().empty(),"Failed to move Vault");

TEST_ASSERT(vrs2.Size() == 7,"Failed to move Vault");
TEST_ASSERT(keys == vrs2.GetKeys(),"Failed to move Vault");

std::type_index keyType = typeid(void);
vrs2.GetKeyType("A", keyType);
TEST_ASSERT(keyType == typeid(int),"Failed to move Vault");
vrs2.GetKeyType("B", keyType);
TEST_ASSERT(keyType == typeid(std::string),"Failed to move Vault");
vrs2.GetKeyType("C", keyType);
TEST_ASSERT(keyType == typeid(std::size_t),"Failed to move Vault");

std::vector<int> vecA2;
std::vector<std::string> vecB2;
std::vector<std::size_t> vecC2;
std::vector<std::string> pointers2;

vrs2.SortBy("A", [&](const VaultRecordRef& ref)
{
int A;
std::string B;
std::size_t C;

ref.GetData("A", A);
ref.GetData("B", B);
ref.GetData("C", C);

vecA2.emplace_back(std::move(A));
vecB2.emplace_back(std::move(B));
vecC2.emplace_back(std::move(C));
pointers2.emplace_back(ref.GetRecordUniqueId());

return true;
});

TEST_ASSERT(vecA1 == vecA2, "Failed to move Vault");
TEST_ASSERT(vecB1 == vecB2, "Failed to move Vault");
TEST_ASSERT(vecC1 == vecC2, "Failed to move Vault");
TEST_ASSERT(pointers1 == pointers2, "Failed to move Vault");

delete vlt;

TEST_ASSERT(vrs2.GetParentVaultUniqueId() == "null", "Failed to move Vault");

// Check clearing old data
vrs2 = VaultRecordSet();

TEST_ASSERT(vrs2.Size() == 0,"Failed to move Vault");
TEST_ASSERT(vrs2.GetKeys().empty(),"Failed to move Vault");
}

void VaultRecordSet_OperatorComparison_Test()
{
Vault vlt;
Expand Down Expand Up @@ -790,6 +974,8 @@ int main()
{
VaultRecordSet_CopyConstructor_Test();
VaultRecordSet_OperatorAssignment_Test();
VaultRecordSet_MoveConstructor_Test();
VaultRecordSet_MoveAssignment_Test();
VaultRecordSet_OperatorComparison_Test();
VaultRecordSet_GetIsParentVaultValid_Test();
VaultRecordSet_GetParentVaultUniqueId_Test();
Expand Down
6 changes: 6 additions & 0 deletions Tests/VaultUnitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ void Vault_MoveAssignment_Test()
TEST_ASSERT(vecB1 == vecB2, "Failed to move Vault");
TEST_ASSERT(vecC1 == vecC2, "Failed to move Vault");
TEST_ASSERT(pointers1 == pointers2, "Failed to move Vault");

// Check clearing old data
vlt2 = Vault();

TEST_ASSERT(vlt2.Size() == 0,"Failed to move Vault");
TEST_ASSERT(vlt2.GetKeys().empty(),"Failed to move Vault");
}

void Vault_AddKey_Test()
Expand Down

0 comments on commit 8e2e948

Please sign in to comment.