buffer_t.cc: more tests

This commit is contained in:
Heinz Mauelshagen 2013-01-23 13:28:00 +01:00
parent a762d34009
commit eed2dfdc38
3 changed files with 32 additions and 41 deletions

View File

@ -31,12 +31,14 @@
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <string.h> #include <string>
#include <malloc.h>
//---------------------------------------------------------------- //----------------------------------------------------------------
namespace persistent_data { namespace persistent_data {
uint32_t const MD_BLOCK_SIZE = 4096;
typedef uint64_t block_address; typedef uint64_t block_address;
template <uint32_t BlockSize = MD_BLOCK_SIZE> template <uint32_t BlockSize = MD_BLOCK_SIZE>

View File

@ -20,60 +20,40 @@
#define BUFFER_H #define BUFFER_H
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> // #include <stdlib.h>
#include <malloc.h>
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <stdexcept> #include <stdexcept>
#include <boost/noncopyable.hpp>
//---------------------------------------------------------------- //----------------------------------------------------------------
namespace persistent_data { namespace persistent_data {
uint32_t const DEFAULT_BUFFER_SIZE = 4096;
uint32_t const MD_BLOCK_SIZE = 4096; // Allocate buffer of Size with Alignment imposed.
// Allocate buffer
// //
// Allocation needs to be on the heap in order to provide alignment guarantees! // Allocation needs to be on the heap in order to provide alignment guarantees!
// //
// Alignment must be a power of two and a multiple of sizeof(void *) // Alignment must be a power of two.
template <uint32_t Size = DEFAULT_BUFFER_SIZE, uint32_t Alignment = 512>
// Heinz: could you move this to a separate file. Add a big
// comment explaining that you should allocate it on the heap if
// you want the alignment guarantees. Then write a test suite
// (buffer_t) that covers the following cases.
//
// - Allocate several on the heap, check they have the requested
// alignment. Try for various Alignments. If memalign has
// restrictions could you document (eg, power of 2).
// - you can use the [] to set a value in a non-const instance
// - you can't use the [] to set a value in a const instance - not
// sure how to do this, since it'll be a compile time error.
// - you can use [] to read back a value that you've set.
// - [] to read works in a const instance.
// - you can use raw() to get and set values.
// - an exception is thrown if you put too large an index in []
// - check you can't copy a buffer via a copy constructor or ==
// - (again a compile time error, just experiment so you understand
// - boost::noncopyable).
template <uint32_t BlockSize = MD_BLOCK_SIZE, uint32_t Alignment = 512>
class buffer : private boost::noncopyable { class buffer : private boost::noncopyable {
public: public:
typedef boost::shared_ptr<buffer> ptr;
unsigned char &operator[](unsigned index) { unsigned char &operator[](unsigned index) {
check_index(index); check_index(index);
return data_[index]; return data_[index];
} }
unsigned char const &operator[](unsigned index) const { unsigned char const &operator[](unsigned index) const {
check_index(index); check_index(index);
return data_[index]; return data_[index];
} }
@ -86,20 +66,25 @@ namespace persistent_data {
} }
static void *operator new(size_t s) { static void *operator new(size_t s) {
void *r; // void *r;
// return posix_memalign(&r, Alignment, s) ? NULL : r;
return ::posix_memalign(&r, Alignment, s) ? r : (void*) NULL; // Allocates size bytes and returns a pointer to the
// allocated memory. The memory address will be a
// multiple of 'Alignment', which must be a power of two
return memalign(Alignment, s);
} }
static void operator delete(void *p) { static void operator delete(void *p) {
free(p); free(p);
} }
private: protected:
unsigned char data_[BlockSize]; unsigned char data_[Size];
private:
static void check_index(unsigned index) { static void check_index(unsigned index) {
if (index >= BlockSize) if (index >= Size)
throw std::runtime_error("buffer index out of bounds"); throw std::runtime_error("buffer index out of bounds");
} }

View File

@ -17,6 +17,7 @@
# <http://www.gnu.org/licenses/>. # <http://www.gnu.org/licenses/>.
TEST_SOURCE=\ TEST_SOURCE=\
unit-tests/buffer_t.cc \
unit-tests/cache_t.cc \ unit-tests/cache_t.cc \
unit-tests/block_t.cc \ unit-tests/block_t.cc \
unit-tests/btree_t.cc \ unit-tests/btree_t.cc \
@ -31,6 +32,9 @@ unit-test: $(TEST_PROGRAMS)
.PHONY: unit-test .PHONY: unit-test
unit-tests/buffer_t: unit-tests/buffer_t.o $(OBJECTS)
g++ $(CXXFLAGS) $(INCLUDES) -o $@ $+ $(LIBS) $(LIBEXPAT)
unit-tests/block_t: unit-tests/block_t.o $(OBJECTS) unit-tests/block_t: unit-tests/block_t.o $(OBJECTS)
g++ $(CXXFLAGS) $(INCLUDES) -o $@ $+ $(LIBS) $(LIBEXPAT) g++ $(CXXFLAGS) $(INCLUDES) -o $@ $+ $(LIBS) $(LIBEXPAT)