TEST_F( SegmentTest, Remove ) { std::unordered_map<TID, uint32_t> values; // TID -> testData entry // Insert some records for ( uint32_t i = 0; i < 500; ++i ) { // Select string/record to insert uint64_t r = rand() % testData.size(); const std::string s = testData[r]; // Insert record TID tid = segment->Insert( Record( static_cast<uint32_t>(s.size()), reinterpret_cast<const uint8_t*>(s.c_str()) ) ); EXPECT_EQ( values.find( tid ), values.end() ); // TIDs should not be overwritten values[tid] = static_cast<uint32_t>(r); } std::unordered_map<TID, bool> removed; // TID -> is removed // Remove records for ( std::pair<TID, uint32_t> tidValue : values ) { if ( rand() > RAND_MAX * 0.5 ) { bool removeSuccess = segment->Remove( tidValue.first ); EXPECT_EQ( true, removeSuccess ); removed.insert( std::make_pair( tidValue.first, true ) ); } else { removed.insert( std::make_pair( tidValue.first, false ) ); } } // Check over every record if it was correctly removed/kept for ( std::pair<TID, uint32_t> tidValue : values ) { if ( removed[tidValue.first] ) { Record rec = segment->Lookup( tidValue.first ); EXPECT_EQ( 0, rec.GetLen() ); EXPECT_EQ( nullptr, rec.GetData() ); } else { const std::string& value = testData[tidValue.second]; uint32_t len = static_cast<uint32_t>(value.size()); Record rec = segment->Lookup( tidValue.first ); EXPECT_EQ( len, rec.GetLen() ); EXPECT_EQ( 0, memcmp( rec.GetData(), value.c_str(), len ) ); } } };
TEST_F(SegmentTest, InsertLookup ) { std::unordered_map<TID, uint32_t> values; // TID -> testData entry // Insert some records for ( uint32_t i = 0; i < 500; ++i ) { // Select string/record to insert uint64_t r = rand() % testData.size(); const std::string s = testData[r]; // Insert record TID tid = segment->Insert( Record( static_cast<uint32_t>(s.size()), reinterpret_cast<const uint8_t*>(s.c_str()) ) ); EXPECT_EQ( values.find( tid ), values.end() ); // TIDs should not be overwritten values[tid] = static_cast<uint32_t>(r); } // Every value has to be the same as it was inserted for ( std::pair<TID, uint32_t> tidValue : values ) { const std::string& value = testData[tidValue.second]; uint32_t len = static_cast<uint32_t>(value.size()); Record rec = segment->Lookup( tidValue.first ); EXPECT_EQ( len, rec.GetLen() ); EXPECT_EQ( 0, memcmp( rec.GetData(), value.c_str(), len ) ); } };
TEST_F( SegmentTest, Update ) { std::unordered_map<TID, uint32_t> values; // TID -> testData entry std::vector<TID> tids; // Insert some records for ( uint32_t i = 0; i < 500; ++i ) { // Select string/record to insert uint64_t r = rand() % testData.size(); const std::string s = testData[r]; // Insert record TID tid = segment->Insert( Record( static_cast<uint32_t>(s.size()), reinterpret_cast<const uint8_t*>(s.c_str()) ) ); tids.push_back( tid ); EXPECT_EQ( values.find( tid ), values.end() ); // TIDs should not be overwritten values[tid] = static_cast<uint32_t>(r); } // Update random records for ( uint32_t i = 0; i < 1000; ++i ) { // Select new string / record TID target = tids[rand() % tids.size()]; uint32_t r = rand() % testData.size(); const std::string s = testData[r]; // Replace old with new value bool success = segment->Update( target, Record( static_cast<uint32_t>(s.size()), reinterpret_cast<const uint8_t*>(s.c_str()) ) ); EXPECT_EQ( true, success ); values[target] = static_cast<uint32_t>(r); } // Every value has to be the same as it was inserted/updated to for ( std::pair<TID, uint32_t> tidValue : values ) { const std::string& value = testData[tidValue.second]; uint32_t len = static_cast<uint32_t>(value.size()); Record rec = segment->Lookup( tidValue.first ); EXPECT_EQ( len, rec.GetLen() ); EXPECT_EQ( 0, memcmp( rec.GetData(), value.c_str(), len ) ); } };
TEST_F( SegmentTest, RandomOperations ) { // Random interspersed operations std::unordered_map<TID, uint32_t> values; // TID -> testData entry std::vector<TID> tids; // Insert some baseline records for ( uint32_t i = 0; i < 100; ++i ) { // Select string/record to insert uint64_t r = rand() % testData.size(); const std::string s = testData[r]; // Insert record TID tid = segment->Insert( Record( static_cast<uint32_t>(s.size()), reinterpret_cast<const uint8_t*>(s.c_str()) ) ); tids.push_back( tid ); EXPECT_EQ( values.find( tid ), values.end() ); // TIDs should not be overwritten values[tid] = static_cast<uint32_t>(r); } // Random ops for ( uint32_t i = 0; i < 10000; ++i ) { float chance = static_cast<float>(rand()) / RAND_MAX; if (chance < 0.70) { // Insert // Select string/record to insert uint64_t r = rand() % testData.size(); const std::string s = testData[r]; // Insert record TID tid = segment->Insert( Record( static_cast<uint32_t>(s.size()), reinterpret_cast<const uint8_t*>(s.c_str()) ) ); EXPECT_EQ( values.find( tid ), values.end() ); // TIDs should not be overwritten tids.push_back( tid ); values[tid] = static_cast<uint32_t>(r); } else if (chance < 0.9) { // Update // Select new string / record TID target = tids[rand() % tids.size()]; uint32_t r = rand() % testData.size(); const std::string s = testData[r]; // Replace old with new value bool success = segment->Update( target, Record( static_cast<uint32_t>(s.size()), reinterpret_cast<const uint8_t*>(s.c_str()) ) ); EXPECT_EQ( true, success ); values[target] = static_cast<uint32_t>(r); } else { // Remove uint32_t inTid = rand() % tids.size(); TID target = tids[inTid]; bool removeSuccess = segment->Remove( target ); EXPECT_EQ( true, removeSuccess ); // Remove from our tid map and tid vector as well values.erase( target ); tids[inTid] = tids[tids.size() - 1]; tids.pop_back(); } } // Every value has to be the same as it was inserted/updated to for ( std::pair<TID, uint32_t> tidValue : values ) { // Not removed, normal check const std::string& value = testData[tidValue.second]; uint32_t len = static_cast<uint32_t>(value.size()); Record rec = segment->Lookup( tidValue.first ); EXPECT_EQ( len, rec.GetLen() ); EXPECT_EQ( 0, memcmp( rec.GetData(), value.c_str(), len ) ); } };