Skip to content

Commit

Permalink
Merge branch 'gcc-4.8' into gcc-4.7
Browse files Browse the repository at this point in the history
  • Loading branch information
ony committed Apr 30, 2014
2 parents c90c3c3 + 3ecacc7 commit 255a1c9
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 15 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ Goals to stick with

Notes for development
---------------------
- tests should be run under valgrind also
- tests should be run under valgrind also unless built with libasan (sanitizer
from gcc 4.8)

Credits
-------
Expand Down
17 changes: 12 additions & 5 deletions include/leveldb/sandwich_db.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,19 @@ namespace leveldb
void SeekToLast()
{
auto p = prefix;
p.next_net();;
impl.Seek(p);
if (impl.Valid())
{ impl.Prev(); }
if (p == p.max())
{
impl.SeekToLast();
}
else
{ impl.SeekToLast(); }
{
p.next_net();;
impl.Seek(p);
if (impl.Valid())
{ impl.Prev(); }
else
{ impl.SeekToLast(); }
}
}
void Next() { impl.Next(); }
void Prev() { impl.Prev(); }
Expand Down
28 changes: 24 additions & 4 deletions include/leveldb/sequence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#pragma once

#include <limits>

#include <leveldb/any_db.hpp>

namespace leveldb
Expand Down Expand Up @@ -62,6 +64,9 @@ namespace leveldb
host_order<T> &operator--()
{ --value; return *this; }

static constexpr host_order<T> max()
{ return std::numeric_limits<T>::max(); }

// arithmetic in network order
host_order<T> &next_net()
{
Expand Down Expand Up @@ -126,15 +131,23 @@ namespace leveldb
template <typename T1>
Status Next(T1 &value)
{
assert(next <= allocated);
assert( allocated == 0 || next <= allocated );

if (next == allocated)
if (allocated == 0) // noting allocated yet
{
Status s = AllocPage();
if (!s.ok()) return s;
}

value = next++;
if (next == allocated)
{
value = next++;
(void) AllocPage(); // pre-allocate next page for next request
}
else
{
value = next++;
}
return Status::OK();
}

Expand All @@ -151,6 +164,7 @@ namespace leveldb
if (allocated == 0) // initial (need to load prev value)
{
allocated = v;
if (allocated == 0) return Status::NotFound("sequence overflow");
next = allocated;
}
else if (allocated != host_order<T>{v})
Expand All @@ -166,7 +180,13 @@ namespace leveldb
return s;
}

const host_order<T> nextAllocated = allocated + PAGE_SIZE;
const host_order<T> nextAllocated = std::min(size_t(allocated.max()), allocated + PAGE_SIZE);
if (nextAllocated == allocated) // overflow
{
(void) base.Put(key, host_order<T>{0}); // mark as overflow
allocated = 0;
return Status::NotFound("meet sequence overflow");
}
s = base.Put(key, nextAllocated);
if (s.ok()) allocated = nextAllocated;
return s;
Expand Down
8 changes: 3 additions & 5 deletions test/simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,7 @@ TEST(Simple, sequence)
leveldb::MemoryDB db;
short x;

vector<short> e;

leveldb::Sequence<short> a(db, "x");
leveldb::Sequence<unsigned short> a(db, "x");
ASSERT_OK( a.Next(x) );
EXPECT_EQ( 0, x );
ASSERT_OK( a.Next(x) );
Expand All @@ -324,8 +322,8 @@ TEST(Simple, sequence)

string v;

leveldb::Sequence<short> z(std::move(a));
leveldb::Sequence<short> b(db, "x");
leveldb::Sequence<unsigned short> z(std::move(a));
leveldb::Sequence<unsigned short> b(db, "x");
EXPECT_OK( db.Get("x", v) );
ASSERT_OK( b.Next(x) );
EXPECT_EQ( 2, x ) << "In db " << PrintToString(v);
Expand Down
48 changes: 48 additions & 0 deletions test/test_corners.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "leveldb/memory_db.hpp"
#include "leveldb/whiteout_db.hpp"
#include "leveldb/sandwich_db.hpp"
#include "leveldb/txn_db.hpp"
#include "leveldb/walker.hpp"

Expand Down Expand Up @@ -331,3 +332,50 @@ TEST(TestTxnIterator, txn_insert_next)
ASSERT_TRUE( w.Valid() );
EXPECT_EQ( "d", w.key() );
}

TEST(TestSequence, sequence_overflow)
{
leveldb::MemoryDB db;
leveldb::Sequence<unsigned char> seq {db, "x"};
for(size_t n = 0; n < 0x100; ++n)
{
unsigned char x;
ASSERT_OK( seq.Next(x) );
EXPECT_EQ( n, x );
}
unsigned char overflow;
EXPECT_STATUS( NotFound, seq.Next(overflow) );
}

TEST(TestSandwichIterator, stuff_sandwich_to_overflow)
{
leveldb::SandwichDB<leveldb::MemoryDB, unsigned char> sdb;
for(size_t n = 0; n < 0xff; ++n) // one part reserved for meta
{
SCOPED_TRACE("n=" + to_string(n));
decltype(sdb)::Cookie cookie;
ASSERT_OK( sdb.cook(to_string(n), cookie) )
<< "Failed to allocate cookie #" << n;
auto db = sdb.use(cookie);
ASSERT_OK( db.Put("a", "first") );
ASSERT_OK( db.Put("b", "second") );
ASSERT_OK( db.Put("z", "last") );

auto w = leveldb::walker(db);

w.SeekToFirst();
ASSERT_TRUE( w.Valid() );
EXPECT_EQ( "a", w.key() );

w.Next();
ASSERT_TRUE( w.Valid() );
EXPECT_EQ( "b", w.key() );

w.SeekToLast();
ASSERT_TRUE( w.Valid() );
EXPECT_EQ( "z", w.key() );
}
decltype(sdb)::Cookie cookie;
ASSERT_STATUS( NotFound, sdb.cook("overflow", cookie) )
<< "Allocated overflow as " << PrintToString(cookie);
}

0 comments on commit 255a1c9

Please sign in to comment.