]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/map.qc
General cleanup/optimize
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / map.qc
1 #ifndef MAP_H
2 #define MAP_H
3
4 // Databases (hash tables)
5 const int DB_BUCKETS = 8192;
6 void db_save(int db, string filename)
7 {
8         int fh = fopen(filename, FILE_WRITE);
9         if (fh < 0)
10         {
11                 LOG_WARNINGF("^1Can't write DB to %s\n", filename);
12                 return;
13         }
14         fputs(fh, strcat(ftos(DB_BUCKETS), "\n"));
15         for (int i = 0, n = buf_getsize(db); i < n; ++i)
16                 fputs(fh, strcat(bufstr_get(db, i), "\n"));
17         fclose(fh);
18 }
19
20 int db_create()
21 {
22         return buf_create();
23 }
24
25 void db_put(int db, string key, string value);
26
27 int db_load(string filename)
28 {
29         int db = buf_create();
30         if (db < 0) return -1;
31         int fh = fopen(filename, FILE_READ);
32         if (fh < 0) return db;
33         string l = fgets(fh);
34         if (stoi(l) == DB_BUCKETS)
35         {
36                 for (int i = 0; (l = fgets(fh)); ++i)
37                 {
38                         if (l != "") bufstr_set(db, i, l);
39                 }
40         }
41         else
42         {
43                 // different count of buckets, or a dump?
44                 // need to reorganize the database then (SLOW)
45                 //
46                 // note: we also parse the first line (l) in case the DB file is
47                 // missing the bucket count
48                 do
49                 {
50                         int n = tokenizebyseparator(l, "\\");
51                         for (int j = 2; j < n; j += 2)
52                                 db_put(db, argv(j - 1), uri_unescape(argv(j)));
53                 }
54                 while ((l = fgets(fh)));
55         }
56         fclose(fh);
57         return db;
58 }
59
60 void db_dump(int db, string filename)
61 {
62         int fh = fopen(filename, FILE_WRITE);
63         if (fh < 0) LOG_FATALF("Can't dump DB to %s\n");
64         fputs(fh, "0\n");
65         for (int i = 0, n = buf_getsize(db); i < n; ++i)
66         {
67                 int m = tokenizebyseparator(bufstr_get(db, i), "\\");
68                 for (int j = 2; j < m; j += 2)
69                         fputs(fh, strcat("\\", argv(j - 1), "\\", argv(j), "\n"));
70         }
71         fclose(fh);
72 }
73
74 void db_close(int db)
75 {
76         buf_del(db);
77 }
78
79 string db_get(int db, string key)
80 {
81         int h = crc16(false, key) % DB_BUCKETS;
82         return uri_unescape(infoget(bufstr_get(db, h), key));
83 }
84
85 #define db_remove(db, key) db_put(db, key, "")
86
87 void db_put(int db, string key, string value)
88 {
89         int h = crc16(false, key) % DB_BUCKETS;
90         bufstr_set(db, h, infoadd(bufstr_get(db, h), key, uri_escape(value)));
91 }
92
93 void db_test()
94 {
95         LOG_INFO("LOAD...\n");
96         int db = db_load("foo.db");
97         LOG_INFO("LOADED. FILL...\n");
98         for (int i = 0; i < DB_BUCKETS; ++i)
99                 db_put(db, ftos(random()), "X");
100         LOG_INFO("FILLED. SAVE...\n");
101         db_save(db, "foo.db");
102         LOG_INFO("SAVED. CLOSE...\n");
103         db_close(db);
104         LOG_INFO("CLOSED.\n");
105 }
106
107 #endif