summaryrefslogtreecommitdiff
path: root/src/common/db.hpp
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2013-02-23 14:28:21 -0800
committerBen Longbons <b.r.longbons@gmail.com>2013-02-23 15:13:16 -0800
commit1e77f5dc8d95bbf912205c85274d294a80ea65c9 (patch)
tree054aa52764297b205431dfe82119a7f3e5e7ecd1 /src/common/db.hpp
parent25823b36905a84d92f9299ba7f9f0c713141c8fb (diff)
downloadtmwa-1e77f5dc8d95bbf912205c85274d294a80ea65c9.tar.gz
tmwa-1e77f5dc8d95bbf912205c85274d294a80ea65c9.tar.bz2
tmwa-1e77f5dc8d95bbf912205c85274d294a80ea65c9.tar.xz
tmwa-1e77f5dc8d95bbf912205c85274d294a80ea65c9.zip
Replace struct dbt with typesafe std::map wrappers
Also fix broken save/accreg.txt reading.
Diffstat (limited to 'src/common/db.hpp')
-rw-r--r--src/common/db.hpp174
1 files changed, 101 insertions, 73 deletions
diff --git a/src/common/db.hpp b/src/common/db.hpp
index 7d07b1d..d171429 100644
--- a/src/common/db.hpp
+++ b/src/common/db.hpp
@@ -1,91 +1,119 @@
-// WARNING: there is a system header by this name
#ifndef DB_HPP
#define DB_HPP
+// db.hpp - convenience wrappers over std::map<K, V>
+//
+// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
+//
+// This file is part of The Mana World (Athena server)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "sanity.hpp"
-# include <functional>
+# include <map>
-/// Number of tree roots
-// Somewhat arbitrary - larger wastes more space but is faster for large trees
-// num % HASH_SIZE minimize collisions even for similar num
-constexpr int HASH_SIZE = 256 + 27;
-
-typedef enum dbn_color
+template<class K, class V>
+class Map
{
- RED,
- BLACK,
-} dbn_color;
+ typedef std::map<K, V> Impl;
-typedef intptr_t numdb_key_t;
-typedef union db_key_t
-{
- char *ms __attribute__((deprecated));
- const char* s;
- numdb_key_t i;
+ Impl impl;
+public:
+ typedef typename Impl::iterator iterator;
+ typedef typename Impl::const_iterator const_iterator;
- db_key_t(numdb_key_t n) : i(n) {}
- db_key_t(const char * z) : s(z) {}
-} db_key_t;
-typedef void* db_val_t;
-typedef uint32_t hash_t;
-typedef std::function<void(db_key_t, db_val_t)> db_func_t;
+ iterator begin() { return impl.begin(); }
+ iterator end() { return impl.end(); }
+ const_iterator begin() const { return impl.begin(); }
+ const_iterator end() const { return impl.end(); }
-/// DataBase Node
-struct dbn
-{
- struct dbn *parent, *left, *right;
- dbn_color color;
- db_key_t key;
- db_val_t data;
-};
+ V *search(const K& k)
+ {
+ iterator it = impl.find(k);
+ if (it == impl.end())
+ return nullptr;
+ return &it->second;
+ }
+ const V *search(const K& k) const
+ {
+ const_iterator it = impl.find(k);
+ if (it == impl.end())
+ return nullptr;
+ return &it->second;
+ }
+ void insert(K k, V v)
+ {
+ // As far as I can tell, this is the simplest way to
+ // implement move-only insert-with-replacement.
+ iterator it = impl.lower_bound(k);
+ // invariant: if it is valid, it->first >= k
+ if (it != impl.end() && it->first == k)
+ it->second = std::move(v);
+ else
+ it = impl.insert(std::pair<K, V>(std::move(k), std::move(v))).first;
+ return (void)&it->second;
-typedef enum dbt_type
-{
- DB_NUMBER,
- DB_STRING,
-} dbt_type;
+ }
+ V *init(K k)
+ {
+ return &impl[k];
+ }
+ void erase(const K& k)
+ {
+ impl.erase(k);
+ }
+ void clear()
+ {
+ impl.clear();
+ }
+ bool empty()
+ {
+ return impl.empty();
+ }
+};
-/// DataBase Table
-struct dbt
+template<class K, class V>
+class DMap
{
- dbt_type type;
- /// Note, before replacement, key/values to be replaced
- // TODO refactor to decrease/eliminate the uses of this?
- void(*release)(db_key_t, db_val_t) __attribute__((deprecated));
- /// Maximum length of a string key - TODO refactor to ensure all strings are NUL-terminated
- size_t maxlen __attribute__((deprecated));
- /// The root trees
- struct dbn *ht[HASH_SIZE];
-};
+ typedef Map<K, V> Impl;
-# define strdb_search(t,k) db_search((t), (db_key_t)(k))
-# define strdb_insert(t,k,d) db_insert((t), (db_key_t)(k), (db_val_t)(d))
-# define strdb_erase(t,k) db_erase((t), (db_key_t)(k))
-# define strdb_foreach db_foreach
-# define strdb_final db_final
-# define numdb_search(t,k) db_search((t), (db_key_t)(k))
-# define numdb_insert(t,k,d) db_insert((t), (db_key_t)(k), (db_val_t)(d))
-# define numdb_erase(t,k) db_erase((t), (db_key_t)(k))
-# define numdb_foreach db_foreach
-# define numdb_final db_final
+ Impl impl;
+public:
+ typedef typename Impl::iterator iterator;
+ typedef typename Impl::const_iterator const_iterator;
-/// Create a map from char* to void*, with strings possibly not null-terminated
-struct dbt *strdb_init(size_t maxlen);
-/// Create a map from int to void*
-struct dbt *numdb_init(void);
-/// Return the value corresponding to the key, or NULL if not found
-db_val_t db_search(struct dbt *table, db_key_t key);
-/// Add or replace table[key] = data
-// if it was already there, call release
-struct dbn *db_insert(struct dbt *table, db_key_t key, db_val_t data);
-/// Remove a key from the table, returning the data
-db_val_t db_erase(struct dbt *table, db_key_t key);
+ iterator begin() { return impl.begin(); }
+ iterator end() { return impl.end(); }
+ const_iterator begin() const { return impl.begin(); }
+ const_iterator end() const { return impl.end(); }
-/// Execute a function for every element, in unspecified order
-void db_foreach(struct dbt *, db_func_t);
-// opposite of init? Calls release for every element and frees memory
-// This probably isn't really needed: we don't have to free memory while exiting
-void db_final(struct dbt *, db_func_t) __attribute__((deprecated));
+ V get(K k)
+ {
+ V *vp = impl.search(k);
+ return vp ? *vp : V();
+ }
+ void put(K k, V v)
+ {
+ if (v == V())
+ impl.erase(k);
+ else
+ impl.insert(k, v);
+ }
+ void clear()
+ {
+ impl.clear();
+ }
+};
#endif // DB_HPP