Skip to content

Commit

Permalink
fix Contiguity + add test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
bastidest committed Nov 12, 2023
1 parent b8c27e0 commit 3a0e678
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 28 deletions.
49 changes: 23 additions & 26 deletions src/ChunkedJournal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@
namespace jess
{

enum class Adjacency {
NON_ADJACENT,
AFTER_CURRENT,
BEFORE_CURRENT,
};

enum class Contiguity {
CONTIGUOUS,
NON_CONTIGUOUS,
OVERLAPPING,
};

enum class InsertPosition {
BEFORE,
AFTER,
};

struct Chunk {
std::map<SdSeqnumId, SdSeqnum> lowestIdsInChunk{};
std::map<SdSeqnumId, SdSeqnum> highestIdsInChunk{};
Expand Down Expand Up @@ -52,7 +53,7 @@ class ChunkedJournal
const auto& getChunks() const { return m_chunks; }

private:
auto createChunkAtCurrentPosition( const InsertPosition insertPos, const Contiguity contiguity ) -> decltype( m_chunks.begin() )
auto createChunkAtCurrentPosition( const Adjacency adjacency ) -> decltype( m_chunks.begin() )
{
Chunk newChunk{ {}, {}, {} };

Expand Down Expand Up @@ -84,27 +85,23 @@ class ChunkedJournal
}

auto insertIt = m_pCurrentChunk;
if ( insertPos == InsertPosition::AFTER )
if ( adjacency == Adjacency::AFTER_CURRENT )
{
std::advance( insertIt, 1 );
}
auto newChunkIt = m_chunks.insert( insertIt, std::move( newChunk ) );

if ( insertPos == InsertPosition::BEFORE )
if ( adjacency == Adjacency::BEFORE_CURRENT )
{
newChunkIt->contiguityEnd = contiguity;
if ( m_pCurrentChunk != m_chunks.end() )
{
m_pCurrentChunk->contiguityBeginning = contiguity;
}
assert( m_pCurrentChunk != m_chunks.end() );
newChunkIt->contiguityEnd = Contiguity::CONTIGUOUS;
m_pCurrentChunk->contiguityBeginning = Contiguity::CONTIGUOUS;
}
else if ( insertPos == InsertPosition::AFTER )
else if ( adjacency == Adjacency::AFTER_CURRENT )
{
if ( m_pCurrentChunk != m_chunks.end() )
{
m_pCurrentChunk->contiguityEnd = contiguity;
}
newChunkIt->contiguityBeginning = contiguity;
assert( m_pCurrentChunk != m_chunks.end() );
m_pCurrentChunk->contiguityEnd = Contiguity::CONTIGUOUS;
newChunkIt->contiguityBeginning = Contiguity::CONTIGUOUS;
}

return newChunkIt;
Expand All @@ -127,7 +124,7 @@ class ChunkedJournal
return ret;
}

void loadChunkAtCurrentPosition( const InsertPosition insertPos, const Contiguity contiguity )
void loadChunkAtCurrentPosition( const Adjacency adjacency )
{
const auto seqid = m_journal.getSeqid();
if ( auto chunks = getChunksBySeqid( seqid ); !chunks.empty() )
Expand All @@ -136,7 +133,7 @@ class ChunkedJournal
}
else
{
m_pCurrentChunk = createChunkAtCurrentPosition( insertPos, contiguity );
m_pCurrentChunk = createChunkAtCurrentPosition( adjacency );
}
}

Expand All @@ -145,15 +142,15 @@ class ChunkedJournal
{
m_journal.seekToBof();
m_journal.next();
loadChunkAtCurrentPosition( InsertPosition::BEFORE, Contiguity::CONTIGUOUS );
loadChunkAtCurrentPosition( Adjacency::NON_ADJACENT );
m_uLineOffsetInChunk = 0;
}

void seekToEof()
{
m_journal.seekToEof();
m_journal.next();
loadChunkAtCurrentPosition( InsertPosition::AFTER, Contiguity::CONTIGUOUS );
loadChunkAtCurrentPosition( Adjacency::NON_ADJACENT );
m_uLineOffsetInChunk = m_uChunkSize - 1;
}

Expand All @@ -173,14 +170,14 @@ class ChunkedJournal
const size_t uNumChunksToSkip = uNewOffsetRelativeToEndOfCurrentChunk / m_uChunkSize;
m_uLineOffsetInChunk = uNewOffsetRelativeToEndOfCurrentChunk - uNumChunksToSkip * m_uChunkSize;

if ( const size_t uLinesToSeek = uNumChunksToSkip * m_uChunkSize; uLinesToSeek > 0)
if ( const size_t uLinesToSeek = uNumChunksToSkip * m_uChunkSize; uLinesToSeek > 0 )
{
m_journal.seekLinesForward( uLinesToSeek );
m_journal.next();
}

const Contiguity contiguity = uNumChunksToSkip == 0 ? Contiguity::CONTIGUOUS : Contiguity::NON_CONTIGUOUS;
loadChunkAtCurrentPosition( InsertPosition::AFTER, contiguity );
const Adjacency adjacency = uNumChunksToSkip == 0 ? Adjacency::AFTER_CURRENT : Adjacency::NON_ADJACENT;
loadChunkAtCurrentPosition( adjacency );
return;
}

