aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/vespa/vespalib/datastore/datastore.hpp
blob: b21a5954eee659a7f9f18aeceabc8236fda1c65f (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include "datastore.h"
#include "allocator.hpp"
#include "free_list_allocator.hpp"
#include "free_list_raw_allocator.hpp"
#include "raw_allocator.hpp"
#include <vespa/vespalib/util/generation_hold_list.hpp>

namespace vespalib::datastore {

template <typename RefT>
DataStoreT<RefT>::DataStoreT()
    : DataStoreBase(RefType::numBuffers(), RefType::offset_bits, RefType::offsetSize())
{
}

template <typename RefT>
DataStoreT<RefT>::~DataStoreT() = default;

template <typename RefT>
void
DataStoreT<RefT>::free_entry_internal(EntryRef ref, size_t num_entries)
{
    RefType intRef(ref);
    BufferState &state = getBufferState(intRef.bufferId());
    state.free_entries(ref, num_entries, intRef.offset());
}

template <typename RefT>
void
DataStoreT<RefT>::hold_entries(EntryRef ref, size_t num_entries, size_t extraBytes)
{
    RefType intRef(ref);
    BufferState &state = getBufferState(intRef.bufferId());
    if (!state.hold_entries(num_entries, extraBytes)) {
        _entry_ref_hold_list.insert({ref, num_entries});
    }
}

template <typename RefT>
void
DataStoreT<RefT>::reclaim_entry_refs(generation_t oldest_used_gen)
{
    _entry_ref_hold_list.reclaim(oldest_used_gen, [this](const auto& elem) {
        free_entry_internal(elem.ref, elem.num_entries);
    });
}

template <typename RefT>
void
DataStoreT<RefT>::reclaim_all_entry_refs()
{
    _entry_ref_hold_list.reclaim_all([this](const auto& elem) {
        free_entry_internal(elem.ref, elem.num_entries);
    });
}

template <typename RefT>
template <typename EntryT>
Allocator<EntryT, RefT>
DataStoreT<RefT>::allocator(uint32_t typeId)
{
    return Allocator<EntryT, RefT>(*this, typeId);
}

template <typename RefT>
template <typename EntryT, typename ReclaimerT>
FreeListAllocator<EntryT, RefT, ReclaimerT>
DataStoreT<RefT>::freeListAllocator(uint32_t typeId)
{
    return FreeListAllocator<EntryT, RefT, ReclaimerT>(*this, typeId);
}

template <typename RefT>
template <typename EntryT>
RawAllocator<EntryT, RefT>
DataStoreT<RefT>::rawAllocator(uint32_t typeId)
{
    return RawAllocator<EntryT, RefT>(*this, typeId);
}

template <typename RefT>
template <typename EntryT>
FreeListRawAllocator<EntryT, RefT>
DataStoreT<RefT>::freeListRawAllocator(uint32_t typeId)
{
    return FreeListRawAllocator<EntryT, RefT>(*this, typeId);
}

template <typename EntryType, typename RefT>
DataStore<EntryType, RefT>::DataStore()
    : DataStore(std::make_unique<BufferType<EntryType>>(1, RefType::offsetSize(), RefType::offsetSize()))
{
}

template <typename EntryType, typename RefT>
DataStore<EntryType, RefT>::DataStore(uint32_t min_arrays)
    : DataStore(std::make_unique<BufferType<EntryType>>(1, min_arrays, RefType::offsetSize()))
{
}

template <typename EntryType, typename RefT>
DataStore<EntryType, RefT>::DataStore(BufferTypeUP type)
    : ParentType(),
      _type(std::move(type))
{
    addType(_type.get());
    init_primary_buffers();
}

template <typename EntryType, typename RefT>
DataStore<EntryType, RefT>::~DataStore()
{
    dropBuffers();  // Drop buffers before type handlers are dropped
}

template <typename EntryType, typename RefT>
EntryRef
DataStore<EntryType, RefT>::addEntry(const EntryType &e)
{
    using NoOpReclaimer = DefaultReclaimer<EntryType>;
    // Note: This will fallback to regular allocation if free lists are not enabled.
    return FreeListAllocator<EntryType, RefT, NoOpReclaimer>(*this, 0).alloc(e).ref;
}

extern template class DataStoreT<EntryRefT<22> >;

}