diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2020-01-11 17:47:44 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-11 17:47:44 +0100 |
commit | b897bac08830142558b104ffcbc104b3ede755cd (patch) | |
tree | 10d1a2d725f84803b3f1420dbea60d31b867e558 /searchlib | |
parent | 5d77f9fe25dd5f143293d09e9086587d6b6a803e (diff) | |
parent | eb90cf9114c07234eddfa2ae03369860e4e9a1d4 (diff) |
Merge pull request #11749 from vespa-engine/balder/compact-buffer-after-compression
Balder/compact buffer after compression
Diffstat (limited to 'searchlib')
-rw-r--r-- | searchlib/src/tests/docstore/document_store/document_store_test.cpp | 9 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/docstore/value.cpp | 27 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/docstore/value.h | 1 |
3 files changed, 28 insertions, 9 deletions
diff --git a/searchlib/src/tests/docstore/document_store/document_store_test.cpp b/searchlib/src/tests/docstore/document_store/document_store_test.cpp index f950377be4b..04ec18aacc4 100644 --- a/searchlib/src/tests/docstore/document_store/document_store_test.cpp +++ b/searchlib/src/tests/docstore/document_store/document_store_test.cpp @@ -142,6 +142,15 @@ TEST("require that Value can store zstd compressed data") { verifyValue(S1, v); } +TEST("require that Value is shrunk to fit compressed data") { + Value v = createValue(S1, CompressionConfig::ZSTD); + EXPECT_EQUAL(CompressionConfig::ZSTD, v.getCompression()); + EXPECT_EQUAL(128u, v.size()); + EXPECT_EQUAL(128u, v.capacity()); + EXPECT_EQUAL(297u, v.getUncompressedSize()); + verifyValue(S1, v); +} + TEST("require that Value can detect if output not equal to input") { Value v = createValue(S1, CompressionConfig::NONE); const_cast<uint8_t *>(static_cast<const uint8_t *>(v.get()))[8] ^= 0xff; diff --git a/searchlib/src/vespa/searchlib/docstore/value.cpp b/searchlib/src/vespa/searchlib/docstore/value.cpp index ea29c894cba..09725b447cd 100644 --- a/searchlib/src/vespa/searchlib/docstore/value.cpp +++ b/searchlib/src/vespa/searchlib/docstore/value.cpp @@ -42,6 +42,19 @@ Value::set(vespalib::DataBuffer &&buf, ssize_t len) { set(std::move(buf), len, CompressionConfig()); } +namespace { + +vespalib::alloc::Alloc +compact(size_t sz, vespalib::alloc::Alloc buf) { + if (vespalib::roundUp2inN(sz) < vespalib::roundUp2inN(buf.size())) { + vespalib::alloc::Alloc shrunk = buf.create(sz); + memcpy(shrunk.get(), buf.get(), sz); + return shrunk; + } + return buf; +} + +} void Value::set(vespalib::DataBuffer &&buf, ssize_t len, const CompressionConfig &compression) { assert(len < std::numeric_limits<uint32_t>::max()); @@ -50,20 +63,16 @@ Value::set(vespalib::DataBuffer &&buf, ssize_t len, const CompressionConfig &com vespalib::ConstBufferRef input(buf.getData(), len); CompressionConfig::Type type = compress(compression, input, compressed, true); _compressedSize = compressed.getDataLen(); + _compression = type; + _uncompressedSize = len; + _uncompressedCrc = XXH64(input.c_str(), input.size(), 0); + _buf = std::make_shared<Alloc>(compact(_compressedSize, + (buf.getData() == compressed.getData()) ? buf.stealBuffer() : compressed.stealBuffer())); - if (buf.getData() == compressed.getData()) { - // Uncompressed so we can just steal the underlying buffer. - _buf = std::make_shared<Alloc>(buf.stealBuffer()); - } else { - _buf = std::make_shared<Alloc>(compressed.stealBuffer()); - } assert(((type == CompressionConfig::NONE) && (len == ssize_t(_compressedSize))) || ((type != CompressionConfig::NONE) && (len > ssize_t(_compressedSize)))); - _compression = type; - _uncompressedSize = len; - _uncompressedCrc = XXH64(input.c_str(), input.size(), 0); } Value::Result diff --git a/searchlib/src/vespa/searchlib/docstore/value.h b/searchlib/src/vespa/searchlib/docstore/value.h index f58d96e3e77..fb377abb2fb 100644 --- a/searchlib/src/vespa/searchlib/docstore/value.h +++ b/searchlib/src/vespa/searchlib/docstore/value.h @@ -42,6 +42,7 @@ public: Result decompressed() const; size_t size() const { return _compressedSize; } + size_t capacity() const { return _buf ? _buf->size() : 0; } bool empty() const { return size() == 0; } operator const void *() const { return get(); } const void *get() const; |