diff options
Diffstat (limited to 'searchlib/src/tests/util/bufferwriter/bufferwriter_test.cpp')
-rw-r--r-- | searchlib/src/tests/util/bufferwriter/bufferwriter_test.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/searchlib/src/tests/util/bufferwriter/bufferwriter_test.cpp b/searchlib/src/tests/util/bufferwriter/bufferwriter_test.cpp new file mode 100644 index 00000000000..95e4db95e03 --- /dev/null +++ b/searchlib/src/tests/util/bufferwriter/bufferwriter_test.cpp @@ -0,0 +1,158 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/fastos/fastos.h> +#include <vespa/log/log.h> +LOG_SETUP("bufferwriter_test"); +#include <vespa/vespalib/testkit/testapp.h> +#include <vespa/vespalib/stllike/string.h> +#include <vespa/searchlib/util/bufferwriter.h> +#include <vespa/searchlib/util/drainingbufferwriter.h> +#include <vespa/searchlib/util/rand48.h> + +namespace search +{ + +namespace +{ + +class StoreBufferWriter : public BufferWriter +{ + std::vector<char> _buf; + std::vector<std::unique_ptr<std::vector<char> > > _bufs; + size_t _bytesWritten; + uint32_t _incompleteBuffers; +public: + static constexpr size_t BUFFER_SIZE = 262144; + + StoreBufferWriter(); + + virtual ~StoreBufferWriter() = default; + + virtual void flush() override; + + size_t getBytesWritten() const { return _bytesWritten; } + + std::vector<char> getSingleBuffer() const; + +}; + + +StoreBufferWriter::StoreBufferWriter() + : BufferWriter(), + _buf(), + _bytesWritten(0), + _incompleteBuffers(0) +{ + _buf.resize(BUFFER_SIZE); + setup(&_buf[0], _buf.size()); +} + + +void +StoreBufferWriter::flush() { + assert(_incompleteBuffers == 0); // all previous buffers must have been full + size_t nowLen = usedLen(); + if (nowLen != _buf.size()) { + // buffer is not full, only allowed for last buffer + ++_incompleteBuffers; + } + if (nowLen == 0) { + return; // empty buffer + } + _bufs.emplace_back(std::make_unique<std::vector<char>>()); + _bufs.back()->resize(BUFFER_SIZE); + _buf.resize(nowLen); + _bufs.back()->swap(_buf); + _bytesWritten += nowLen; + setup(&_buf[0], _buf.size()); +} + + +std::vector<char> +StoreBufferWriter::getSingleBuffer() const +{ + std::vector<char> res; + size_t needSize = 0; + for (const auto &buf : _bufs) { + needSize += buf->size(); + } + res.reserve(needSize); + for (const auto &buf : _bufs) { + res.insert(res.end(), buf->cbegin(), buf->cend()); + } + return std::move(res); +} + +} + + +TEST("Test that bufferwriter works with no writes") +{ + DrainingBufferWriter writer; + writer.flush(); + EXPECT_EQUAL(0u, writer.getBytesWritten()); +} + +TEST("Test that bufferwriter works with single byte write") +{ + DrainingBufferWriter writer; + char a = 4; + writer.write(&a, sizeof(a)); + writer.flush(); + EXPECT_EQUAL(1u, writer.getBytesWritten()); +} + +TEST("Test that bufferwriter works with multiple writes") +{ + DrainingBufferWriter writer; + char a = 4; + int16_t b = 5; + int32_t c = 6; + writer.write(&a, sizeof(a)); + writer.write(&b, sizeof(b)); + writer.write(&c, sizeof(c)); + writer.flush(); + EXPECT_EQUAL(7u, writer.getBytesWritten()); +} + + +TEST("Test that bufferwriter works with long writes") +{ + std::vector<char> a; + const size_t mysize = 10000000; + const size_t drainerBufferSize = DrainingBufferWriter::BUFFER_SIZE; + EXPECT_GREATER(mysize, drainerBufferSize); + a.resize(mysize); + DrainingBufferWriter writer; + writer.write(&a[0], a.size()); + writer.flush(); + EXPECT_EQUAL(a.size(), writer.getBytesWritten()); +} + + +TEST("Test that bufferwriter passes on written data") +{ + std::vector<int> a; + const size_t mysize = 25000000; + const size_t drainerBufferSize = DrainingBufferWriter::BUFFER_SIZE; + EXPECT_GREATER(mysize * sizeof(int), drainerBufferSize); + a.reserve(mysize); + search::Rand48 rnd; + for (uint32_t i = 0; i < mysize; ++i) { + a.emplace_back(rnd.lrand48()); + } + StoreBufferWriter writer; + writer.write(&a[0], a.size() * sizeof(int)); + writer.flush(); + EXPECT_EQUAL(a.size() * sizeof(int), writer.getBytesWritten()); + std::vector<char> written = writer.getSingleBuffer(); + EXPECT_EQUAL(a.size() * sizeof(int), written.size()); + EXPECT_TRUE(memcmp(&a[0], &written[0], written.size()) == 0); +} + +} + +TEST_MAIN() +{ + TEST_RUN_ALL(); +} |