jens@0: /* jens@0: * Ottoman_test.cpp jens@0: * Ottoman jens@0: * jens@0: * Created by Jens Alfke on 9/11/09. jens@0: * Copyright 2009 Jens Alfke. All rights reserved. jens@0: * BSD-Licensed: See the file "LICENSE.txt" for details. jens@0: */ jens@0: jens@0: #include jens@0: #include "TestUtils.h" jens@0: #include "Chunk.h" jens@0: #include "Ottoman.h" jens@0: #include "VersionDictionary.h" jens@0: #include jens@0: #include jens@0: jens@0: using namespace Mooseyard; jens@0: jens@0: jens@0: TEST(Ottoman,Build) { jens@0: ASSERT_EQ(8, sizeof(Chunk)); jens@0: ASSERT_EQ(8, sizeof(KeyValueChunk)); jens@0: jens@0: time_t startTime = ::time(NULL); jens@0: time_t createTime; jens@0: { jens@0: Ottoman otto; jens@0: EXPECT_EQ((void*)NULL, otto.lastVersion()); jens@0: ASSERT_NE((void*)NULL, otto.currentVersion()); jens@0: readWords(); jens@0: for( int i=0; iput(Key(kv),kv); jens@0: } jens@0: Timer t("Saving Ottoman", sNWords); jens@0: otto.saveAs("/tmp/test.ottoman"); jens@0: jens@0: VersionDictionary *last = otto.lastVersion(); jens@0: ASSERT_NE((void*)NULL, last); jens@0: EXPECT_EQ(sNWords, last->count()); jens@0: ASSERT_NE((void*)NULL, otto.currentVersion()); jens@0: EXPECT_FALSE(otto.currentVersion()->isChanged()); jens@0: createTime = last->timestamp(); jens@0: EXPECT_GE(createTime, startTime); jens@0: EXPECT_LE(createTime, ::time(NULL)); jens@0: } jens@0: { jens@0: Ottoman otto("/tmp/test.ottoman"); jens@0: VersionDictionary *last = otto.lastVersion(); jens@0: ASSERT_NE((void*)NULL, last); jens@0: ASSERT_EQ(0, last->generation()); jens@0: ASSERT_EQ(createTime, last->timestamp()); jens@0: { jens@0: Timer t("Reading from Ottoman", sNWords); jens@0: EXPECT_EQ( sNWords , last->count() ); jens@0: for( int i=0; iget(key); jens@0: ASSERT_TRUE(value); jens@0: ASSERT_TRUE( value.equals(key) ) << "expected '" << key << "', got '" << value << "' (i=" << i <<")"; jens@0: } jens@0: } jens@0: jens@0: printf("Iterating through the Ottoman...\n"); jens@0: Timer t("Iterating Ottoman", sNWords); jens@0: int n=0; jens@0: for( VersionDictionary::Iterator it(last); it; ++it) { jens@0: n++; jens@0: ASSERT_TRUE(it.key().length > 0 && it.key().length < 50); jens@0: ASSERT_TRUE(it.key().equals(it.value())); jens@0: ASSERT_EQ( 0, ((size_t)it.value().bytes & 0x3) ); // 4-byte aligned jens@0: } jens@0: ASSERT_EQ(sNWords, n); jens@0: } jens@0: { jens@0: printf("Opening Ottoman...\n"); jens@0: Ottoman otto("/tmp/test.ottoman"); jens@0: OverlayDictionary *current = otto.currentVersion(); jens@0: ASSERT_TRUE(current != NULL); jens@0: EXPECT_EQ( sNWords , current->count() ); jens@0: EXPECT_TRUE(current->get("asparagus").equals("asparagus")); jens@0: jens@0: current->put("animal", "AMINAL"); jens@0: current->put("growf", "growf"); jens@0: EXPECT_TRUE(current->remove("asparagus")); jens@0: jens@0: EXPECT_EQ( sNWords, current->count() ); jens@0: EXPECT_TRUE(current->get("animal").equals("AMINAL")); jens@0: EXPECT_TRUE(current->get("growf").equals("growf")); jens@0: EXPECT_EQ( NULL, current->get("asparagus").bytes ); jens@0: EXPECT_TRUE(!current->contains("asparagus")); jens@0: jens@0: int n=0; jens@0: for( OverlayDictionary::Iterator it(*current); it; ++it) { jens@0: n++; jens@0: ASSERT_TRUE(!it.key().equals("asparagus")); jens@0: } jens@0: ASSERT_EQ(sNWords, n); jens@0: jens@0: printf("Saving Ottoman...\n"); jens@0: { jens@0: Timer t("Saving Ottoman"); jens@0: otto.save(); jens@0: } jens@0: jens@0: EXPECT_EQ( sNWords, current->count() ); jens@0: EXPECT_TRUE(current->get("animal").equals("AMINAL")); jens@0: EXPECT_TRUE(current->get("growf").equals("growf")); jens@0: EXPECT_EQ( NULL, current->get("asparagus").bytes ); jens@0: EXPECT_TRUE(!current->contains("asparagus")); jens@0: jens@0: n=0; jens@0: for( OverlayDictionary::Iterator it(*current); it; ++it) { jens@0: n++; jens@0: ASSERT_TRUE(!it.key().equals("asparagus")); jens@0: } jens@0: ASSERT_EQ(sNWords, n); jens@0: jens@0: EXPECT_EQ(1, otto.lastVersion()->generation()); jens@0: const VersionDictionary *prev = otto.lastVersion()->previousVersion(); jens@0: ASSERT_TRUE(prev != NULL); jens@0: EXPECT_EQ(0, prev->generation()); jens@0: EXPECT_TRUE(prev->get("asparagus").equals("asparagus")); jens@0: EXPECT_TRUE(prev->get("growf").equals(NULL)); jens@0: } jens@0: { jens@0: printf("Re-opening Ottoman...\n"); jens@0: Ottoman otto("/tmp/test.ottoman", false); jens@0: ASSERT_EQ(NULL, otto.currentVersion()); jens@0: VersionDictionary *last = otto.lastVersion(); jens@0: ASSERT_TRUE(last != NULL); jens@0: EXPECT_EQ(1, last->generation()); jens@0: EXPECT_GE(last->timestamp(), createTime); jens@0: EXPECT_LE(last->timestamp(), ::time(NULL)); jens@0: EXPECT_EQ( sNWords , last->count() ); jens@0: EXPECT_TRUE(last->get("animal").equals("AMINAL")); jens@0: EXPECT_TRUE(last->get("growf").equals("growf")); jens@0: EXPECT_EQ( NULL, last->get("asparagus").bytes ); jens@0: EXPECT_TRUE(!last->contains("asparagus")); jens@0: jens@0: int n=0; jens@0: for( VersionDictionary::Iterator it(last); it; ++it) { jens@0: n++; jens@0: ASSERT_TRUE(!it.key().equals("asparagus")); jens@0: } jens@0: ASSERT_EQ(sNWords, n); jens@0: } jens@0: { jens@0: printf("Writing Ottoman to a new file...\n"); jens@0: Ottoman oldhf("/tmp/test.ottoman"); jens@0: jens@0: oldhf.saveAs("/tmp/test2.ottoman"); jens@0: } jens@0: { jens@0: printf("Opening new file...\n"); jens@0: Ottoman otto("/tmp/test2.ottoman"); jens@0: OverlayDictionary *current = otto.currentVersion(); jens@0: ASSERT_TRUE(current != NULL); jens@0: jens@0: EXPECT_EQ( sNWords , current->count() ); jens@0: EXPECT_TRUE(current->get("animal").equals("AMINAL")); jens@0: EXPECT_TRUE(current->get("growf").equals("growf")); jens@0: EXPECT_EQ( NULL, current->get("asparagus").bytes ); jens@0: EXPECT_TRUE(!current->contains("asparagus")); jens@0: jens@0: int n=0; jens@0: for( OverlayDictionary::Iterator it(*current); it; ++it) { jens@0: n++; jens@0: ASSERT_TRUE(!it.key().equals("asparagus")); jens@0: } jens@0: ASSERT_EQ(sNWords, n); jens@0: jens@0: printf("Iterating the chunks...\n"); jens@0: int lastType = -1; jens@0: int count = 0; jens@0: n = 0; jens@0: ChunkIterator *it = otto.chunkIterator(); jens@0: for (; *it; it->next()) { jens@0: uint16_t type = it->chunk()->type(); jens@0: if (type != lastType) { jens@0: if (count > 0) jens@0: printf("%6d\n", count); jens@0: printf("type %u ... ", type); jens@0: lastType = type; jens@0: count = 0; jens@0: } jens@0: count++; jens@0: ASSERT_LE(type, 3); jens@0: if (type != 0) // don't count padding chunks jens@0: n++; jens@0: } jens@0: if (count > 0) jens@0: printf("%6d\n", count); jens@0: printf("Iterated over %i chunks\n",n); jens@0: EXPECT_EQ(sNWords+256+1, n); jens@0: EXPECT_TRUE(it->atEOF()); jens@0: jens@0: printf("Scavenging...\n"); jens@0: EXPECT_TRUE( otto.scavenge() ); jens@0: } jens@0: } jens@0: