ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/shstr.C
Revision: 1.16
Committed: Tue Sep 12 00:53:56 2006 UTC (17 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.15: +9 -16 lines
Log Message:
introducing skillinc.h

File Contents

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