]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/map.qc
Merge branch 'master' into Mario/bulldozer
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / map.qc
1 #ifndef MAP_H
2 #define MAP_H
3
4 // Databases (hash tables)
5 const float DB_BUCKETS = 8192;
6 void db_save(float db, string pFilename)
7 {
8         int fh = fopen(pFilename, FILE_WRITE);
9         if (fh < 0)
10         {
11                 LOG_INFO(strcat("^1Can't write DB to ", pFilename));
12                 return;
13         }
14         int n = buf_getsize(db);
15         fputs(fh, strcat(ftos(DB_BUCKETS), "\n"));
16         for (int i = 0; i < n; ++i)
17                 fputs(fh, strcat(bufstr_get(db, i), "\n"));
18         fclose(fh);
19 }
20
21 int db_create()
22 {
23         return buf_create();
24 }
25
26 void db_put(float db, string pKey, string pValue);
27
28 int db_load(string pFilename)
29 {
30         int db = buf_create();
31         if (db < 0) return -1;
32         int fh = fopen(pFilename, FILE_READ);
33         if (fh < 0) return db;
34         string l = fgets(fh);
35         if (stof(l) == DB_BUCKETS)
36         {
37                 for (int i = 0; (l = fgets(fh)); ++i)
38                 {
39                         if (l != "") bufstr_set(db, i, l);
40                 }
41         }
42         else
43         {
44                 // different count of buckets, or a dump?
45                 // need to reorganize the database then (SLOW)
46                 //
47                 // note: we also parse the first line (l) in case the DB file is
48                 // missing the bucket count
49                 do
50                 {
51                         int n = tokenizebyseparator(l, "\\");
52                         for (int j = 2; j < n; j += 2)
53                                 db_put(db, argv(j - 1), uri_unescape(argv(j)));
54                 }
55                 while ((l = fgets(fh)));
56         }
57         fclose(fh);
58         return db;
59 }
60
61 void db_dump(float db, string pFilename)
62 {
63         int fh = fopen(pFilename, FILE_WRITE);
64         if (fh < 0) error(strcat("Can't dump DB to ", pFilename));
65         int n = buf_getsize(db);
66         fputs(fh, "0\n");
67         for (int i = 0; i < n; ++i)
68         {
69                 int m = tokenizebyseparator(bufstr_get(db, i), "\\");
70                 for (int j = 2; j < m; j += 2)
71                         fputs(fh, strcat("\\", argv(j - 1), "\\", argv(j), "\n"));
72         }
73         fclose(fh);
74 }
75
76 void db_close(float db)
77 {
78         buf_del(db);
79 }
80
81 string db_get(float db, string pKey)
82 {
83         int h = crc16(false, pKey) % DB_BUCKETS;
84         return uri_unescape(infoget(bufstr_get(db, h), pKey));
85 }
86
87 void db_put(float db, string pKey, string pValue)
88 {
89         int h = crc16(false, pKey) % DB_BUCKETS;
90         bufstr_set(db, h, infoadd(bufstr_get(db, h), pKey, uri_escape(pValue)));
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