1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef RY_STAT_DB_TREE_H
20 #define RY_STAT_DB_TREE_H
22 #include "nel/misc/smart_ptr.h"
23 #include "nel/misc/static_map.h"
24 #include "nel/misc/entity_id.h"
25 #include "nel/misc/log.h"
27 #include "stat_db_common.h"
28 #include "stat_db_tree_visitor.h"
32 typedef NLMISC::CSmartPtr
<IStatDBNode
> IStatDBNodePtr
;
36 * Node structure of the statistical database,
37 * this is the base for branches and leaves.
39 * A path is a string composed of keys separated with a '.'
40 * A key is an alphanumeric string: [0-9A-Za-z_]*
41 * Example of path: "branch1_name.branch2_name.leaf1"
43 * A path pattern can contain wildcard keys:
44 * Wildcard key '*' means any key
46 * \author Matthieu 'Trap' Besson
47 * \author Nevrax France
50 class IStatDBNode
: public NLMISC::CRefCount
61 virtual ~IStatDBNode() {}
63 /// add a node at the given path, it creates the path if necessary
64 /// NOTE: if another node is already at the given path it is replaced
65 virtual bool setNode(const std::string
& path
, IStatDBNodePtr node
) = 0;
67 /// get the node at the given path or NULL if the path does not exist
68 virtual IStatDBNodePtr
getNode(const std::string
& path
) = 0;
70 /// get all nodes whose path matches the given pattern
71 /// \param pathPattern : a path pattern
72 /// \param matchingNodes : return the matching nodes
73 /// \param currentPath : the current path
74 /// WARNING: the vector 'matchingNodes' will not be cleared by this method before matching nodes are added
75 virtual void getNodes(const std::string
& pathPattern
, std::vector
<CMatchingNode
> & matchingNodes
,
76 const std::string
& currentPath
) = 0;
78 /// remove and return the node at the given path
79 virtual IStatDBNodePtr
removeNode(const std::string
& path
) = 0;
81 /// accept a visitor (visitor design pattern)
82 /// \param currentPath : the path of this node
83 virtual void acceptVisitor(CStatDBNodeVisitor
& visitor
, const std::string
& currentPath
) = 0;
87 * Leaf structure of the statistical database.
89 * \author Matthieu 'Trap' Besson
90 * \author Nevrax France
93 class CStatDBLeaf
: public IStatDBNode
96 virtual ~CStatDBLeaf() {}
98 bool setNode(const std::string
& /* path */, IStatDBNodePtr
/* node */) { return false; }
99 IStatDBNodePtr
getNode(const std::string
& /* path */) { return NULL
; }
100 void getNodes(const std::string
& /* pathPattern */, std::vector
<CMatchingNode
> & /* matchingNodes */,
101 const std::string
& /* currentPath */) {}
102 IStatDBNodePtr
removeNode(const std::string
& /* path */) { return NULL
; }
104 virtual void acceptVisitor(CStatDBNodeVisitor
& /* visitor */, const std::string
& /* currentPath */) {}
108 * Simple value leaf structure of the statistical database
110 * \author Matthieu 'Trap' Besson
111 * \author Nevrax France
114 class CStatDBValueLeaf
: public CStatDBLeaf
118 CStatDBValueLeaf(sint32 val
= 0) : _Value(val
) {}
121 void setValue(sint32 val
) { _Value
= val
; }
123 sint32
getValue() { return _Value
; }
126 void addValue(sint32 val
) { _Value
+= val
; }
128 void acceptVisitor(CStatDBNodeVisitor
& visitor
, const std::string
& currentPath
)
130 visitor
.visitValueLeaf(this, currentPath
);
138 * Leaf structure of the statistical database retaining info for players and guilds.
139 * For the moment a table leaf removes entries with a value <= 0 (cf playerAdd() and guildAdd() methods).
140 * It is typically made to store some positive scores,
141 * but it may support both signed and unsigned scores in the future.
143 * \author Matthieu 'Trap' Besson
144 * \author Nevrax France
147 class CStatDBTableLeaf
: public CStatDBLeaf
150 typedef std::map
<NLMISC::CEntityId
,sint32
> TPlayerValues
;
151 typedef std::map
<EGSPD::TGuildId
,sint32
> TGuildValues
;
155 CStatDBTableLeaf() {}
156 CStatDBTableLeaf(const TPlayerValues
& playerValues
, const TGuildValues
& guildValues
)
157 : _PlayerValues(playerValues
), _GuildValues(guildValues
)
161 /// add a value to a player
162 /// NOTE: if the new value of the player is <= 0 the player entry is removed
163 void playerAdd(NLMISC::CEntityId playerId
, sint32 val
);
164 /// add a value to a guild
165 /// NOTE: if the new value of the guild is <= 0 the guild entry is removed
166 void guildAdd(EGSPD::TGuildId guildId
, sint32 val
);
168 /// set a player value
169 /// NOTE: if the new value of the player is <= 0 the player entry is removed
170 void playerSet(NLMISC::CEntityId playerId
, sint32 val
);
171 /// set a guild value
172 /// NOTE: if the new value of the guild is <= 0 the guild entry is removed
173 void guildSet(EGSPD::TGuildId guildId
, sint32 val
);
175 /// get a value of a player
176 bool playerGet(NLMISC::CEntityId playerId
, sint32
& val
) const;
177 /// get a value of a guild
178 bool guildGet(EGSPD::TGuildId guildId
, sint32
& val
) const;
180 /// get player values
181 const TPlayerValues
& getPlayerValues() const { return _PlayerValues
; }
183 const TGuildValues
& getGuildValues() const { return _GuildValues
; }
185 /// remove a player from the table
186 void removePlayer(NLMISC::CEntityId playerId
);
187 /// remove a guild from the table
188 void removeGuild(EGSPD::TGuildId guildId
);
190 void acceptVisitor(CStatDBNodeVisitor
& visitor
, const std::string
& currentPath
)
192 visitor
.visitTableLeaf(this, currentPath
);
196 TPlayerValues _PlayerValues
;
197 TGuildValues _GuildValues
;
201 * Branch structure of the statistical database.
202 * We use a static map for branches because we will not add branches all days its a
203 * 'created once read/write multiple' type of structure.
205 * \author Matthieu 'Trap' Besson
206 * \author Nevrax France
209 class CStatDBBranch
: public IStatDBNode
212 bool setNode(const std::string
& path
, IStatDBNodePtr node
);
213 IStatDBNodePtr
getNode(const std::string
& path
);
214 void getNodes(const std::string
& pathPattern
, std::vector
<CMatchingNode
> & matchingNodes
,
215 const std::string
& currentPath
);
216 IStatDBNodePtr
removeNode(const std::string
& path
);
218 void acceptVisitor(CStatDBNodeVisitor
& visitor
, const std::string
& currentPath
);
221 bool isValidToken(const std::string
& token
) const;
222 void splitPath(const std::string
& path
, std::string
& token
, std::string
& rest
) const;
225 typedef NLMISC::CStaticMap
<std::string
, IStatDBNodePtr
> TChildren
;
230 * This class removes entities (players and guilds) through a SDB node
232 * \author Sebastien 'kxu' Guignot
233 * \author Nevrax France
236 class CStatDBEntitiesRemoval
: private CStatDBNodeVisitor
239 /// queue a player to remove
240 void addPlayerToRemove(NLMISC::CEntityId playerId
);
241 /// queue a guild to remove
242 void addGuildToRemove(EGSPD::TGuildId guildId
);
244 /// process removal of players and guilds actually queued and flush them
245 void processRemoval(IStatDBNodePtr root
);
248 void visitTableLeaf(CStatDBTableLeaf
* tableLeaf
, const std::string
& path
);
251 std::vector
<NLMISC::CEntityId
> _PlayersToRemove
;
252 std::vector
<EGSPD::TGuildId
> _GuildsToRemove
;
256 #endif // RY_STAT_DB_TREE_H