ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/shstr.C
(Generate patch)

Comparing deliantra/server/common/shstr.C (file contents):
Revision 1.4 by root, Sun Sep 3 08:05:39 2006 UTC vs.
Revision 1.5 by root, Sun Sep 3 09:00:05 2006 UTC

6#include <cstdlib> 6#include <cstdlib>
7 7
8#include <tr1/unordered_set> 8#include <tr1/unordered_set>
9 9
10#include "shstr.h" 10#include "shstr.h"
11
12// NOTE: even with lots of stuff loaded, we do not usually have >>20000 strings.
13// maybe refcounting is just overhead?
11 14
12struct hash 15struct hash
13{ 16{
14 std::size_t operator ()(const char *s) const 17 std::size_t operator ()(const char *s) const
15 { 18 {
55 return s; 58 return s;
56 59
57 HT::iterator i = ht.find (s); 60 HT::iterator i = ht.find (s);
58 61
59 return i != ht.end () 62 return i != ht.end ()
60 ? (char *)*i 63 ? *i
61 : 0; 64 : 0;
62} 65}
63 66
64const char * 67const char *
65shstr::intern (const char *s) 68shstr::intern (const char *s)
66{ 69{
67 if (!s) 70 if (!s)
68 return s; 71 return s;
69 72
70 if (const char *found = find (s)) 73 if (const char *found = find (s))
74 {
75 ++refcnt (found);
71 return found; 76 return found;
77 }
72 78
73 int len = strlen (s); 79 int len = strlen (s);
74 80
75 int *v = (int *)malloc (sizeof (int) * 2 + len + 1); 81 const char *v = (const char *)(2 + (int *)malloc (sizeof (int) * 2 + len + 1));
76 82
77 v [0] = len; 83 length (v) = len;
78 v [1] = 0; 84 refcnt (v) = 1;
79 85
80 v += 2; 86 memcpy ((char *)v, s, len + 1);
81 87
82 memcpy (v, s, len + 1); 88 ht.insert (v);
83 89
84 ht.insert ((char *)v); 90 return v;
85
86 return (char *)v;
87} 91}
88 92
89// TODO: periodically test refcounts == 0 for a few strings (e.g. one hash bucket, 93// periodically test refcounts == 0 for a few strings
90// exploiting the fatc that iterators stay valid for unordered_set). 94// this is the ONLY thing that erases stuff from ht. keep it that way.
91void 95void
92shstr::gc () 96shstr::gc ()
93{ 97{
98 static const char *curpos;
99
100 HT::iterator i = curpos ? ht.find (curpos) : ht.begin ();
101
102 if (i == ht.end ())
103 i = ht.begin ();
104
105 // go through all strings roughly once every 4 minutes
106 for (int n = ht.size () / 256 + 16; --n; )
107 {
108 if (i == ht.end ())
109 {
110 curpos = 0;
111 return;
112 }
113
114 if (!refcnt (*i))
115 {
116 HT::iterator o = i++;
117 const char *s = *o;
118 ht.erase (o);
119
120 //printf ("GC %4d %3d %d >%s<%d\n", (int)ht.size (), n, shstr::refcnt (s), s, shstr::length (s));
121 free (-2 + (int *)s);
122 }
123 else
124 ++i;
125 }
126
127 curpos = *i;
94} 128}
95 129
130//TODO: this should of course not be here
96/* buf_overflow() - we don't want to exceed the buffer size of 131/* buf_overflow() - we don't want to exceed the buffer size of
97 * buf1 by adding on buf2! Returns true if overflow will occur. 132 * buf1 by adding on buf2! Returns true if overflow will occur.
98 */ 133 */
99 134
100int 135int

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines