aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.h
blob: 79939ff9499ad91fc01af422a1da1f6365b7edb9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include "multi_value_mapping_base.h"
#include "multi_value_mapping_read_view.h"
#include <vespa/vespalib/datastore/array_store.h>
#include <vespa/vespalib/datastore/array_store_dynamic_type_mapper.h>
#include <vespa/vespalib/datastore/dynamic_array_buffer_type.h>
#include <vespa/vespalib/util/address_space.h>

namespace search::attribute {

/**
 * Class for mapping from document id to an array of values.
 */
template <typename ElemT, typename RefT = vespalib::datastore::EntryRefT<19> >
class MultiValueMapping : public MultiValueMappingBase
{
public:
    using MultiValueType = ElemT;
    using RefType = RefT;
    using ReadView = MultiValueMappingReadView<ElemT, RefT>;

    static constexpr double array_store_grow_factor = 1.03;
    static constexpr uint32_t array_store_max_type_id = 300;
private:
    using ArrayRef = vespalib::ArrayRef<ElemT>;
    using ArrayStoreTypeMapper = vespalib::datastore::ArrayStoreDynamicTypeMapper<ElemT>;
    using ArrayStore = vespalib::datastore::ArrayStore<ElemT, RefT, ArrayStoreTypeMapper>;
    using generation_t = vespalib::GenerationHandler::generation_t;
    using ConstArrayRef = vespalib::ConstArrayRef<ElemT>;

    ArrayStore _store;
public:
    MultiValueMapping(const MultiValueMapping &) = delete;
    MultiValueMapping & operator = (const MultiValueMapping &) = delete;
    MultiValueMapping(const vespalib::datastore::ArrayStoreConfig &storeCfg,
                      size_t max_buffer_size,
                      const vespalib::GrowStrategy &gs,
                      std::shared_ptr<vespalib::alloc::MemoryAllocator> memory_allocator);
    ~MultiValueMapping() override;
    ConstArrayRef get(uint32_t docId) const { return _store.get(acquire_entry_ref(docId)); }
    ConstArrayRef getDataForIdx(EntryRef idx) const { return _store.get(idx); }
    void set(uint32_t docId, ConstArrayRef values);

    // get_writable is generally unsafe and should only be used when
    // compacting enum store (replacing old enum index with updated enum index)
    ArrayRef get_writable(uint32_t docId) { return _store.get_writable(_indices[docId].load_relaxed()); }

    /*
     * Readers holding a generation guard can call make_read_view() to
     * get a read view to the multi value mapping. Array bound (read_size) must
     * be specified by reader, cf. committed docid limit in attribute vectors.
     */
    ReadView make_read_view(size_t read_size) const { return ReadView(_indices.make_read_view(read_size), &_store); }
    // Pass on hold list management to underlying store
    void assign_generation(generation_t current_gen) { _store.assign_generation(current_gen); }
    void reclaim_memory(generation_t oldest_used_gen) { _store.reclaim_memory(oldest_used_gen); }
    void prepareLoadFromMultiValue() { _store.setInitializing(true); }

    void doneLoadFromMultiValue() { _store.setInitializing(false); }

    vespalib::AddressSpace getAddressSpaceUsage() const override;
    vespalib::MemoryUsage getArrayStoreMemoryUsage() const override;
    vespalib::MemoryUsage update_stat(const CompactionStrategy& compaction_strategy);
    bool consider_compact(const CompactionStrategy &compactionStrategy) {
        if (_store.consider_compact()) {
            compact_worst(compactionStrategy);
            return true;
        }
        return false;
    }
    void compact_worst(const CompactionStrategy& compaction_strategy);
    bool has_free_lists_enabled() const { return _store.has_free_lists_enabled(); }
    // Set compaction spec. Only used by unit tests.
    void set_compaction_spec(vespalib::datastore::CompactionSpec compaction_spec) noexcept { _store.set_compaction_spec(compaction_spec); }
    // Get type mapper. Only used by unit tests.
    const ArrayStoreTypeMapper &get_mapper() const noexcept { return _store.get_mapper(); }


    static vespalib::datastore::ArrayStoreConfig optimizedConfigForHugePage(size_t max_type_id,
                                                                            size_t hugePageSize,
                                                                            size_t smallPageSize,
                                                                            size_t max_buffer_size,
                                                                            size_t min_num_entries_for_new_buffer,
                                                                            float allocGrowFactor,
                                                                            bool enable_free_lists);
};

}