]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/map.qh
ea7f0e1fe26f62143774a14a217047780abb9e6c
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / map.qh
1 #pragma once
2
3 #include "int.qh"
4
5 // Databases (hash tables)
6 const int DB_BUCKETS = 8192;
7 ERASEABLE
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
24 ERASEABLE
25 int db_create()
26 {
27         return buf_create();
28 }
29 #define HM_NEW(this) (this = db_create())
30
31 ERASEABLE
32 void db_put(int db, string key, string value);
33
34 ERASEABLE
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
68 ERASEABLE
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");
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
83 ERASEABLE
84 void db_close(int db)
85 {
86         buf_del(db);
87 }
88 #define HM_DELETE(this) db_close(this)
89
90 ERASEABLE
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 */