ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/shstr.C
Revision: 1.21
Committed: Mon Apr 16 15:41:26 2007 UTC (17 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.20: +3 -3 lines
Log Message:
replace AUTODECL by auto. this is the first time in my life, I think, that I redefined a keyword - fortunately only with arguments

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.3 * shstr.C
3 elmex 1.1 */
4    
5 root 1.3 #include <cstring>
6     #include <cstdlib>
7    
8 root 1.10 #include <glib.h>
9    
10 root 1.3 #include <tr1/unordered_set>
11 elmex 1.1
12 root 1.16 #include "global.h"
13 elmex 1.1
14 root 1.18 typedef std::tr1::unordered_set <const char *, str_hash, str_equal, slice_allocator<const char *>, true> HT;
15 elmex 1.1
16 root 1.16 static HT ht;
17 elmex 1.1
18 root 1.13 static const char *
19     makevec (const char *s)
20 root 1.7 {
21 root 1.17 int len = strlen (s);
22 root 1.7
23 root 1.18 const char *v = (const char *) (2 + (int *)g_slice_alloc (sizeof (int) * 2 + len + 1));
24 root 1.7
25     shstr::length (v) = len;
26     shstr::refcnt (v) = 1;
27    
28 root 1.13 memcpy ((char *) v, s, len + 1);
29 root 1.7
30 root 1.8 return v;
31 root 1.7 }
32    
33 root 1.17 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 root 1.15
43 elmex 1.1 const char *
44 root 1.3 shstr::find (const char *s)
45     {
46 root 1.4 if (!s)
47     return s;
48    
49 root 1.21 auto (i, ht.find (s));
50 elmex 1.1
51 root 1.13 return i != ht.end ()? *i : 0;
52 elmex 1.1 }
53    
54     const char *
55 root 1.3 shstr::intern (const char *s)
56     {
57 root 1.4 if (!s)
58 root 1.7 return null;
59 elmex 1.1
60 root 1.4 if (const char *found = find (s))
61 root 1.5 {
62     ++refcnt (found);
63     return found;
64     }
65 elmex 1.1
66 root 1.7 s = makevec (s);
67     ht.insert (s);
68     return s;
69 elmex 1.1 }
70    
71 root 1.5 // periodically test refcounts == 0 for a few strings
72     // this is the ONLY thing that erases stuff from ht. keep it that way.
73 elmex 1.1 void
74 root 1.3 shstr::gc ()
75     {
76 root 1.5 static const char *curpos;
77    
78 root 1.21 auto (i, curpos ? ht.find (curpos) : ht.begin ());
79 root 1.5
80     if (i == ht.end ())
81     i = ht.begin ();
82    
83     // go through all strings roughly once every 4 minutes
84 root 1.11 int n = ht.size () / 256 + 16;
85 root 1.6
86     for (;;)
87 root 1.5 {
88     if (i == ht.end ())
89     {
90     curpos = 0;
91     return;
92     }
93 root 1.6 else if (!--n)
94     break;
95     else if (!refcnt (*i))
96 root 1.5 {
97 root 1.21 auto (o, i++);
98 root 1.5 const char *s = *o;
99 root 1.13
100 root 1.5 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 root 1.13 g_slice_free1 (sizeof (int) * 2 + length (s) + 1, -2 + (int *) s);
104 root 1.5 }
105     else
106     ++i;
107     }
108    
109     curpos = *i;
110 elmex 1.1 }
111    
112 root 1.16 shstr skill_names[NUM_SKILLS];
113    
114     // what weird misoptimisation is this again?
115     const shstr undead_name ("undead");
116    
117 root 1.5 //TODO: this should of course not be here
118 root 1.13
119 elmex 1.1 /* 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 root 1.13 int
124 elmex 1.1 buf_overflow (const char *buf1, const char *buf2, int bufsize)
125     {
126 root 1.13 int len1 = 0, len2 = 0;
127 elmex 1.1
128 root 1.13 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 elmex 1.1 }