aboutsummaryrefslogtreecommitdiffstats
path: root/searchcore/src/vespa/searchcore/proton/server/memoryflush.h
blob: 4af9967d6b113a4c9663a2657ca30650b936c0bd (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include <vespa/searchcore/proton/flushengine/iflushstrategy.h>
#include <vespa/vespalib/util/time.h>
#include <mutex>

namespace proton {

class MemoryFlush : public IFlushStrategy
{
public:
    struct Config
    {
        /// Global maxMemory
        uint64_t          maxGlobalMemory;
        /// Maximum global tls size.
        uint64_t          maxGlobalTlsSize;
        /// Maximum global disk bloat factor. When this limit is reached
        /// flush is forced.
        double            globalDiskBloatFactor;
        /// Maximum memory saved. When this limit is reached flush is forced.
        int64_t           maxMemoryGain;
        /// Maximum disk bloat factor. When this limit is reached
        /// flush is forced.
        double            diskBloatFactor;

        /// Maximum age of unflushed data.
        vespalib::duration maxTimeGain;
        Config();
        Config(uint64_t maxGlobalMemory_in,
               uint64_t maxGlobalTlsSize_in,
               double globalDiskBloatFactor_in,
               uint64_t maxMemoryGain_in,
               double diskBloatFactor_in,
               vespalib::duration maxTimeGain_in);
        bool operator == (const Config & rhs) const { return equal(rhs); }
        bool operator != (const Config & rhs) const { return ! equal(rhs); }
        bool equal(const Config & rhs) const {
            return (maxGlobalMemory == rhs.maxGlobalMemory) &&
                   (maxGlobalTlsSize == rhs.maxGlobalTlsSize) &&
                   (globalDiskBloatFactor == rhs.globalDiskBloatFactor) &&
                   (maxMemoryGain == rhs.maxMemoryGain) &&
                   (maxTimeGain == rhs.maxTimeGain) &&
                   (diskBloatFactor == rhs. diskBloatFactor);
        }
        vespalib::string toString() const;
    };

    enum OrderType { DEFAULT, MAXAGE, DISKBLOAT, TLSSIZE, MEMORY };

private:
    /// Needed as flushDone is called in different context from the rest
    mutable std::mutex _lock;
    Config             _config;
    /// The time when the strategy was started.
    vespalib::system_time  _startTime;

    class CompareTarget
    {
    public:
        CompareTarget(OrderType order, const flushengine::TlsStatsMap &tlsStatsMap)
            : _order(order),
              _tlsStatsMap(tlsStatsMap)
        { }

        bool operator ()(const FlushContext::SP &lfc, const FlushContext::SP &rfc) const;
    private:
        OrderType     _order;
        const flushengine::TlsStatsMap &_tlsStatsMap;
    };

public:
    using SP = std::shared_ptr<MemoryFlush>;

    MemoryFlush();
    explicit MemoryFlush(const Config &config) : MemoryFlush(config, vespalib::system_clock::now()) { }
    MemoryFlush(const Config &config, vespalib::system_time startTime);
    ~MemoryFlush();

    FlushContext::List
    getFlushTargets(const FlushContext::List &targetList,
                    const flushengine::TlsStatsMap &tlsStatsMap,
                    const flushengine::ActiveFlushStats& active_flushes) const override;

    void setConfig(const Config &config);
    Config getConfig() const;
};

} // namespace proton