diff options
7 files changed, 103 insertions, 16 deletions
diff --git a/vespalib/src/vespa/vespalib/datastore/i_compactable.h b/vespalib/src/vespa/vespalib/datastore/i_compactable.h new file mode 100644 index 00000000000..599b2adfa20 --- /dev/null +++ b/vespalib/src/vespa/vespalib/datastore/i_compactable.h @@ -0,0 +1,19 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +namespace search::datastore { + +/** + * Interface for moving an entry as part of compaction of data in old + * buffers into new buffers. + * + * Old entry is unchanged and not placed on any hold lists since we + * expect the old buffers to be freed soon anyway. + */ +struct ICompactable { + virtual ~ICompactable() = default; + virtual EntryRef move(EntryRef ref) = 0; +}; + +} diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store.h b/vespalib/src/vespa/vespalib/datastore/unique_store.h index d5ae495a698..9dbd4f73821 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store.h +++ b/vespalib/src/vespa/vespalib/datastore/unique_store.h @@ -7,8 +7,10 @@ #include "datastore.h" #include "entryref.h" #include "entry_comparator_wrapper.h" +#include "unique_store_entry.h" #include "unique_store_comparator.h" #include "i_compaction_context.h" +#include "i_compactable.h" #include <vespa/vespalib/util/array.h> #include <vespa/vespalib/btree/btree.h> @@ -25,16 +27,17 @@ class UniqueStoreSaver; * 32-bit EntryRef. */ template <typename EntryT, typename RefT = EntryRefT<22> > -class UniqueStore +class UniqueStore : public ICompactable { public: using DataStoreType = DataStoreT<RefT>; using EntryType = EntryT; + using WrappedEntryType = UniqueStoreEntry<EntryType>; using RefType = RefT; using Saver = UniqueStoreSaver<EntryT, RefT>; using Builder = UniqueStoreBuilder<EntryT, RefT>; using Compare = UniqueStoreComparator<EntryType, RefType>; - using UniqueStoreBufferType = BufferType<EntryType>; + using UniqueStoreBufferType = BufferType<WrappedEntryType>; using DictionaryTraits = btree::BTreeTraits<32, 32, 7, true>; using Dictionary = btree::BTree<EntryRef, uint32_t, btree::NoAggregated, @@ -62,13 +65,17 @@ private: public: UniqueStore(); ~UniqueStore(); - EntryRef move(EntryRef ref); + EntryRef move(EntryRef ref) override; AddResult add(const EntryType &value); EntryRef find(const EntryType &value); - const EntryType &get(EntryRef ref) const + const WrappedEntryType &getWrapped(EntryRef ref) const { RefType iRef(ref); - return *_store.template getEntry<EntryType>(iRef); + return *_store.template getEntry<WrappedEntryType>(iRef); + } + const EntryType &get(EntryRef ref) const + { + return getWrapped(ref).value(); } void remove(EntryRef ref); ICompactionContext::UP compactWorst(); diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store.hpp index 9530072eae9..36986658e6a 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store.hpp +++ b/vespalib/src/vespa/vespalib/datastore/unique_store.hpp @@ -17,7 +17,8 @@ constexpr float ALLOC_GROW_FACTOR = 0.2; template <typename EntryT, typename RefT> UniqueStore<EntryT, RefT>::UniqueStore() - : _store(), + : ICompactable(), + _store(), _typeHandler(1, 2u, RefT::offsetSize(), NUM_ARRAYS_FOR_NEW_UNIQUESTORE_BUFFER, ALLOC_GROW_FACTOR), _typeId(0), _dict() @@ -48,7 +49,7 @@ UniqueStore<EntryT, RefT>::add(const EntryType &value) return AddResult(itr.getKey(), false); } else { - EntryRef newRef = _store.template allocator<EntryType>(_typeId).alloc(value).ref; + EntryRef newRef = _store.template allocator<WrappedEntryType>(_typeId).alloc(value).ref; _dict.insert(itr, newRef, 1u); return AddResult(newRef, true); } @@ -71,7 +72,7 @@ template <typename EntryT, typename RefT> EntryRef UniqueStore<EntryT, RefT>::move(EntryRef ref) { - return _store.template allocator<EntryType>(_typeId).alloc(get(ref)).ref; + return _store.template allocator<WrappedEntryType>(_typeId).alloc(getWrapped(ref)).ref; } template <typename EntryT, typename RefT> @@ -95,14 +96,17 @@ UniqueStore<EntryT, RefT>::remove(EntryRef ref) namespace uniquestore { -template <typename EntryT, typename RefT> +template <typename RefT> class CompactionContext : public ICompactionContext { private: - using UniqueStoreType = UniqueStore<EntryT, RefT>; - using Dictionary = typename UniqueStoreType::Dictionary; + using DictionaryTraits = btree::BTreeTraits<32, 32, 7, true>; + using Dictionary = btree::BTree<EntryRef, uint32_t, + btree::NoAggregated, + EntryComparatorWrapper, + DictionaryTraits>; DataStoreBase &_dataStore; Dictionary &_dict; - UniqueStoreType &_store; + ICompactable &_store; std::vector<uint32_t> _bufferIdsToCompact; std::vector<std::vector<EntryRef>> _mapping; @@ -140,7 +144,7 @@ private: public: CompactionContext(DataStoreBase &dataStore, Dictionary &dict, - UniqueStoreType &store, + ICompactable &store, std::vector<uint32_t> bufferIdsToCompact) : _dataStore(dataStore), _dict(dict), @@ -180,7 +184,7 @@ ICompactionContext::UP UniqueStore<EntryT, RefT>::compactWorst() { std::vector<uint32_t> bufferIdsToCompact = _store.startCompactWorstBuffers(true, true); - return std::make_unique<uniquestore::CompactionContext<EntryT, RefT>> + return std::make_unique<uniquestore::CompactionContext<RefT>> (_store, _dict, *this, std::move(bufferIdsToCompact)); } diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_builder.h b/vespalib/src/vespa/vespalib/datastore/unique_store_builder.h index 0a3ec447e67..8b46c4d630d 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_builder.h +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_builder.h @@ -19,6 +19,7 @@ class UniqueStoreBuilder { using DataStoreType = typename UniqueStoreType::DataStoreType; using Dictionary = typename UniqueStoreType::Dictionary; using EntryType = EntryT; + using WrappedEntryType = UniqueStoreEntry<EntryType>; using RefType = RefT; DataStoreType &_store; @@ -33,7 +34,7 @@ public: void setupRefCounts(); void makeDictionary(); void add(const EntryType &value) { - EntryRef newRef = _store.template allocator<EntryType>(_typeId).alloc(value).ref; + EntryRef newRef = _store.template allocator<WrappedEntryType>(_typeId).alloc(value).ref; _refs.push_back(newRef); } EntryRef mapEnumValueToEntryRef(uint32_t enumValue) { diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_comparator.h b/vespalib/src/vespa/vespalib/datastore/unique_store_comparator.h index bae42c5fe05..12c798fcd52 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_comparator.h +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_comparator.h @@ -3,6 +3,7 @@ #pragma once #include "entry_comparator.h" +#include "unique_store_entry.h" #include "datastore.h" namespace search::datastore { @@ -15,6 +16,7 @@ namespace search::datastore { template <typename EntryT, typename RefT> class UniqueStoreComparator : public EntryComparator { using EntryType = EntryT; + using WrappedEntryType = UniqueStoreEntry<EntryType>; using RefType = RefT; using DataStoreType = DataStoreT<RefT>; const DataStoreType &_store; @@ -28,7 +30,7 @@ public: inline const EntryType &get(EntryRef ref) const { if (ref.valid()) { RefType iRef(ref); - return *_store.template getEntry<EntryType>(iRef); + return _store.template getEntry<WrappedEntryType>(iRef)->value(); } else { return _value; } diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_entry.h b/vespalib/src/vespa/vespalib/datastore/unique_store_entry.h new file mode 100644 index 00000000000..b3468ecf523 --- /dev/null +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_entry.h @@ -0,0 +1,36 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "unique_store_entry_base.h" + +namespace search::datastore { + +/* + * Class for entries in unique store. + */ +template <typename EntryT> +class UniqueStoreEntry : public UniqueStoreEntryBase { + using EntryType = EntryT; + EntryType _value; +public: + UniqueStoreEntry() + : UniqueStoreEntryBase(), + _value() + { + } + explicit UniqueStoreEntry(const EntryType& value) + : UniqueStoreEntryBase(), + _value(value) + { + } + explicit UniqueStoreEntry(EntryType&& value) + : UniqueStoreEntryBase(), + _value(std::move(value)) + { + } + + const EntryType& value() const { return _value; } +}; + +} diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_entry_base.h b/vespalib/src/vespa/vespalib/datastore/unique_store_entry_base.h new file mode 100644 index 00000000000..49962ffc5c0 --- /dev/null +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_entry_base.h @@ -0,0 +1,18 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <cstring> + +namespace search::datastore { + +/* + * Class containing common metadata for entries in unique store. + */ +class UniqueStoreEntryBase { +protected: + UniqueStoreEntryBase() {} + ~UniqueStoreEntryBase() = default; +}; + +} |