Expand Down
50 changes: 48 additions & 2 deletions test/ChunkedJournal_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ TEST_CASE( "ChunkedJournal(1) load BOF" )
REQUIRE( chunks.size() == 1 );

const jess::Chunk& firstChunk = chunks.front();
CHECK( firstChunk.contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( firstChunk.contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );
checkSequence( firstChunk, 1, 0 );

SUBCASE( "seeking to BOF shall again shall not change anything" )
Expand All @@ -85,9 +87,13 @@ TEST_CASE( "ChunkedJournal(1) load BOF" )
REQUIRE_MESSAGE( &chunks.front() == &firstChunk, "the first chunk shall remain at the first position" );

checkSequence( firstChunk, 1, 0 );
CHECK( firstChunk.contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( firstChunk.contiguityEnd == jess::Contiguity::CONTIGUOUS );

const jess::Chunk& secondChunk = chunks2.back();
checkSequence( secondChunk, 1, 1 );
CHECK( secondChunk.contiguityBeginning == jess::Contiguity::CONTIGUOUS );
CHECK( secondChunk.contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );
}
}

Expand All @@ -100,6 +106,8 @@ TEST_CASE( "ChunkedJournal(2) load BOF" )

const jess::Chunk& firstChunk = chunks.front();
checkSequence( firstChunk, 2, 0 );
CHECK( firstChunk.contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( firstChunk.contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );

SUBCASE( "seeking to BOF shall again shall not change anything" )
{
Expand All @@ -116,6 +124,8 @@ TEST_CASE( "ChunkedJournal(2) load BOF" )
REQUIRE( chunks2.size() == 1 );
REQUIRE_MESSAGE( &chunks.front() == &firstChunk, "the first chunk shall remain at the first position" );
checkSequence( chunks.front(), 2, 0 );
CHECK( firstChunk.contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( firstChunk.contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );
}

SUBCASE( "advance another line" )
Expand All @@ -127,6 +137,11 @@ TEST_CASE( "ChunkedJournal(2) load BOF" )

checkSequence( chunks.front(), 2, 0 );
checkSequence( chunks.back(), 2, 2 );

CHECK( chunks.front().contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( chunks.front().contiguityEnd == jess::Contiguity::CONTIGUOUS );
CHECK( chunks.back().contiguityBeginning == jess::Contiguity::CONTIGUOUS );
CHECK( chunks.back().contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );
}
}

Expand All @@ -139,6 +154,11 @@ TEST_CASE( "ChunkedJournal(2) load BOF" )

checkSequence( chunks.front(), 2, 0 );
checkSequence( chunks.back(), 2, 2 );

CHECK( chunks.front().contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( chunks.front().contiguityEnd == jess::Contiguity::CONTIGUOUS );
CHECK( chunks.back().contiguityBeginning == jess::Contiguity::CONTIGUOUS );
CHECK( chunks.back().contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );
}
}

Expand All @@ -150,6 +170,8 @@ TEST_CASE( "ChunkedJournal(3) load BOF" )
REQUIRE( chunks.size() == 1 );

checkSequence( chunks.front(), 3, 0 );
CHECK( chunks.front().contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( chunks.front().contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );
}

TEST_CASE( "ChunkedJournal(1) load EOF" )
Expand All @@ -158,16 +180,40 @@ TEST_CASE( "ChunkedJournal(1) load EOF" )
sut.seekToEof();
const std::list<jess::Chunk>& chunks = sut.getChunks();
REQUIRE( chunks.size() == 1 );
checkSequence( chunks.front(), 1, 9 );
const jess::Chunk& lastChunk = chunks.front();
checkSequence( lastChunk, 1, 9 );
CHECK( lastChunk.contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( lastChunk.contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );

SUBCASE( "seek to BOF" )
{
sut.seekToBof();
REQUIRE( chunks.size() == 2 );
checkSequence( chunks.front(), 1, 0 );
const jess::Chunk& firstChunk = chunks.front();
checkSequence( firstChunk, 1, 0 );
CHECK( firstChunk.contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( firstChunk.contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );
CHECK( lastChunk.contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( lastChunk.contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );

SUBCASE( "load next line" )
{
sut.seekLines( 1 );
REQUIRE( chunks.size() == 3 );
auto it = chunks.begin();
std::advance( it, 1 );
const jess::Chunk& secondChunk = *it;
REQUIRE( &secondChunk != &firstChunk );
REQUIRE( &secondChunk != &lastChunk );
checkSequence( secondChunk, 1, 1 );
CHECK( firstChunk.contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( firstChunk.contiguityEnd == jess::Contiguity::CONTIGUOUS );
CHECK( secondChunk.contiguityBeginning == jess::Contiguity::CONTIGUOUS );
CHECK( secondChunk.contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );
CHECK( lastChunk.contiguityBeginning == jess::Contiguity::NON_CONTIGUOUS );
CHECK( lastChunk.contiguityEnd == jess::Contiguity::NON_CONTIGUOUS );
}
}
}

// todo: check skipping a chunk

0 comments on commit 3a0e678

Please sign in to comment.