aboutsummaryrefslogtreecommitdiffstats
path: root/storage/src/vespa/storage/distributor/statecheckers.h
blob: e77e19e8c9d58e3005d7fd8b2d7a5315905fdbc0 (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
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include "idealstatemanager.h"

namespace storage::distributor {

class SynchronizeAndMoveStateChecker : public StateChecker
{
public:
    Result check(const Context &c) const override;
    const char* getName() const noexcept override { return "SynchronizeAndMove"; }
};

class DeleteExtraCopiesStateChecker : public StateChecker
{
public:
    Result check(const Context &c) const override;
    const char* getName() const noexcept override { return "DeleteExtraCopies"; }

private:
    static bool bucketHasNoData(const Context& c);
    static void removeRedundantEmptyOrConsistentCopies(const Context& c, std::vector<uint16_t>& removedCopies, vespalib::asciistream& reasons);
    static bool copyIsInIdealState(const BucketCopy& cp, const Context& c);
    static bool enoughCopiesKept(uint32_t keptIdealCopies, uint32_t keptNonIdealCopies, const Context& c);
    static uint32_t numberOfIdealCopiesPresent(const Context& c);
    static void addToRemoveSet(const BucketCopy& copyToRemove, const char* reasonForRemoval,
                               std::vector<uint16_t>& removedCopies, vespalib::asciistream& reasons);
                            
};

class JoinBucketsStateChecker : public StateChecker
{
public:
    Result check(const Context &c) const override;
    const char* getName() const noexcept override { return "JoinBuckets"; }
private:
    static uint64_t getTotalUsedFileSize(const Context& c);
    static uint64_t getTotalMetaCount(const Context& c);
    static bool isFirstSibling(const document::BucketId& bucketId);
    static bool siblingsAreInSync(const Context& c);
    static bool shouldJoin(const Context& c);
    static bool smallEnoughToJoin(const Context& c);
    static bool singleBucketJoinIsEnabled(const Context&);
    static bool singleBucketJoinIsConsistent(const Context& c);
    static document::Bucket computeJoinBucket(const Context& c);
};

class SplitBucketStateChecker : public StateChecker
{
public:
    Result check(const Context &c) const override;
    const char* getName() const noexcept override { return "SplitBucket"; }
private:
    static Result generateMinimumBucketSplitOperation(const Context& c);
    static Result generateMaxSizeExceededSplitOperation(const Context& c);

    static bool validForSplit(const Context& c);
    static double getBucketSizeRelativeToMax(const Context& c);
};

class SplitInconsistentStateChecker : public StateChecker
{
public:
    Result check(const Context &c) const override;
    const char* getName() const noexcept override { return "SplitInconsistentBuckets"; }

private:
    static bool isLeastSplitBucket(const document::BucketId& bucket,const std::vector<BucketDatabase::Entry>& entries);
    static uint32_t getHighestUsedBits(const std::vector<BucketDatabase::Entry>& entries);
    static vespalib::string getReason(const document::BucketId& bucketId, const std::vector<BucketDatabase::Entry>& entries);
};

class ActiveList;

class BucketStateStateChecker : public StateChecker
{
public:
    Result check(const Context &c) const override;
    const char* getName() const noexcept override { return "SetBucketState"; }
};

class GarbageCollectionStateChecker : public StateChecker
{
public:
    Result check(const Context &c) const override;
    const char* getName() const noexcept override { return "GarbageCollection"; }
private:
    static bool garbage_collection_disabled(const Context& c) noexcept;
    static bool needs_garbage_collection(const Context& c, vespalib::duration time_since_epoch);
};

}