Xonotic
map.qh
Go to the documentation of this file.
1 #pragma once
2 
3 #include "int.qh"
4 
5 // Databases (hash tables)
6 const int DB_BUCKETS = 8192;
8 void db_save(int db, string filename)
9 {
10  int fh = fopen(filename, FILE_WRITE);
11  if (fh < 0)
12  {
13  LOG_WARNF("^1Can't write DB to %s", filename);
14  return;
15  }
16  fputs(fh, strcat(ftos(DB_BUCKETS), "\n"));
17  for (int i = 0, n = buf_getsize(db); i < n; ++i)
18  fputs(fh, strcat(bufstr_get(db, i), "\n"));
19  fclose(fh);
20 }
21 
22 USING(HashMap, int);
23 
25 int db_create()
26 {
27  return buf_create();
28 }
29 #define HM_NEW(this) (this = db_create())
30 
32 void db_put(int db, string key, string value);
33 
35 int db_load(string filename)
36 {
37  int db = buf_create();
38  if (db < 0) return -1;
39  int fh = fopen(filename, FILE_READ);
40  if (fh < 0) return db;
41  string l = fgets(fh);
42  if (stoi(l) == DB_BUCKETS)
43  {
44  for (int i = 0; (l = fgets(fh)); ++i)
45  {
46  if (l != "") bufstr_set(db, i, l);
47  }
48  }
49  else
50  {
51  // different count of buckets, or a dump?
52  // need to reorganize the database then (SLOW)
53  //
54  // note: we also parse the first line (l) in case the DB file is
55  // missing the bucket count
56  do
57  {
58  int n = tokenizebyseparator(l, "\\");
59  for (int j = 2; j < n; j += 2)
60  db_put(db, argv(j - 1), uri_unescape(argv(j)));
61  }
62  while ((l = fgets(fh)));
63  }
64  fclose(fh);
65  return db;
66 }
67 
69 void db_dump(int db, string filename)
70 {
71  int fh = fopen(filename, FILE_WRITE);
72  if (fh < 0) LOG_FATALF("Can't dump DB to %s", filename);
73  fputs(fh, "0\n");
74  for (int i = 0, n = buf_getsize(db); i < n; ++i)
75  {
76  int m = tokenizebyseparator(bufstr_get(db, i), "\\");
77  for (int j = 2; j < m; j += 2)
78  fputs(fh, strcat("\\", argv(j - 1), "\\", argv(j), "\n"));
79  }
80  fclose(fh);
81 }
82 
84 void db_close(int db)
85 {
86  buf_del(db);
87 }
88 #define HM_DELETE(this) db_close(this)
89 
91 string db_get(int db, string key)
92 {
93  int h = crc16(false, key) % DB_BUCKETS;
94  return uri_unescape(infoget(bufstr_get(db, h), key));
95 }
96 #define HM_gets(this, k) db_get(this, k)
97 
98 #define db_remove(db, key) db_put(db, key, "")
99 
100 ERASEABLE
101 void db_put(int db, string key, string value)
102 {
103  int h = crc16(false, key) % DB_BUCKETS;
104  bufstr_set(db, h, infoadd(bufstr_get(db, h), key, uri_escape(value)));
105 }
106 #define HM_sets(this, key, val) db_put(this, key, val)
107 
108 /*
109 void db_test()
110 {
111  LOG_INFO("LOAD...\n");
112  int db = db_load("foo.db");
113  LOG_INFO("LOADED. FILL...\n");
114  for (int i = 0; i < DB_BUCKETS; ++i)
115  db_put(db, ftos(random()), "X");
116  LOG_INFO("FILLED. SAVE...\n");
117  db_save(db, "foo.db");
118  LOG_INFO("SAVED. CLOSE...\n");
119  db_close(db);
120  LOG_INFO("CLOSED.\n");
121 }
122 */
ERASEABLE int db_create()
Definition: map.qh:25
ERASEABLE void db_put(int db, string key, string value)
Definition: map.qh:101
ERASEABLE int db_load(string filename)
Definition: map.qh:35
ERASEABLE void db_close(int db)
Definition: map.qh:84
const float FILE_READ
Definition: csprogsdefs.qc:231
#define ERASEABLE
Definition: _all.inc:35
#define stoi(s)
Definition: int.qh:4
#define LOG_WARNF(...)
Definition: log.qh:67
#define buf_create
Definition: dpextensions.qh:63
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
ERASEABLE void db_save(int db, string filename)
Definition: map.qh:8
ERASEABLE void db_dump(int db, string filename)
Definition: map.qh:69
ERASEABLE string db_get(int db, string key)
Definition: map.qh:91
const int DB_BUCKETS
Definition: map.qh:6
const float FILE_WRITE
Definition: csprogsdefs.qc:233
#define LOG_FATALF(...)
Definition: log.qh:59
#define tokenizebyseparator
Definition: dpextensions.qh:21
#define USING(name, T)
Definition: _all.inc:72
int HashMap
Definition: map.qh:22