aboutsummaryrefslogtreecommitdiffstats
path: root/vdslib/src/vespa/vdslib/state/state.h
blob: 8d3c2a1d0db74b6ca9ee1c4dc8a72d509f2330b8 (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
/**
 * @class vdslib::State
 *
 * Defines legal states for various uses. Split this into its own class such
 * that we can easily see what states are legal to use in what situations.
 * They double as node states nodes report they are in, and
 * wanted states set external sources.
 */
#pragma once

#include "nodetype.h"
#include <vespa/vespalib/util/printable.h>
#include <vespa/vespalib/stllike/string.h>
#include <vector>

namespace storage::lib {

class State : public vespalib::Printable {
    vespalib::string _name;
    vespalib::string _serialized;
    uint8_t _rankValue;
    std::vector<bool> _validReportedNodeState;
    std::vector<bool> _validWantedNodeState;
    bool _validClusterState;

    State(const State&);
    State(vespalib::stringref name, vespalib::stringref serialized,
          uint8_t rank,
          bool validDistributorReported, bool validStorageReported,
          bool validDistributorWanted, bool validStorageWanted,
          bool validCluster);
    ~State();

    State& operator=(const State&);

public:
    static const State UNKNOWN;
    static const State MAINTENANCE;
    static const State DOWN;
    static const State STOPPING;
    static const State INITIALIZING;
    static const State RETIRED;
    static const State UP;

    /** Throws vespalib::IllegalArgumentException if invalid state given. */
    static const State& get(vespalib::stringref serialized);
    const vespalib::string& serialize() const { return _serialized; }

    bool validReportedNodeState(const NodeType& node) const { return _validReportedNodeState[node]; }
    bool validWantedNodeState(const NodeType& node) const { return _validWantedNodeState[node]; }
    bool validClusterState() const { return _validClusterState; }

    bool maySetWantedStateForThisNodeState(const State& wantedState) const {
        return (wantedState._rankValue <= _rankValue);
    }

    /**
     * Get a string that represents a more human readable version of
     * the state than what can be provided through the single-character
     * serialized representation.
     *
     * Example: State::RETIRED.getName() -> "Retired"
     */
    const vespalib::string& getName() const noexcept {
        return _name;
    }

    void print(std::ostream& out, bool verbose, const std::string& indent) const override;
    bool operator==(const State& other) const { return (&other == this); }
    bool operator!=(const State& other) const { return (&other != this); }

    /**
     * Utility function to check whether this state is one of the given
     * states, given as the single character they are serialized as.
     * For instance, "um" will check if this state is up or maintenance.
     */
    bool oneOf(const char* states) const {
        for (const char* c = states; *c != '\0'; ++c) {
            if (*c == _serialized[0]) return true;
        }
        return false;
    }
};

}