aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/vespa/vespalib/datastore/array_store_config.h
blob: 9a7884ef3bcd0950ef23abfff7fee13fe42204dc (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include <vespa/vespalib/util/size_literals.h>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <vector>

namespace vespalib::datastore {

/**
 * Config specifying layout and buffer allocation strategy for an array store.
 */
class ArrayStoreConfig
{
public:
    /**
     * Specification of buffer allocation strategy for arrays of a given size.
     */
    struct AllocSpec {
        // Minimum number of entries to allocate in a buffer.
        size_t min_entries_in_buffer;
        // Maximum number of entries to allocate in a buffer.
        size_t max_entries_in_buffer;
        // Number of entries needed before allocating a new buffer instead of just resizing the first one.
        size_t num_entries_for_new_buffer;
        // Grow factor used when allocating a new buffer.
        float allocGrowFactor;
        AllocSpec(size_t min_entries_in_buffer_,
                  size_t max_entries_in_buffer_,
                  size_t num_entries_for_new_buffer_,
                  float allocGrowFactor_) noexcept
            : min_entries_in_buffer(min_entries_in_buffer_),
              max_entries_in_buffer(max_entries_in_buffer_),
              num_entries_for_new_buffer(num_entries_for_new_buffer_),
              allocGrowFactor(allocGrowFactor_) {}
    };

    using AllocSpecVector = std::vector<AllocSpec>;

    static constexpr size_t default_max_buffer_size = 256_Mi;

private:
    AllocSpecVector _allocSpecs;
    bool _enable_free_lists;

    /**
     * Setup an array store where buffer type ids [1-(allocSpecs.size()-1)] are used to allocate small arrays in datastore buffers and
     * larger arrays are heap allocated. The allocation spec for a given buffer type is found in the given vector.
     * Allocation spec for large arrays is located at position 0.
     */
    ArrayStoreConfig(const AllocSpecVector &allocSpecs);

public:
    /**
     * Setup an array store where buffer type ids [1-max_type_id] are used to allocate small arrays in datastore buffers
     * with the given default allocation spec. Larger arrays are heap allocated.
     */
    ArrayStoreConfig(uint32_t max_type_id, const AllocSpec &defaultSpec);

    uint32_t max_type_id() const { return _allocSpecs.size() - 1; }
    const AllocSpec &spec_for_type_id(uint32_t type_id) const;
    ArrayStoreConfig& enable_free_lists(bool enable) & noexcept {
        _enable_free_lists = enable;
        return *this;
    }
    ArrayStoreConfig&& enable_free_lists(bool enable) && noexcept {
        _enable_free_lists = enable;
        return std::move(*this);
    }
    [[nodiscard]] bool enable_free_lists() const noexcept { return _enable_free_lists; }

    /**
     * Generate a config that is optimized for the given memory huge page size.
     */
    static ArrayStoreConfig optimizeForHugePage(uint32_t max_type_id,
                                                std::function<size_t(uint32_t)> type_id_to_entry_size,
                                                size_t hugePageSize,
                                                size_t smallPageSize,
                                                size_t maxEntryRefOffset,
                                                size_t max_buffer_size,
                                                size_t min_num_entries_for_new_buffer,
                                                float allocGrowFactor);
};

}