ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/shstr.C
Revision: 1.20
Committed: Thu Sep 14 18:13:01 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_0
Changes since 1.19: +3 -3 lines
Log Message:
presuppose iso c++0x

File Contents

# Content
1 /*
2 * shstr.C
3 */
4
5 #include <cstring>
6 #include <cstdlib>
7
8 #include <glib.h>
9
10 #include <tr1/unordered_set>
11
12 #include "global.h"
13
14 typedef std::tr1::unordered_set <const char *, str_hash, str_equal, slice_allocator<const char *>, true> HT;
15
16 static HT ht;
17
18 static const char *
19 makevec (const char *s)
20 {
21 int len = strlen (s);
22
23 const char *v = (const char *) (2 + (int *)g_slice_alloc (sizeof (int) * 2 + len + 1));
24
25 shstr::length (v) = len;
26 shstr::refcnt (v) = 1;
27
28 memcpy ((char *) v, s, len + 1);
29
30 return v;
31 }
32
33 static const char *
34 makenull ()
35 {
36 const char *s = makevec ("(null)");
37 shstr::length (s) = 0;
38 return s;
39 }
40
41 const char *shstr::null = makenull ();
42
43 const char *
44 shstr::find (const char *s)
45 {
46 if (!s)
47 return s;
48
49 AUTODECL (i, ht.find (s));
50
51 return i != ht.end ()? *i : 0;
52 }
53
54 const char *
55 shstr::intern (const char *s)
56 {
57 if (!s)
58 return null;
59
60 if (const char *found = find (s))
61 {
62 ++refcnt (found);
63 return found;
64 }
65
66 s = makevec (s);
67 ht.insert (s);
68 return s;
69 }
70
71 // periodically test refcounts == 0 for a few strings
72 // this is the ONLY thing that erases stuff from ht. keep it that way.
73 void
74 shstr::gc ()
75 {
76 static const char *curpos;
77
78 AUTODECL (i, curpos ? ht.find (curpos) : ht.begin ());
79
80 if (i == ht.end ())
81 i = ht.begin ();
82
83 // go through all strings roughly once every 4 minutes
84 int n = ht.size () / 256 + 16;
85
86 for (;;)
87 {
88 if (i == ht.end ())
89 {
90 curpos = 0;
91 return;
92 }
93 else if (!--n)
94 break;
95 else if (!refcnt (*i))
96 {
97 AUTODECL (o, i++);
98 const char *s = *o;
99
100 ht.erase (o);
101
102 //printf ("GC %4d %3d %d >%s<%d\n", (int)ht.size (), n, shstr::refcnt (s), s, shstr::length (s));
103 g_slice_free1 (sizeof (int) * 2 + length (s) + 1, -2 + (int *) s);
104 }
105 else
106 ++i;
107 }
108
109 curpos = *i;
110 }
111
112 shstr skill_names[NUM_SKILLS];
113
114 // what weird misoptimisation is this again?
115 const shstr undead_name ("undead");
116
117 //TODO: this should of course not be here
118
119 /* buf_overflow() - we don't want to exceed the buffer size of
120 * buf1 by adding on buf2! Returns true if overflow will occur.
121 */
122
123 int
124 buf_overflow (const char *buf1, const char *buf2, int bufsize)
125 {
126 int len1 = 0, len2 = 0;
127
128 if (buf1)
129 len1 = strlen (buf1);
130 if (buf2)
131 len2 = strlen (buf2);
132 if ((len1 + len2) >= bufsize)
133 return 1;
134 return 0;
135 }