summaryrefslogtreecommitdiffstats
path: root/documentapi/src/vespa/documentapi/messagebus/systemstate/nodestate.h
blob: eff684f5bfed4f7f076905dc23d0a7dce30b8b1b (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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include <vespa/documentapi/common.h>
#include <map>

namespace documentapi {

/**
 * A node state is a single node in an annotatet tree of such nodes. It contains a reference to its parent
 * node, a list of named child nodes, as well as a mapping of (key, value) pairs that constitute the annotated
 * state of this node. To create an instance of a node state tree, one can either use the {@link SystemState}
 * factory class, or one can programmatically construct each node and use the chaining capabilities of its
 * set-methods to compact the necessary code.
 */
class NodeState {
public:
    typedef std::unique_ptr<NodeState> UP;
    typedef std::shared_ptr<NodeState> SP;
    typedef std::map<string, string> StateMap;
    typedef std::map<string, NodeState::SP> ChildMap;

private:
    NodeState*  _parent;
    string _id;
    ChildMap    _children;
    StateMap    _state;

    /**
     * Compacts the system state tree from this node upwards. This will delete itself if it has a parent, but
     * no internal state and no children.
     *
     * @return This or the first non-null ancestor, to allow chaining.
     */
    NodeState &compact();

    /**
     * Returns a string representation of this node state.
     *
     * @param prefix The prefix to use for this string.
     * @return A string representation of this.
     */
    const string toString(const string &prefix) const;

public:
    NodeState(NodeState && rhs) = default;
    NodeState & operator = (NodeState && rhs) = default;
    NodeState & operator = (const NodeState & rhs) = default;
    /**
     * Creates a node state that no internal content.
     */
    NodeState();

    /**
     * Creates a node state as a copy of another.
     *
     * @param rhs The state to copy.
     */
    NodeState(const NodeState &rhs);

    /**
     * Creates a node state based on a list of argument objects. These arguments are iterated and added to
     * this node's internal state map.
     *
     * @param args The arguments to use as state.
     */
    NodeState(StateMap args);

    ~NodeState();

    /**
     * Adds a child to this node at the given location. The key can be a location string, in which case the
     * necessary intermediate node states are created.
     *
     * @param key   The location at which to add the child.
     * @param child The child node to add.
     * @return This, to allow chaining.
     */
    NodeState &addChild(const string &key, const NodeState &child);

    /**
     * Returns the child at the given location relative to this. This method can be forced to return a child
     * node even if it does not exist, by adding all intermediate nodes and the target node itself.
     *
     * @param key   The location of the child to return.
     * @param force Whether or not to force a return value by creating missing nodes.
     * @return The child object, null if not found.
     */
    NodeState *getChild(const string &key, bool force = false);

    /**
     * Returns the map of child nodes for iteration.
     *
     * @return The internal child map.
     */
    const ChildMap &getChildren() const;

    /**
     * Removes the named child node from this node, and attempts to compact the system state from this node
     * upwards by removing empty nodes.
     *
     * @param key The child to remove.
     * @return The result of invoking {@link #compact} after the remove.
     */
    NodeState &removeChild(const string &key);

    /**
     * Retrieves some arbitrary state information for a given key. The key can be a location string, in which
     * case the necessary intermediate nodes are traversed. If the key is not found, this method returns
     * null. This method can not be const because it uses the non-const method {@link #getChild} to resolve a
     * pathed key.
     *
     * @param key The name of the state information to return.
     * @return The value of the state key.
     */
    const string getState(const string &key);

    /**
     * Sets some arbitrary state data in this node. The key can be a location string, in which case the
     * necessary intermediate nodes are traversed and even created if missing.
     *
     * @param key   The key to set.
     * @param value The value to assign to the key.
     * @return This, to allow chaining.
     */
    NodeState &setState(const string &key, const string &value);

    /**
     * Removes the named (key, value) state pair from this node, and attempts to compact the system state from
     * this node upwards by removing empty nodes.
     *
     * @param key The state variable to clear.
     * @return The result of invoking {@link #compact} after the remove.
     */
    NodeState &removeState(const string &key);

    /**
     * Copies the state content of another node state object into this.
     *
     * @param node The node state to copy into this.
     * @return This, to allow chaining.
     */
    NodeState &copy(const NodeState &node);

    /**
     * Clears both the internal state and child list, then compacts the tree from this node upwards.
     *
     * @return The result of invoking {@link #compact} after the remove.
     */
    NodeState &clear();

    /**
     * Sets the parent of this node.
     *
     * @param parent The parent node.
     * @param id     The identifier of this node as seen in the parent.
     * @return This, to allow chaining.
     */
    NodeState &setParent(NodeState &parent, const string &id);

    /**
     * Returns a string representation of this node state.
     *
     * @return A string representation of this.
     */
    const string toString() const;
};

}