summaryrefslogtreecommitdiffstats
path: root/runtime/docs/html/map_8c-source.html
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/docs/html/map_8c-source.html')
-rw-r--r--runtime/docs/html/map_8c-source.html1711
1 files changed, 855 insertions, 856 deletions
diff --git a/runtime/docs/html/map_8c-source.html b/runtime/docs/html/map_8c-source.html
index 22e39231..9d91bd68 100644
--- a/runtime/docs/html/map_8c-source.html
+++ b/runtime/docs/html/map_8c-source.html
@@ -10,861 +10,860 @@
00003 <span class="comment"> * @brief Implements maps (associative arrays) and lists</span>
00004 <span class="comment"> */</span>
00005
-00006
-00007 <span class="keyword">static</span> <span class="keywordtype">int</span> map_sizes[] = {
-00008 <span class="keyword">sizeof</span>(<span class="keyword">struct </span>map_node_int64),
-00009 sizeof(struct map_node_stat),
-00010 sizeof(struct map_node_str),
-00011 0
-00012 };
-00013
-00014 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> string_hash(<span class="keyword">const</span> <span class="keywordtype">char</span> *key1, <span class="keyword">const</span> <span class="keywordtype">char</span> *key2)
-00015 {
-00016 <span class="keywordtype">int</span> hash = 0, count = 0;
-00017 <span class="keywordtype">char</span> *v1 = (<span class="keywordtype">char</span> *)key1;
-00018 <span class="keywordtype">char</span> *v2 = (<span class="keywordtype">char</span> *)key2;
-00019 <span class="keywordflow">while</span> (*v1 &amp;&amp; count++ &lt; 5) {
-00020 hash += *v1++;
-00021 }
-00022 <span class="keywordflow">while</span> (v2 &amp;&amp; *v2 &amp;&amp; count++ &lt; 5) {
-00023 hash += *v2++;
-00024 }
-00025 <span class="keywordflow">return</span> hash_long((<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)hash, HASH_TABLE_BITS);
-00026 }
-00027
-00028 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> mixed_hash(<span class="keyword">const</span> <span class="keywordtype">char</span> *key1, <span class="keywordtype">long</span> key2)
-00029 {
-00030 <span class="keywordtype">int</span> hash = 0, count = 0;
-00031 <span class="keywordtype">char</span> *v = (<span class="keywordtype">char</span> *)key1;
-00032 <span class="keywordflow">while</span> (v &amp;&amp; *v &amp;&amp; count++ &lt; 5)
-00033 hash += *v++;
-00034 return hash_long((<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)(hash ^ key2), HASH_TABLE_BITS);
-00035 }
-00036 <span class="comment"></span>
-00037 <span class="comment">/** Create a new map.</span>
-00038 <span class="comment"> * Maps must be created at module initialization time.</span>
-00039 <span class="comment"> * @param max_entries The maximum number of entries allowed. Currently that number will</span>
-00040 <span class="comment"> * be preallocated. If more entries are required, the oldest ones will be deleted. This makes</span>
-00041 <span class="comment"> * it effectively a circular buffer. If max_entries is 0, there will be no maximum and entries</span>
-00042 <span class="comment"> * will be allocated dynamically.</span>
-00043 <span class="comment"> * @param type Type of values stored in this map. </span>
-00044 <span class="comment"> * @return A MAP on success or NULL on failure.</span>
-00045 <span class="comment"> */</span>
-00046
-<a name="l00047"></a><a class="code" href="map_8c.html#a3">00047</a> <a class="code" href="structmap__root.html">MAP</a> _stp_map_new(<span class="keywordtype">unsigned</span> max_entries, enum valtype type)
-00048 {
-00049 size_t size;
-00050 <a class="code" href="structmap__root.html">MAP</a> m = (<a class="code" href="structmap__root.html">MAP</a>) _stp_valloc(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> <a class="code" href="structmap__root.html">map_root</a>));
-00051 <span class="keywordflow">if</span> (m == NULL)
-00052 <span class="keywordflow">return</span> NULL;
-00053
-00054 INIT_LIST_HEAD(&amp;m-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
-00055
-00056 m-&gt;<a class="code" href="structmap__root.html#o1">maxnum</a> = max_entries;
-00057 m-&gt;<a class="code" href="structmap__root.html#o0">type</a> = type;
-00058 <span class="keywordflow">if</span> (type &gt;= END) {
-00059 dbug (<span class="stringliteral">"map_new: unknown type %d\n"</span>, type);
-00060 <span class="keywordflow">return</span> NULL;
-00061 }
-00062
-00063 <span class="keywordflow">if</span> (max_entries) {
-00064 <span class="keywordtype">void</span> *tmp;
-00065 <span class="keywordtype">int</span> i;
-00066 <span class="keyword">struct </span>list_head *e;
-00067
-00068 INIT_LIST_HEAD(&amp;m-&gt;<a class="code" href="structmap__root.html#o5">pool</a>);
-00069 size = map_sizes[type];
-00070 tmp = _stp_valloc(max_entries * size);
-00071
-00072 <span class="keywordflow">for</span> (i = max_entries - 1; i &gt;= 0; i--) {
-00073 e = i * size + tmp;
-00074 dbug (<span class="stringliteral">"e=%lx\n"</span>, (<span class="keywordtype">long</span>)e);
-00075 list_add(e, &amp;m-&gt;<a class="code" href="structmap__root.html#o5">pool</a>);
-00076 }
-00077 m-&gt;<a class="code" href="structmap__root.html#o14">membuf</a> = tmp;
-00078 }
-00079 <span class="keywordflow">return</span> m;
-00080 }
-00081
-00082 <span class="keyword">static</span> <span class="keywordtype">void</span> map_free_strings(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *n)
-00083 {
-00084 <span class="keyword">struct </span>map_node_str *m = (<span class="keyword">struct </span>map_node_str *)n;
-00085 dbug (<span class="stringliteral">"n = %lx\n"</span>, (<span class="keywordtype">long</span>)n);
-00086 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o0">type</a> == STRING) {
-00087 dbug (<span class="stringliteral">"val STRING %lx\n"</span>, (<span class="keywordtype">long</span>)m-&gt;str);
-00088 <span class="keywordflow">if</span> (m-&gt;str)
-00089 _stp_free(m-&gt;str);
-00090 }
-00091 if (m-&gt;n.key1type == STR) {
-00092 dbug (<span class="stringliteral">"key1 STR %lx\n"</span>, (<span class="keywordtype">long</span>)key1str(m));
-00093 <span class="keywordflow">if</span> (key1str(m))
-00094 _stp_free(key1str(m));
-00095 }
-00096 if (m-&gt;n.key2type == STR) {
-00097 dbug (<span class="stringliteral">"key2 STR %lx\n"</span>, (<span class="keywordtype">long</span>)key2str(m));
-00098 <span class="keywordflow">if</span> (key2str(m))
-00099 _stp_free(key2str(m));
-00100 }
-00101 }
-00102 <span class="comment"></span>
-00103 <span class="comment">/** Deletes the current element.</span>
-00104 <span class="comment"> * If no current element (key) for this map is set, this function does nothing.</span>
-00105 <span class="comment"> * @param map </span>
-00106 <span class="comment"> */</span>
-00107
-<a name="l00108"></a><a class="code" href="map_8c.html#a5">00108</a> <span class="keywordtype">void</span> _stp_map_key_del(<a class="code" href="structmap__root.html">MAP</a> map)
-00109 {
-00110 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *m;
-00111
-00112 dbug (<span class="stringliteral">"create=%d key=%lx\n"</span>, map-&gt;create, (<span class="keywordtype">long</span>)map-&gt;key);
-00113 <span class="keywordflow">if</span> (map == NULL)
-00114 <span class="keywordflow">return</span>;
-00115
-00116 <span class="keywordflow">if</span> (map-&gt;create) {
-00117 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 0;
-00118 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = NULL;
-00119 <span class="keywordflow">return</span>;
-00120 }
-00121
-00122 <span class="keywordflow">if</span> (map-&gt;key == NULL)
-00123 <span class="keywordflow">return</span>;
-00124
-00125 m = (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)map-&gt;key;
-00126
-00127 <span class="comment">/* remove node from old hash list */</span>
-00128 hlist_del_init(&amp;m-&gt;<a class="code" href="structmap__node.html#o1">hnode</a>);
-00129
-00130 <span class="comment">/* remove from entry list */</span>
-00131 list_del(&amp;m-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>);
-00132
-00133 <span class="comment">/* remove any allocated string storage */</span>
-00134 map_free_strings(map, (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)map-&gt;key);
-00135
-00136 <span class="keywordflow">if</span> (map-&gt;maxnum)
-00137 list_add(&amp;m-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>, &amp;map-&gt;pool);
-00138 <span class="keywordflow">else</span>
-00139 _stp_free(m);
-00140
-00141 map-&gt;key = NULL;
-00142 map-&gt;num--;
-00143 }
-00144 <span class="comment"></span>
-00145 <span class="comment">/** Get the first element in a map.</span>
-00146 <span class="comment"> * @param map </span>
-00147 <span class="comment"> * @returns a pointer to the first element.</span>
-00148 <span class="comment"> * This is typically used with _stp_map_iter(). See the foreach() macro</span>
-00149 <span class="comment"> * for typical usage. It probably does what you want anyway.</span>
-00150 <span class="comment"> * @sa foreach</span>
-00151 <span class="comment"> */</span>
-00152
-<a name="l00153"></a><a class="code" href="map_8c.html#a6">00153</a> <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *<a class="code" href="map_8c.html#a6">_stp_map_start</a>(<a class="code" href="structmap__root.html">MAP</a> map)
-00154 {
-00155 <span class="keywordflow">if</span> (map == NULL)
-00156 <span class="keywordflow">return</span> NULL;
-00157
-00158 dbug (<span class="stringliteral">"%lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next);
-00159
-00160 <span class="keywordflow">if</span> (list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>))
-00161 <span class="keywordflow">return</span> NULL;
-00162
-00163 <span class="keywordflow">return</span> (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
-00164 }
-00165 <span class="comment"></span>
-00166 <span class="comment">/** Get the next element in a map.</span>
-00167 <span class="comment"> * @param map </span>
-00168 <span class="comment"> * @param m a pointer to the current element, returned from _stp_map_start()</span>
-00169 <span class="comment"> * or _stp_map_iter().</span>
-00170 <span class="comment"> * @returns a pointer to the next element.</span>
-00171 <span class="comment"> * This is typically used with _stp_map_start(). See the foreach() macro</span>
-00172 <span class="comment"> * for typical usage. It probably does what you want anyway.</span>
-00173 <span class="comment"> * @sa foreach</span>
-00174 <span class="comment"> */</span>
-00175
-<a name="l00176"></a><a class="code" href="map_8c.html#a7">00176</a> <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *<a class="code" href="map_8c.html#a7">_stp_map_iter</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *m)
-00177 {
-00178 <span class="keywordflow">if</span> (map == NULL)
-00179 <span class="keywordflow">return</span> NULL;
-00180
-00181 dbug (<span class="stringliteral">"%lx next=%lx prev=%lx map-&gt;head.next=%lx\n"</span>, (<span class="keywordtype">long</span>)m,
-00182 (<span class="keywordtype">long</span>)m-&gt;lnode.next, (<span class="keywordtype">long</span>)m-&gt;lnode.prev, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next);
-00183
-00184 <span class="keywordflow">if</span> (m-&gt;lnode.next == &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>)
-00185 <span class="keywordflow">return</span> NULL;
-00186
-00187 <span class="keywordflow">return</span> (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)m-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>.next;
-00188 }
-00189 <span class="comment"></span>
-00190 <span class="comment">/** Deletes a map.</span>
-00191 <span class="comment"> * Deletes a map, freeing all memory in all elements. Normally done only when the module exits.</span>
-00192 <span class="comment"> * @param map</span>
-00193 <span class="comment"> */</span>
-00194
-<a name="l00195"></a><a class="code" href="map_8c.html#a8">00195</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a8">_stp_map_del</a>(<a class="code" href="structmap__root.html">MAP</a> map)
-00196 {
-00197 <span class="keywordflow">if</span> (map == NULL)
-00198 <span class="keywordflow">return</span>;
-00199
-00200 <span class="keywordflow">if</span> (!list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>)) {
-00201 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *ptr = (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
-00202 <span class="keywordflow">while</span> (ptr &amp;&amp; ptr != (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)&amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>) {
-00203 map_free_strings(map, ptr);
-00204 ptr = (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)ptr-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>.next;
-00205 }
-00206 }
-00207 _stp_vfree(map-&gt;<a class="code" href="structmap__root.html#o14">membuf</a>);
-00208 _stp_vfree(map);
-00209 }
-00210
-00211 <span class="comment">/********************** KEY FUNCTIONS *********************/</span>
-00212
-00213 <span class="comment"></span>
-00214 <span class="comment">/** Set the map's key to two longs.</span>
-00215 <span class="comment"> * This sets the current element based on a key of two strings. If the keys are</span>
-00216 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
-00217 <span class="comment"> * call.</span>
-00218 <span class="comment"> * @param map</span>
-00219 <span class="comment"> * @param key1 first key</span>
-00220 <span class="comment"> * @param key2 second key</span>
-00221 <span class="comment"> */</span>
-00222
-<a name="l00223"></a><a class="code" href="map_8c.html#a9">00223</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a9">_stp_map_key_long_long</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">long</span> key1, <span class="keywordtype">long</span> key2)
-00224 {
-00225 <span class="keywordtype">unsigned</span> hv;
-00226 <span class="keyword">struct </span>hlist_head *head;
-00227 <span class="keyword">struct </span>hlist_node *e;
-00228
-00229 <span class="keywordflow">if</span> (map == NULL)
-00230 <span class="keywordflow">return</span>;
-00231
-00232 hv = hash_long(key1 ^ key2, HASH_TABLE_BITS);
-00233 head = &amp;map-&gt;<a class="code" href="structmap__root.html#o13">hashes</a>[hv];
-00234
-00235 dbug (<span class="stringliteral">"hash for %ld,%ld is %d\n"</span>, key1, key2, hv);
-00236
-00237 hlist_for_each(e, head) {
-00238 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *n =
-00239 (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)((long)e - <span class="keyword">sizeof</span>(<span class="keyword">struct </span>hlist_node));
-00240 dbug (<span class="stringliteral">"n =%lx key=%ld,%ld\n"</span>, (<span class="keywordtype">long</span>)n, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o0">val</a>, n-&gt;key2.<a class="code" href="unionkey__data.html#o0">val</a>);
-00241 <span class="keywordflow">if</span> (key1 == n-&gt;key1.val &amp;&amp; key2 == n-&gt;key2.val) {
-00242 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = n;
-00243 dbug (<span class="stringliteral">"saving key %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
-00244 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 0;
-00245 <span class="keywordflow">return</span>;
-00246 }
-00247 }
-00248
-00249 map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o0">val</a> = key1;
-00250 map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o0">val</a> = key2;
-00251 map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a> = LONG;
-00252 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = LONG;
-00253 map-&gt;<a class="code" href="structmap__root.html#o10">c_keyhead</a> = head;
-00254 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 1;
-00255 }
-00256 <span class="comment"></span>
-00257 <span class="comment">/** Set the map's key to two strings.</span>
-00258 <span class="comment"> * This sets the current element based on a key of two strings. If the keys are</span>
-00259 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
-00260 <span class="comment"> * call.</span>
-00261 <span class="comment"> * @param map</span>
-00262 <span class="comment"> * @param key1 first key</span>
-00263 <span class="comment"> * @param key2 second key</span>
-00264 <span class="comment"> */</span>
-00265
-<a name="l00266"></a><a class="code" href="map_8c.html#a10">00266</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a10">_stp_map_key_str_str</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">char</span> *key1, <span class="keywordtype">char</span> *key2)
-00267 {
-00268 <span class="keywordtype">unsigned</span> hv;
-00269 <span class="keyword">struct </span>hlist_head *head;
-00270 <span class="keyword">struct </span>hlist_node *e;
-00271
-00272 <span class="keywordflow">if</span> (map == NULL)
-00273 <span class="keywordflow">return</span>;
-00274
-00275 <span class="keywordflow">if</span> (key1 == NULL) {
-00276 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = NULL;
-00277 <span class="keywordflow">return</span>;
-00278 }
-00279
-00280 hv = string_hash(key1, key2);
-00281 head = &amp;map-&gt;<a class="code" href="structmap__root.html#o13">hashes</a>[hv];
-00282
-00283 dbug (<span class="stringliteral">"hash for %s,%s is %d\n"</span>, key1, key2, hv);
-00284
-00285 hlist_for_each(e, head) {
-00286 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *n =
-00287 (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)((long)e - <span class="keyword">sizeof</span>(<span class="keyword">struct </span>hlist_node));
-00288 dbug (<span class="stringliteral">"e =%lx key=%s,%s\n"</span>, (<span class="keywordtype">long</span>)e, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>,n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>);
-00289 <span class="keywordflow">if</span> (strcmp(key1, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>) == 0
-00290 &amp;&amp; (key2 == NULL || strcmp(key2, n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>) == 0)) {
-00291 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = n;
-00292 dbug (<span class="stringliteral">"saving key %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
-00293 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 0;
-00294 <span class="keywordflow">return</span>;
-00295 }
-00296 }
-00297
-00298 map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o1">str</a> = key1;
-00299 map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o1">str</a> = key2;
-00300 map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a> = STR;
-00301 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = STR;
-00302 map-&gt;<a class="code" href="structmap__root.html#o10">c_keyhead</a> = head;
-00303 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 1;
-00304 }
-00305 <span class="comment"></span>
-00306 <span class="comment">/** Set the map's key to a string and a long.</span>
-00307 <span class="comment"> * This sets the current element based on a key of a string and a long. If the keys are</span>
-00308 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
-00309 <span class="comment"> * call.</span>
-00310 <span class="comment"> * @param map</span>
-00311 <span class="comment"> * @param key1 first key</span>
-00312 <span class="comment"> * @param key2 second key</span>
-00313 <span class="comment"> */</span>
-00314
-<a name="l00315"></a><a class="code" href="map_8c.html#a11">00315</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a11">_stp_map_key_str_long</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">char</span> *key1, <span class="keywordtype">long</span> key2)
-00316 {
-00317 <span class="keywordtype">unsigned</span> hv;
-00318 <span class="keyword">struct </span>hlist_head *head;
-00319 <span class="keyword">struct </span>hlist_node *e;
-00320
-00321 <span class="keywordflow">if</span> (map == NULL)
-00322 <span class="keywordflow">return</span>;
-00323
-00324 <span class="keywordflow">if</span> (key1 == NULL) {
-00325 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = NULL;
-00326 <span class="keywordflow">return</span>;
-00327 }
-00328
-00329 hv = mixed_hash(key1, key2);
-00330 head = &amp;map-&gt;<a class="code" href="structmap__root.html#o13">hashes</a>[hv];
-00331
-00332 dbug (<span class="stringliteral">"hash for %s,%ld is %d\n"</span>, key1, key2, hv);
-00333
-00334 hlist_for_each(e, head) {
-00335 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *n =
-00336 (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)((long)e - <span class="keyword">sizeof</span>(<span class="keyword">struct </span>hlist_node));
-00337 dbug (<span class="stringliteral">"e =%lx key=%s,%ld\n"</span>, (<span class="keywordtype">long</span>)e, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>,(<span class="keywordtype">long</span>)n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o0">val</a>);
-00338 <span class="keywordflow">if</span> (strcmp(key1, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>) == 0 &amp;&amp; key2 == n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o0">val</a>) {
-00339 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = n;
-00340 dbug (<span class="stringliteral">"saving key %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
-00341 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 0;
-00342 <span class="keywordflow">return</span>;
-00343 }
-00344 }
-00345
-00346 map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o1">str</a> = key1;
-00347 map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o0">val</a> = key2;
-00348 map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a> = STR;
-00349 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = LONG;
-00350 map-&gt;<a class="code" href="structmap__root.html#o10">c_keyhead</a> = head;
-00351 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 1;
-00352 }
-00353 <span class="comment"></span>
-00354 <span class="comment">/** Set the map's key to a long and a string.</span>
-00355 <span class="comment"> * This sets the current element based on a key of a long and a string. If the keys are</span>
-00356 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
-00357 <span class="comment"> * call.</span>
-00358 <span class="comment"> * @param map</span>
-00359 <span class="comment"> * @param key1 first key</span>
-00360 <span class="comment"> * @param key2 second key</span>
-00361 <span class="comment"> */</span>
-00362
-<a name="l00363"></a><a class="code" href="map_8c.html#a12">00363</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a12">_stp_map_key_long_str</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">long</span> key1, <span class="keywordtype">char</span> *key2)
-00364 {
-00365 <span class="keywordtype">unsigned</span> hv;
-00366 <span class="keyword">struct </span>hlist_head *head;
-00367 <span class="keyword">struct </span>hlist_node *e;
-00368
-00369 <span class="keywordflow">if</span> (map == NULL)
-00370 <span class="keywordflow">return</span>;
-00371
-00372 hv = mixed_hash(key2, key1);
-00373 head = &amp;map-&gt;<a class="code" href="structmap__root.html#o13">hashes</a>[hv];
-00374 dbug (<span class="stringliteral">"hash for %ld,%s is %d\n"</span>, key1, key2, hv);
-00375
-00376 hlist_for_each(e, head) {
-00377 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *n =
-00378 (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)((long)e - <span class="keyword">sizeof</span>(<span class="keyword">struct </span>hlist_node));
-00379 dbug (<span class="stringliteral">"e =%lx key=%ld,%s\n"</span>, (<span class="keywordtype">long</span>)e, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o0">val</a>,n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>);
-00380 <span class="keywordflow">if</span> (key1 == n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o0">val</a> &amp;&amp; strcmp(key2, n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>) == 0) {
-00381 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = n;
-00382 dbug (<span class="stringliteral">"saving key %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
-00383 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 0;
-00384 <span class="keywordflow">return</span>;
-00385 }
-00386 }
-00387
-00388 map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o0">val</a> = key1;
-00389 map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o1">str</a> = key2;
-00390 map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a> = LONG;
-00391 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = STR;
-00392 map-&gt;<a class="code" href="structmap__root.html#o10">c_keyhead</a> = head;
-00393 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 1;
-00394 }
-00395 <span class="comment"></span>
-00396 <span class="comment">/** Set the map's key to a string.</span>
-00397 <span class="comment"> * This sets the current element based on a string key. If the key is</span>
-00398 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
-00399 <span class="comment"> * call.</span>
-00400 <span class="comment"> * @param map</span>
-00401 <span class="comment"> * @param key</span>
-00402 <span class="comment"> */</span>
-00403
-<a name="l00404"></a><a class="code" href="map_8c.html#a13">00404</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a13">_stp_map_key_str</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">char</span> *key)
-00405 {
-00406 <span class="keywordflow">if</span> (map == NULL)
-00407 <span class="keywordflow">return</span>;
-00408 <a class="code" href="map_8c.html#a10">_stp_map_key_str_str</a>(map, key, NULL);
-00409 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = NONE;
-00410 }
-00411 <span class="comment"></span>
-00412 <span class="comment">/** Set the map's key to a long.</span>
-00413 <span class="comment"> * This sets the current element based on a long key. If the key is</span>
-00414 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
-00415 <span class="comment"> * call.</span>
-00416 <span class="comment"> * @param map</span>
-00417 <span class="comment"> * @param key </span>
-00418 <span class="comment"> */</span>
-00419
-<a name="l00420"></a><a class="code" href="map_8c.html#a14">00420</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a14">_stp_map_key_long</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">long</span> key)
-00421 {
-00422 <span class="keywordflow">if</span> (map == NULL)
-00423 <span class="keywordflow">return</span>;
-00424 <a class="code" href="map_8c.html#a9">_stp_map_key_long_long</a>(map, key, 0);
-00425 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = NONE;
-00426 }
-00427
-00428 <span class="comment">/********************** SET/GET VALUES *********************/</span>
-00429
-00430 <span class="keyword">static</span> <span class="keywordtype">void</span> map_copy_keys(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *m)
-00431 {
-00432 m-&gt;key1type = map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a>;
-00433 m-&gt;key2type = map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a>;
-00434 <span class="keywordflow">switch</span> (map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a>) {
-00435 <span class="keywordflow">case</span> STR:
-00436 m-&gt;key1.str = _stp_alloc(strlen(map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>) + 1);
-00437 strcpy(m-&gt;key1.str, map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>);
-00438 <span class="keywordflow">break</span>;
-00439 <span class="keywordflow">case</span> LONG:
-00440 m-&gt;key1.val = map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o0">val</a>;
-00441 <span class="keywordflow">break</span>;
-00442 <span class="keywordflow">case</span> NONE:
-00443 <span class="comment">/* ERROR */</span>
-00444 <span class="keywordflow">break</span>;
-00445 }
-00446 <span class="keywordflow">switch</span> (map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a>) {
-00447 <span class="keywordflow">case</span> STR:
-00448 m-&gt;key2.<a class="code" href="unionkey__data.html#o1">str</a> = _stp_alloc(strlen(map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>) + 1);
-00449 strcpy(m-&gt;key2.str, map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>);
-00450 <span class="keywordflow">break</span>;
-00451 <span class="keywordflow">case</span> LONG:
-00452 m-&gt;key2.<a class="code" href="unionkey__data.html#o0">val</a> = map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o0">val</a>;
-00453 <span class="keywordflow">break</span>;
-00454 <span class="keywordflow">case</span> NONE:
-00455 <span class="keywordflow">break</span>;
-00456 }
-00457
-00458 <span class="comment">/* add node to new hash list */</span>
-00459 hlist_add_head(&amp;m-&gt;hnode, map-&gt;<a class="code" href="structmap__root.html#o10">c_keyhead</a>);
-00460
-00461 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = m;
-00462 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 0;
-00463 map-&gt;<a class="code" href="structmap__root.html#o2">num</a>++;
-00464 }
-00465
-00466 <span class="keyword">static</span> <span class="keywordtype">void</span> __stp_map_set_int64(<a class="code" href="structmap__root.html">MAP</a> map, int64_t val, <span class="keywordtype">int</span> add)
-00467 {
-00468 <span class="keyword">struct </span>map_node_int64 *m;
-00469
-00470 <span class="keywordflow">if</span> (map == NULL)
-00471 return;
-00472
-00473 if (map-&gt;create) {
-00474 <span class="keywordflow">if</span> (val == 0)
-00475 return;
-00476
-00477 if (map-&gt;maxnum) {
-00478 <span class="keywordflow">if</span> (list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>)) {
-00479 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o3">no_wrap</a>) {
-00480 <span class="comment">/* ERROR. FIXME */</span>
-00481 <span class="keywordflow">return</span>;
-00482 }
-00483 m = (<span class="keyword">struct </span>map_node_int64 *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
-00484 hlist_del_init(&amp;m-&gt;n.hnode);
-00485 map_free_strings(map, (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)m);
-00486 dbug (<span class="stringliteral">"got %lx off head\n"</span>, (<span class="keywordtype">long</span>)m);
-00487 } <span class="keywordflow">else</span> {
-00488 m = (<span class="keyword">struct </span>map_node_int64 *)map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>.next;
-00489 dbug (<span class="stringliteral">"got %lx off pool\n"</span>, (<span class="keywordtype">long</span>)m);
-00490 }
-00491 list_move_tail(&amp;m-&gt;n.lnode, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
-00492 } <span class="keywordflow">else</span> {
-00493 m = (<span class="keyword">struct </span>map_node_int64 *)
-00494 _stp_calloc(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> map_node_int64));
-00495 <span class="comment">/* add node to list */</span>
-00496 list_add_tail(&amp;m-&gt;n.lnode, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
-00497 }
-00498
-00499 <span class="comment">/* copy the key(s) */</span>
-00500 map_copy_keys(map, &amp;m-&gt;n);
-00501
-00502 <span class="comment">/* set the value */</span>
-00503 m-&gt;val = val;
-00504 } <span class="keywordflow">else</span> {
-00505 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
-00506 return;
-00507
-00508 if (val) {
-00509 m = (<span class="keyword">struct </span>map_node_int64 *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
-00510 <span class="keywordflow">if</span> (add)
-00511 m-&gt;val += val;
-00512 else
-00513 m-&gt;val = val;
-00514 } else if (!add) {
-00515 <span class="comment">/* setting value to 0 is the same as deleting */</span>
-00516 <a class="code" href="map_8c.html#a5">_stp_map_key_del</a>(map);
-00517 }
-00518 }
-00519 }
-00520 <span class="comment"></span>
-00521 <span class="comment">/** Set the current element's value to an int64.</span>
-00522 <span class="comment"> * This sets the current element's value to an int64. The map must have been created</span>
-00523 <span class="comment"> * to hold int64s using _stp_map_new()</span>
-00524 <span class="comment"> *</span>
-00525 <span class="comment"> * If the element doesn't exist, it is created. If no current element (key)</span>
-00526 <span class="comment"> * is set for the map, this function does nothing.</span>
-00527 <span class="comment"> * @param map</span>
-00528 <span class="comment"> * @param val new value</span>
-00529 <span class="comment"> * @sa _stp_map_add_int64</span>
-00530 <span class="comment"> */</span>
-<a name="l00531"></a><a class="code" href="map_8c.html#a17">00531</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a17">_stp_map_set_int64</a>(<a class="code" href="structmap__root.html">MAP</a> map, int64_t val)
-00532 {
-00533 __stp_map_set_int64 (map, val, 0);
-00534 }
-00535
-00536 <span class="comment"></span>
-00537 <span class="comment">/** Adds an int64 to the current element's value.</span>
-00538 <span class="comment"> * This adds an int64 to the current element's value. The map must have been created</span>
-00539 <span class="comment"> * to hold int64s using _stp_map_new()</span>
-00540 <span class="comment"> *</span>
-00541 <span class="comment"> * If the element doesn't exist, it is created. If no current element (key)</span>
-00542 <span class="comment"> * is set for the map, this function does nothing.</span>
-00543 <span class="comment"> * @param map</span>
-00544 <span class="comment"> * @param val value</span>
-00545 <span class="comment"> * @sa _stp_map_set_int64</span>
-00546 <span class="comment"> */</span>
-00547
-<a name="l00548"></a><a class="code" href="map_8c.html#a18">00548</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a18">_stp_map_add_int64</a>(<a class="code" href="structmap__root.html">MAP</a> map, int64_t val)
-00549 {
-00550 __stp_map_set_int64 (map, val, 1);
-00551 }
-00552 <span class="comment"></span>
-00553 <span class="comment">/** Gets the current element's value.</span>
-00554 <span class="comment"> * @param map</span>
-00555 <span class="comment"> * @returns The value. If the current element is not set or doesn't exist, returns 0.</span>
-00556 <span class="comment"> */</span>
-00557
-<a name="l00558"></a><a class="code" href="map_8c.html#a19">00558</a> int64_t <a class="code" href="map_8c.html#a19">_stp_map_get_int64</a>(<a class="code" href="structmap__root.html">MAP</a> map)
-00559 {
-00560 <span class="keyword">struct </span>map_node_int64 *m;
-00561 <span class="keywordflow">if</span> (map == NULL || map-&gt;<a class="code" href="structmap__root.html#o7">create</a> || map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
-00562 <span class="keywordflow">return</span> 0;
-00563 dbug (<span class="stringliteral">"%lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
-00564 m = (<span class="keyword">struct </span>map_node_int64 *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
-00565 <span class="keywordflow">return</span> m-&gt;val;
-00566 }
-00567 <span class="comment"></span>
-00568 <span class="comment">/** Set the current element's value to a string.</span>
-00569 <span class="comment"> * This sets the current element's value to an string. The map must have been created</span>
-00570 <span class="comment"> * to hold int64s using &lt;i&gt;_stp_map_new(xxx, STRING)&lt;/i&gt;</span>
-00571 <span class="comment"> *</span>
-00572 <span class="comment"> * If the element doesn't exist, it is created. If no current element (key)</span>
-00573 <span class="comment"> * is set for the map, this function does nothing.</span>
-00574 <span class="comment"> * @param map</span>
-00575 <span class="comment"> * @param val new string</span>
-00576 <span class="comment"> */</span>
-00577
-<a name="l00578"></a><a class="code" href="map_8c.html#a20">00578</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a20">_stp_map_set_str</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">char</span> *val)
-00579 {
-00580 <span class="keyword">struct </span>map_node_str *m;
-00581
-00582 <span class="keywordflow">if</span> (map == NULL)
-00583 <span class="keywordflow">return</span>;
-00584
-00585 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o7">create</a>) {
-00586 <span class="keywordflow">if</span> (val == NULL)
-00587 <span class="keywordflow">return</span>;
-00588
-00589 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o1">maxnum</a>) {
-00590 <span class="keywordflow">if</span> (list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>)) {
-00591 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o3">no_wrap</a>) {
-00592 <span class="comment">/* ERROR. FIXME */</span>
-00593 <span class="keywordflow">return</span>;
-00594 }
-00595 m = (<span class="keyword">struct </span>map_node_str *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
-00596 hlist_del_init(&amp;m-&gt;n.hnode);
-00597 map_free_strings(map, (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)m);
-00598 dbug (<span class="stringliteral">"got %lx off head\n"</span>, (<span class="keywordtype">long</span>)m);
-00599 } <span class="keywordflow">else</span> {
-00600 m = (<span class="keyword">struct </span>map_node_str *)map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>.next;
-00601 dbug (<span class="stringliteral">"got %lx off pool\n"</span>, (<span class="keywordtype">long</span>)m);
-00602 }
-00603 list_move_tail(&amp;m-&gt;n.lnode, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
-00604 } <span class="keywordflow">else</span> {
-00605 m = (<span class="keyword">struct </span>map_node_str *)
-00606 _stp_calloc(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> map_node_str));
-00607 <span class="comment">/* add node to list */</span>
-00608 list_add_tail(&amp;m-&gt;n.lnode, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
-00609 }
-00610
-00611 <span class="comment">/* copy the key(s) */</span>
-00612 map_copy_keys(map, &amp;m-&gt;n);
-00613
-00614 <span class="comment">/* set the value */</span>
-00615 m-&gt;str = _stp_alloc(strlen(val) + 1);
-00616 strcpy(m-&gt;str, val);
-00617 } <span class="keywordflow">else</span> {
-00618 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
-00619 <span class="keywordflow">return</span>;
-00620
-00621 <span class="keywordflow">if</span> (val) {
-00622 m = (<span class="keyword">struct </span>map_node_str *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
-00623 <span class="keywordflow">if</span> (m-&gt;str)
-00624 _stp_free(m-&gt;str);
-00625 m-&gt;str = _stp_alloc(strlen(val) + 1);
-00626 strcpy(m-&gt;str, val);
-00627 } <span class="keywordflow">else</span> {
-00628 <span class="comment">/* setting value to 0 is the same as deleting */</span>
-00629 <a class="code" href="map_8c.html#a5">_stp_map_key_del</a>(map);
-00630 }
-00631 }
-00632 }
-00633 <span class="comment"></span>
-00634 <span class="comment">/** Gets the current element's value.</span>
-00635 <span class="comment"> * @param map</span>
-00636 <span class="comment"> * @returns A string pointer. If the current element is not set or doesn't exist, returns NULL.</span>
-00637 <span class="comment"> */</span>
-00638
-<a name="l00639"></a><a class="code" href="map_8c.html#a21">00639</a> <span class="keywordtype">char</span> *<a class="code" href="map_8c.html#a21">_stp_map_get_str</a>(<a class="code" href="structmap__root.html">MAP</a> map)
-00640 {
-00641 <span class="keyword">struct </span>map_node_str *m;
-00642 <span class="keywordflow">if</span> (map == NULL || map-&gt;<a class="code" href="structmap__root.html#o7">create</a> || map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
-00643 <span class="keywordflow">return</span> NULL;
-00644 dbug (<span class="stringliteral">"%lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
-00645 m = (<span class="keyword">struct </span>map_node_str *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
-00646 <span class="keywordflow">return</span> m-&gt;str;
-00647 }
-00648 <span class="comment"></span>
-00649 <span class="comment">/** Set the current element's value to a stat.</span>
-00650 <span class="comment"> * This sets the current element's value to an stat struct. The map must have been created</span>
-00651 <span class="comment"> * to hold stats using &lt;i&gt;_stp_map_new(xxx, STAT)&lt;/i&gt;. This function would only be used</span>
-00652 <span class="comment"> * if we wanted to set stats to something other than the normal initial values (count = 0,</span>
-00653 <span class="comment"> * sum = 0, etc). It may be deleted if it doesn't turn out to be useful.</span>
-00654 <span class="comment"> * @sa _stp_map_stat_add </span>
-00655 <span class="comment"> *</span>
-00656 <span class="comment"> * If the element doesn't exist, it is created. If no current element (key)</span>
-00657 <span class="comment"> * is set for the map, this function does nothing.</span>
-00658 <span class="comment"> * @param map</span>
-00659 <span class="comment"> * @param stats pointer to stats struct.</span>
-00660 <span class="comment"> * @todo Histograms don't work yet.</span>
-00661 <span class="comment"> */</span>
-00662
-<a name="l00663"></a><a class="code" href="map_8c.html#a22">00663</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a22">_stp_map_set_stat</a>(<a class="code" href="structmap__root.html">MAP</a> map, <a class="code" href="structstat.html">stat</a> * stats)
-00664 {
-00665 <span class="keyword">struct </span>map_node_stat *m;
-00666
-00667 <span class="keywordflow">if</span> (map == NULL)
-00668 <span class="keywordflow">return</span>;
-00669 dbug (<span class="stringliteral">"set_stat %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
-00670
-00671 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o7">create</a>) {
-00672 <span class="keywordflow">if</span> (stats == NULL)
-00673 <span class="keywordflow">return</span>;
-00674
-00675 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o1">maxnum</a>) {
-00676 <span class="keywordflow">if</span> (list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>)) {
-00677 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o3">no_wrap</a>) {
-00678 <span class="comment">/* ERROR. FIXME */</span>
-00679 <span class="keywordflow">return</span>;
-00680 }
-00681 m = (<span class="keyword">struct </span>map_node_stat *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
-00682 hlist_del_init(&amp;m-&gt;n.hnode);
-00683 map_free_strings(map, (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)m);
-00684 dbug (<span class="stringliteral">"got %lx off head\n"</span>, (<span class="keywordtype">long</span>)m);
-00685 } <span class="keywordflow">else</span> {
-00686 m = (<span class="keyword">struct </span>map_node_stat *)map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>.next;
-00687 dbug (<span class="stringliteral">"got %lx off pool\n"</span>, (<span class="keywordtype">long</span>)m);
-00688 }
-00689 list_move_tail(&amp;m-&gt;n.lnode, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
-00690 } <span class="keywordflow">else</span> {
-00691 m = (<span class="keyword">struct </span>map_node_stat *)
-00692 _stp_calloc(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> map_node_stat));
-00693 <span class="comment">/* add node to list */</span>
-00694 list_add_tail(&amp;m-&gt;n.lnode, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
-00695 }
-00696
-00697 <span class="comment">/* copy the key(s) */</span>
-00698 map_copy_keys(map, &amp;m-&gt;n);
-00699
-00700 <span class="comment">/* set the value */</span>
-00701 memcpy(&amp;m-&gt;stats, stats, <span class="keyword">sizeof</span>(<a class="code" href="structstat.html">stat</a>));
-00702 } <span class="keywordflow">else</span> {
-00703 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
-00704 <span class="keywordflow">return</span>;
-00705
-00706 <span class="keywordflow">if</span> (stats) {
-00707 m = (<span class="keyword">struct </span>map_node_stat *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
-00708 memcpy(&amp;m-&gt;stats, stats, <span class="keyword">sizeof</span>(<a class="code" href="structstat.html">stat</a>));
-00709 } <span class="keywordflow">else</span> {
-00710 <span class="comment">/* setting value to NULL is the same as deleting */</span>
-00711 <a class="code" href="map_8c.html#a5">_stp_map_key_del</a>(map);
-00712 }
-00713 }
-00714 }
-00715 <span class="comment"></span>
-00716 <span class="comment">/** Gets the current element's value.</span>
-00717 <span class="comment"> * @param map</span>
-00718 <span class="comment"> * @returns A pointer to the stats struct. If the current element is not set </span>
-00719 <span class="comment"> * or doesn't exist, returns NULL.</span>
-00720 <span class="comment"> */</span>
-00721
-<a name="l00722"></a><a class="code" href="map_8c.html#a23">00722</a> <a class="code" href="structstat.html">stat</a> *<a class="code" href="map_8c.html#a23">_stp_map_get_stat</a>(<a class="code" href="structmap__root.html">MAP</a> map)
-00723 {
-00724 <span class="keyword">struct </span>map_node_stat *m;
-00725 <span class="keywordflow">if</span> (map == NULL || map-&gt;<a class="code" href="structmap__root.html#o7">create</a> || map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
-00726 <span class="keywordflow">return</span> NULL;
-00727 dbug (<span class="stringliteral">"%lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
-00728 m = (<span class="keyword">struct </span>map_node_stat *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
-00729 <span class="keywordflow">return</span> &amp;m-&gt;stats;
-00730 }
-00731 <span class="comment"></span>
-00732 <span class="comment">/** Add to the current element's statistics.</span>
-00733 <span class="comment"> * Increments the statistics counter by one and the sum by &lt;i&gt;val&lt;/i&gt;.</span>
-00734 <span class="comment"> * Adjusts minimum, maximum, and histogram.</span>
-00735 <span class="comment"> *</span>
-00736 <span class="comment"> * If the element doesn't exist, it is created. If no current element (key)</span>
-00737 <span class="comment"> * is set for the map, this function does nothing.</span>
-00738 <span class="comment"> * @param map</span>
-00739 <span class="comment"> * @param val value to add to the statistics</span>
-00740 <span class="comment"> * @todo Histograms don't work yet.</span>
-00741 <span class="comment"> */</span>
-00742
-<a name="l00743"></a><a class="code" href="map_8c.html#a24">00743</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a24">_stp_map_stat_add</a>(<a class="code" href="structmap__root.html">MAP</a> map, int64_t val)
-00744 {
-00745 <span class="keyword">struct </span>map_node_stat *m;
-00746 <span class="keywordflow">if</span> (map == NULL)
-00747 <span class="keywordflow">return</span>;
-00748
-00749 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o7">create</a>) {
-00750 <a class="code" href="structstat.html">stat</a> st = { 1, val, val, val };
-00751 <span class="comment">/* histogram */</span>
-00752 <a class="code" href="map_8c.html#a22">_stp_map_set_stat</a>(map, &amp;st);
-00753 <span class="keywordflow">return</span>;
-00754 }
-00755
-00756 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
-00757 <span class="keywordflow">return</span>;
-00758
-00759 dbug (<span class="stringliteral">"add_stat %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
-00760 m = (<span class="keyword">struct </span>map_node_stat *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
-00761 m-&gt;stats.count++;
-00762 m-&gt;stats.sum += val;
-00763 <span class="keywordflow">if</span> (val &gt; m-&gt;stats.max)
-00764 m-&gt;stats.max = val;
-00765 <span class="keywordflow">if</span> (val &lt; m-&gt;stats.min)
-00766 m-&gt;stats.min = val;
-00767 <span class="comment">/* histogram */</span>
-00768 }
-00769
-00770 <span class="comment">/********************** List Functions *********************/</span>
-00771 <span class="comment"></span>
-00772 <span class="comment">/** Create a new list.</span>
-00773 <span class="comment"> * A list is a map that internally has an incrementing long key for each member.</span>
-00774 <span class="comment"> * Lists do not wrap if elements are added to exceed their maximum size.</span>
-00775 <span class="comment"> * @param max_entries The maximum number of entries allowed. Currently that number will</span>
-00776 <span class="comment"> * be preallocated. If max_entries is 0, there will be no maximum and entries</span>
-00777 <span class="comment"> * will be allocated dynamically.</span>
-00778 <span class="comment"> * @param type Type of values stored in this list. </span>
-00779 <span class="comment"> * @return A MAP on success or NULL on failure.</span>
-00780 <span class="comment"> * @sa foreach</span>
-00781 <span class="comment"> */</span>
-00782
-<a name="l00783"></a><a class="code" href="map_8c.html#a25">00783</a> <a class="code" href="structmap__root.html">MAP</a> <a class="code" href="map_8c.html#a25">_stp_list_new</a>(<span class="keywordtype">unsigned</span> max_entries, <span class="keyword">enum</span> valtype type)
-00784 {
-00785 <a class="code" href="structmap__root.html">MAP</a> map = <a class="code" href="map_8c.html#a3">_stp_map_new</a> (max_entries, type);
-00786 map-&gt;<a class="code" href="structmap__root.html#o3">no_wrap</a> = 1;
-00787 <span class="keywordflow">return</span> map;
-00788 }
-00789 <span class="comment"></span>
-00790 <span class="comment">/** Clears a list.</span>
-00791 <span class="comment"> * All elements in the list are deleted.</span>
-00792 <span class="comment"> * @param map </span>
-00793 <span class="comment"> */</span>
-00794
-<a name="l00795"></a><a class="code" href="map_8c.html#a26">00795</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a26">_stp_list_clear</a>(<a class="code" href="structmap__root.html">MAP</a> map)
-00796 {
-00797 <span class="keywordflow">if</span> (map == NULL)
-00798 <span class="keywordflow">return</span>;
-00799
-00800 <span class="keywordflow">if</span> (!list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>)) {
-00801 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *ptr = (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
-00802
-00803 <span class="keywordflow">while</span> (ptr &amp;&amp; ptr != (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)&amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>) {
-00804 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *next = (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)ptr-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>.next;
-00805
-00806 <span class="comment">/* remove node from old hash list */</span>
-00807 hlist_del_init(&amp;ptr-&gt;<a class="code" href="structmap__node.html#o1">hnode</a>);
-00808
-00809 <span class="comment">/* remove from entry list */</span>
-00810 list_del(&amp;ptr-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>);
-00811
-00812 <span class="comment">/* remove any allocated string storage */</span>
-00813 map_free_strings(map, ptr);
-00814
-00815 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o1">maxnum</a>)
-00816 list_add(&amp;ptr-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>, &amp;map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>);
-00817 <span class="keywordflow">else</span>
-00818 _stp_free(ptr);
-00819
-00820 map-&gt;<a class="code" href="structmap__root.html#o2">num</a>--;
-00821 ptr = next;
-00822 }
-00823 }
-00824
-00825 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o2">num</a> != 0) {
-00826 dlog (<span class="stringliteral">"ERROR: list is supposed to be empty (has %d)\n"</span>, map-&gt;<a class="code" href="structmap__root.html#o2">num</a>);
-00827 }
-00828 }
-00829 <span class="comment"></span>
-00830 <span class="comment">/** Adds a string to a list.</span>
-00831 <span class="comment"> * @param map</span>
-00832 <span class="comment"> * @param str</span>
-00833 <span class="comment"> */</span>
-00834
-<a name="l00835"></a><a class="code" href="map_8c.html#a27">00835</a> <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a27">_stp_list_add_str</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">char</span> *str)
-00836 {
-00837 <a class="code" href="map_8c.html#a14">_stp_map_key_long</a>(map, map-&gt;<a class="code" href="structmap__root.html#o2">num</a>);
-00838 <a class="code" href="map_8c.html#a20">_stp_map_set_str</a>(map, str);
-00839 }
-00840 <span class="comment"></span>
-00841 <span class="comment">/** Adds an int64 to a list.</span>
-00842 <span class="comment"> * @param map</span>
-00843 <span class="comment"> * @param val</span>
-00844 <span class="comment"> */</span>
-00845
-<a name="l00846"></a><a class="code" href="map_8c.html#a28">00846</a> <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a28">_stp_list_add_int64</a>(<a class="code" href="structmap__root.html">MAP</a> map, int64_t val)
-00847 {
-00848 <a class="code" href="map_8c.html#a14">_stp_map_key_long</a>(map, map-&gt;<a class="code" href="structmap__root.html#o2">num</a>);
-00849 <a class="code" href="map_8c.html#a17">_stp_map_set_int64</a>(map, val);
-00850 }
-00851 <span class="comment"></span>
-00852 <span class="comment">/** Get the number of elements in a list.</span>
-00853 <span class="comment"> * @param map</span>
-00854 <span class="comment"> * @returns The number of elements in a list.</span>
-00855 <span class="comment"> */</span>
-00856
-<a name="l00857"></a><a class="code" href="map_8c.html#a29">00857</a> <span class="keyword">inline</span> <span class="keywordtype">int</span> <a class="code" href="map_8c.html#a29">_stp_list_size</a>(<a class="code" href="structmap__root.html">MAP</a> map)
-00858 {
-00859 <span class="keywordflow">return</span> map-&gt;<a class="code" href="structmap__root.html#o2">num</a>;
-00860 }
+00006 <span class="keyword">static</span> <span class="keywordtype">int</span> map_sizes[] = {
+00007 <span class="keyword">sizeof</span>(<span class="keyword">struct </span><a class="code" href="structmap__node__int64.html">map_node_int64</a>),
+00008 sizeof(struct map_node_stat),
+00009 sizeof(struct map_node_str),
+00010 0
+00011 };
+00012
+00013 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> string_hash(<span class="keyword">const</span> <span class="keywordtype">char</span> *key1, <span class="keyword">const</span> <span class="keywordtype">char</span> *key2)
+00014 {
+00015 <span class="keywordtype">int</span> hash = 0, count = 0;
+00016 <span class="keywordtype">char</span> *v1 = (<span class="keywordtype">char</span> *)key1;
+00017 <span class="keywordtype">char</span> *v2 = (<span class="keywordtype">char</span> *)key2;
+00018 <span class="keywordflow">while</span> (*v1 &amp;&amp; count++ &lt; 5) {
+00019 hash += *v1++;
+00020 }
+00021 <span class="keywordflow">while</span> (v2 &amp;&amp; *v2 &amp;&amp; count++ &lt; 5) {
+00022 hash += *v2++;
+00023 }
+00024 <span class="keywordflow">return</span> hash_long((<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)hash, HASH_TABLE_BITS);
+00025 }
+00026
+00027 <span class="keyword">static</span> <span class="keywordtype">unsigned</span> mixed_hash(<span class="keyword">const</span> <span class="keywordtype">char</span> *key1, <span class="keywordtype">long</span> key2)
+00028 {
+00029 <span class="keywordtype">int</span> hash = 0, count = 0;
+00030 <span class="keywordtype">char</span> *v = (<span class="keywordtype">char</span> *)key1;
+00031 <span class="keywordflow">while</span> (v &amp;&amp; *v &amp;&amp; count++ &lt; 5)
+00032 hash += *v++;
+00033 return hash_long((<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)(hash ^ key2), HASH_TABLE_BITS);
+00034 }
+00035 <span class="comment"></span>
+00036 <span class="comment">/** Create a new map.</span>
+00037 <span class="comment"> * Maps must be created at module initialization time.</span>
+00038 <span class="comment"> * @param max_entries The maximum number of entries allowed. Currently that number will</span>
+00039 <span class="comment"> * be preallocated. If more entries are required, the oldest ones will be deleted. This makes</span>
+00040 <span class="comment"> * it effectively a circular buffer. If max_entries is 0, there will be no maximum and entries</span>
+00041 <span class="comment"> * will be allocated dynamically.</span>
+00042 <span class="comment"> * @param type Type of values stored in this map. </span>
+00043 <span class="comment"> * @return A MAP on success or NULL on failure.</span>
+00044 <span class="comment"> */</span>
+00045
+<a name="l00046"></a><a class="code" href="map_8c.html#a3">00046</a> <a class="code" href="structmap__root.html">MAP</a> _stp_map_new(<span class="keywordtype">unsigned</span> max_entries, enum valtype type)
+00047 {
+00048 size_t size;
+00049 <a class="code" href="structmap__root.html">MAP</a> m = (<a class="code" href="structmap__root.html">MAP</a>) <a class="code" href="alloc_8h.html#a5">_stp_valloc</a>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> <a class="code" href="structmap__root.html">map_root</a>));
+00050 <span class="keywordflow">if</span> (m == NULL)
+00051 <span class="keywordflow">return</span> NULL;
+00052
+00053 INIT_LIST_HEAD(&amp;m-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
+00054
+00055 m-&gt;<a class="code" href="structmap__root.html#o1">maxnum</a> = max_entries;
+00056 m-&gt;<a class="code" href="structmap__root.html#o0">type</a> = type;
+00057 <span class="keywordflow">if</span> (type &gt;= END) {
+00058 dbug (<span class="stringliteral">"map_new: unknown type %d\n"</span>, type);
+00059 <span class="keywordflow">return</span> NULL;
+00060 }
+00061
+00062 <span class="keywordflow">if</span> (max_entries) {
+00063 <span class="keywordtype">void</span> *tmp;
+00064 <span class="keywordtype">int</span> i;
+00065 <span class="keyword">struct </span>list_head *e;
+00066
+00067 INIT_LIST_HEAD(&amp;m-&gt;<a class="code" href="structmap__root.html#o5">pool</a>);
+00068 size = map_sizes[type];
+00069 tmp = <a class="code" href="alloc_8h.html#a5">_stp_valloc</a>(max_entries * size);
+00070
+00071 <span class="keywordflow">for</span> (i = max_entries - 1; i &gt;= 0; i--) {
+00072 e = i * size + tmp;
+00073 dbug (<span class="stringliteral">"e=%lx\n"</span>, (<span class="keywordtype">long</span>)e);
+00074 list_add(e, &amp;m-&gt;<a class="code" href="structmap__root.html#o5">pool</a>);
+00075 }
+00076 m-&gt;<a class="code" href="structmap__root.html#o14">membuf</a> = tmp;
+00077 }
+00078 <span class="keywordflow">return</span> m;
+00079 }
+00080
+00081 <span class="keyword">static</span> <span class="keywordtype">void</span> map_free_strings(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *n)
+00082 {
+00083 <span class="keyword">struct </span>map_node_str *m = (<span class="keyword">struct </span>map_node_str *)n;
+00084 dbug (<span class="stringliteral">"n = %lx\n"</span>, (<span class="keywordtype">long</span>)n);
+00085 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o0">type</a> == STRING) {
+00086 dbug (<span class="stringliteral">"val STRING %lx\n"</span>, (<span class="keywordtype">long</span>)m-&gt;<a class="code" href="structmap__node__str.html#o1">str</a>);
+00087 <span class="keywordflow">if</span> (m-&gt;<a class="code" href="structmap__node__str.html#o1">str</a>)
+00088 _stp_free(m-&gt;str);
+00089 }
+00090 if (m-&gt;n.key1type == STR) {
+00091 dbug (<span class="stringliteral">"key1 STR %lx\n"</span>, (<span class="keywordtype">long</span>)<a class="code" href="map_8h.html#a0">key1str</a>(m));
+00092 <span class="keywordflow">if</span> (<a class="code" href="map_8h.html#a0">key1str</a>(m))
+00093 _stp_free(key1str(m));
+00094 }
+00095 if (m-&gt;n.key2type == STR) {
+00096 dbug (<span class="stringliteral">"key2 STR %lx\n"</span>, (<span class="keywordtype">long</span>)<a class="code" href="map_8h.html#a1">key2str</a>(m));
+00097 <span class="keywordflow">if</span> (<a class="code" href="map_8h.html#a1">key2str</a>(m))
+00098 _stp_free(key2str(m));
+00099 }
+00100 }
+00101 <span class="comment"></span>
+00102 <span class="comment">/** Deletes the current element.</span>
+00103 <span class="comment"> * If no current element (key) for this map is set, this function does nothing.</span>
+00104 <span class="comment"> * @param map </span>
+00105 <span class="comment"> */</span>
+00106
+<a name="l00107"></a><a class="code" href="map_8c.html#a5">00107</a> <span class="keywordtype">void</span> _stp_map_key_del(<a class="code" href="structmap__root.html">MAP</a> map)
+00108 {
+00109 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *m;
+00110
+00111 dbug (<span class="stringliteral">"create=%d key=%lx\n"</span>, map-&gt;create, (<span class="keywordtype">long</span>)map-&gt;key);
+00112 <span class="keywordflow">if</span> (map == NULL)
+00113 <span class="keywordflow">return</span>;
+00114
+00115 <span class="keywordflow">if</span> (map-&gt;create) {
+00116 map-&gt;create = 0;
+00117 map-&gt;key = NULL;
+00118 <span class="keywordflow">return</span>;
+00119 }
+00120
+00121 <span class="keywordflow">if</span> (map-&gt;key == NULL)
+00122 <span class="keywordflow">return</span>;
+00123
+00124 m = (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)map-&gt;key;
+00125
+00126 <span class="comment">/* remove node from old hash list */</span>
+00127 hlist_del_init(&amp;m-&gt;<a class="code" href="structmap__node.html#o1">hnode</a>);
+00128
+00129 <span class="comment">/* remove from entry list */</span>
+00130 list_del(&amp;m-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>);
+00131
+00132 <span class="comment">/* remove any allocated string storage */</span>
+00133 map_free_strings(map, (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)map-&gt;key);
+00134
+00135 <span class="keywordflow">if</span> (map-&gt;maxnum)
+00136 list_add(&amp;m-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>, &amp;map-&gt;pool);
+00137 <span class="keywordflow">else</span>
+00138 <a class="code" href="alloc_8h.html#a6">_stp_free</a>(m);
+00139
+00140 map-&gt;key = NULL;
+00141 map-&gt;num--;
+00142 }
+00143 <span class="comment"></span>
+00144 <span class="comment">/** Get the first element in a map.</span>
+00145 <span class="comment"> * @param map </span>
+00146 <span class="comment"> * @returns a pointer to the first element.</span>
+00147 <span class="comment"> * This is typically used with _stp_map_iter(). See the foreach() macro</span>
+00148 <span class="comment"> * for typical usage. It probably does what you want anyway.</span>
+00149 <span class="comment"> * @sa foreach</span>
+00150 <span class="comment"> */</span>
+00151
+<a name="l00152"></a><a class="code" href="map_8c.html#a6">00152</a> <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *<a class="code" href="map_8c.html#a6">_stp_map_start</a>(<a class="code" href="structmap__root.html">MAP</a> map)
+00153 {
+00154 <span class="keywordflow">if</span> (map == NULL)
+00155 <span class="keywordflow">return</span> NULL;
+00156
+00157 dbug (<span class="stringliteral">"%lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next);
+00158
+00159 <span class="keywordflow">if</span> (list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>))
+00160 <span class="keywordflow">return</span> NULL;
+00161
+00162 <span class="keywordflow">return</span> (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
+00163 }
+00164 <span class="comment"></span>
+00165 <span class="comment">/** Get the next element in a map.</span>
+00166 <span class="comment"> * @param map </span>
+00167 <span class="comment"> * @param m a pointer to the current element, returned from _stp_map_start()</span>
+00168 <span class="comment"> * or _stp_map_iter().</span>
+00169 <span class="comment"> * @returns a pointer to the next element.</span>
+00170 <span class="comment"> * This is typically used with _stp_map_start(). See the foreach() macro</span>
+00171 <span class="comment"> * for typical usage. It probably does what you want anyway.</span>
+00172 <span class="comment"> * @sa foreach</span>
+00173 <span class="comment"> */</span>
+00174
+<a name="l00175"></a><a class="code" href="map_8c.html#a7">00175</a> <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *<a class="code" href="map_8c.html#a7">_stp_map_iter</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *m)
+00176 {
+00177 <span class="keywordflow">if</span> (map == NULL)
+00178 <span class="keywordflow">return</span> NULL;
+00179
+00180 dbug (<span class="stringliteral">"%lx next=%lx prev=%lx map-&gt;head.next=%lx\n"</span>, (<span class="keywordtype">long</span>)m,
+00181 (<span class="keywordtype">long</span>)m-&gt;lnode.next, (<span class="keywordtype">long</span>)m-&gt;lnode.prev, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next);
+00182
+00183 <span class="keywordflow">if</span> (m-&gt;lnode.next == &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>)
+00184 <span class="keywordflow">return</span> NULL;
+00185
+00186 <span class="keywordflow">return</span> (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)m-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>.next;
+00187 }
+00188 <span class="comment"></span>
+00189 <span class="comment">/** Deletes a map.</span>
+00190 <span class="comment"> * Deletes a map, freeing all memory in all elements. Normally done only when the module exits.</span>
+00191 <span class="comment"> * @param map</span>
+00192 <span class="comment"> */</span>
+00193
+<a name="l00194"></a><a class="code" href="map_8c.html#a8">00194</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a8">_stp_map_del</a>(<a class="code" href="structmap__root.html">MAP</a> map)
+00195 {
+00196 <span class="keywordflow">if</span> (map == NULL)
+00197 <span class="keywordflow">return</span>;
+00198
+00199 <span class="keywordflow">if</span> (!list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>)) {
+00200 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *ptr = (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
+00201 <span class="keywordflow">while</span> (ptr &amp;&amp; ptr != (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)&amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>) {
+00202 map_free_strings(map, ptr);
+00203 ptr = (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)ptr-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>.next;
+00204 }
+00205 }
+00206 <a class="code" href="alloc_8h.html#a7">_stp_vfree</a>(map-&gt;<a class="code" href="structmap__root.html#o14">membuf</a>);
+00207 <a class="code" href="alloc_8h.html#a7">_stp_vfree</a>(map);
+00208 }
+00209
+00210 <span class="comment">/********************** KEY FUNCTIONS *********************/</span>
+00211
+00212 <span class="comment"></span>
+00213 <span class="comment">/** Set the map's key to two longs.</span>
+00214 <span class="comment"> * This sets the current element based on a key of two strings. If the keys are</span>
+00215 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
+00216 <span class="comment"> * call.</span>
+00217 <span class="comment"> * @param map</span>
+00218 <span class="comment"> * @param key1 first key</span>
+00219 <span class="comment"> * @param key2 second key</span>
+00220 <span class="comment"> */</span>
+00221
+<a name="l00222"></a><a class="code" href="map_8c.html#a9">00222</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a9">_stp_map_key_long_long</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">long</span> key1, <span class="keywordtype">long</span> key2)
+00223 {
+00224 <span class="keywordtype">unsigned</span> hv;
+00225 <span class="keyword">struct </span>hlist_head *head;
+00226 <span class="keyword">struct </span>hlist_node *e;
+00227
+00228 <span class="keywordflow">if</span> (map == NULL)
+00229 <span class="keywordflow">return</span>;
+00230
+00231 hv = hash_long(key1 ^ key2, HASH_TABLE_BITS);
+00232 head = &amp;map-&gt;<a class="code" href="structmap__root.html#o13">hashes</a>[hv];
+00233
+00234 dbug (<span class="stringliteral">"hash for %ld,%ld is %d\n"</span>, key1, key2, hv);
+00235
+00236 hlist_for_each(e, head) {
+00237 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *n =
+00238 (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)((long)e - <span class="keyword">sizeof</span>(<span class="keyword">struct </span>hlist_node));
+00239 dbug (<span class="stringliteral">"n =%lx key=%ld,%ld\n"</span>, (<span class="keywordtype">long</span>)n, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o0">val</a>, n-&gt;key2.<a class="code" href="unionkey__data.html#o0">val</a>);
+00240 <span class="keywordflow">if</span> (key1 == n-&gt;key1.val &amp;&amp; key2 == n-&gt;key2.val) {
+00241 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = n;
+00242 dbug (<span class="stringliteral">"saving key %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
+00243 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 0;
+00244 <span class="keywordflow">return</span>;
+00245 }
+00246 }
+00247
+00248 map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o0">val</a> = key1;
+00249 map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o0">val</a> = key2;
+00250 map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a> = LONG;
+00251 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = LONG;
+00252 map-&gt;<a class="code" href="structmap__root.html#o10">c_keyhead</a> = head;
+00253 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 1;
+00254 }
+00255 <span class="comment"></span>
+00256 <span class="comment">/** Set the map's key to two strings.</span>
+00257 <span class="comment"> * This sets the current element based on a key of two strings. If the keys are</span>
+00258 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
+00259 <span class="comment"> * call.</span>
+00260 <span class="comment"> * @param map</span>
+00261 <span class="comment"> * @param key1 first key</span>
+00262 <span class="comment"> * @param key2 second key</span>
+00263 <span class="comment"> */</span>
+00264
+<a name="l00265"></a><a class="code" href="map_8c.html#a10">00265</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a10">_stp_map_key_str_str</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">char</span> *key1, <span class="keywordtype">char</span> *key2)
+00266 {
+00267 <span class="keywordtype">unsigned</span> hv;
+00268 <span class="keyword">struct </span>hlist_head *head;
+00269 <span class="keyword">struct </span>hlist_node *e;
+00270
+00271 <span class="keywordflow">if</span> (map == NULL)
+00272 <span class="keywordflow">return</span>;
+00273
+00274 <span class="keywordflow">if</span> (key1 == NULL) {
+00275 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = NULL;
+00276 <span class="keywordflow">return</span>;
+00277 }
+00278
+00279 hv = string_hash(key1, key2);
+00280 head = &amp;map-&gt;<a class="code" href="structmap__root.html#o13">hashes</a>[hv];
+00281
+00282 dbug (<span class="stringliteral">"hash for %s,%s is %d\n"</span>, key1, key2, hv);
+00283
+00284 hlist_for_each(e, head) {
+00285 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *n =
+00286 (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)((long)e - <span class="keyword">sizeof</span>(<span class="keyword">struct </span>hlist_node));
+00287 dbug (<span class="stringliteral">"e =%lx key=%s,%s\n"</span>, (<span class="keywordtype">long</span>)e, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>,n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>);
+00288 <span class="keywordflow">if</span> (strcmp(key1, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>) == 0
+00289 &amp;&amp; (key2 == NULL || strcmp(key2, n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>) == 0)) {
+00290 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = n;
+00291 dbug (<span class="stringliteral">"saving key %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
+00292 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 0;
+00293 <span class="keywordflow">return</span>;
+00294 }
+00295 }
+00296
+00297 map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o1">str</a> = key1;
+00298 map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o1">str</a> = key2;
+00299 map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a> = STR;
+00300 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = STR;
+00301 map-&gt;<a class="code" href="structmap__root.html#o10">c_keyhead</a> = head;
+00302 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 1;
+00303 }
+00304 <span class="comment"></span>
+00305 <span class="comment">/** Set the map's key to a string and a long.</span>
+00306 <span class="comment"> * This sets the current element based on a key of a string and a long. If the keys are</span>
+00307 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
+00308 <span class="comment"> * call.</span>
+00309 <span class="comment"> * @param map</span>
+00310 <span class="comment"> * @param key1 first key</span>
+00311 <span class="comment"> * @param key2 second key</span>
+00312 <span class="comment"> */</span>
+00313
+<a name="l00314"></a><a class="code" href="map_8c.html#a11">00314</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a11">_stp_map_key_str_long</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">char</span> *key1, <span class="keywordtype">long</span> key2)
+00315 {
+00316 <span class="keywordtype">unsigned</span> hv;
+00317 <span class="keyword">struct </span>hlist_head *head;
+00318 <span class="keyword">struct </span>hlist_node *e;
+00319
+00320 <span class="keywordflow">if</span> (map == NULL)
+00321 <span class="keywordflow">return</span>;
+00322
+00323 <span class="keywordflow">if</span> (key1 == NULL) {
+00324 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = NULL;
+00325 <span class="keywordflow">return</span>;
+00326 }
+00327
+00328 hv = mixed_hash(key1, key2);
+00329 head = &amp;map-&gt;<a class="code" href="structmap__root.html#o13">hashes</a>[hv];
+00330
+00331 dbug (<span class="stringliteral">"hash for %s,%ld is %d\n"</span>, key1, key2, hv);
+00332
+00333 hlist_for_each(e, head) {
+00334 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *n =
+00335 (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)((long)e - <span class="keyword">sizeof</span>(<span class="keyword">struct </span>hlist_node));
+00336 dbug (<span class="stringliteral">"e =%lx key=%s,%ld\n"</span>, (<span class="keywordtype">long</span>)e, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>,(<span class="keywordtype">long</span>)n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o0">val</a>);
+00337 <span class="keywordflow">if</span> (strcmp(key1, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>) == 0 &amp;&amp; key2 == n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o0">val</a>) {
+00338 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = n;
+00339 dbug (<span class="stringliteral">"saving key %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
+00340 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 0;
+00341 <span class="keywordflow">return</span>;
+00342 }
+00343 }
+00344
+00345 map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o1">str</a> = key1;
+00346 map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o0">val</a> = key2;
+00347 map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a> = STR;
+00348 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = LONG;
+00349 map-&gt;<a class="code" href="structmap__root.html#o10">c_keyhead</a> = head;
+00350 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 1;
+00351 }
+00352 <span class="comment"></span>
+00353 <span class="comment">/** Set the map's key to a long and a string.</span>
+00354 <span class="comment"> * This sets the current element based on a key of a long and a string. If the keys are</span>
+00355 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
+00356 <span class="comment"> * call.</span>
+00357 <span class="comment"> * @param map</span>
+00358 <span class="comment"> * @param key1 first key</span>
+00359 <span class="comment"> * @param key2 second key</span>
+00360 <span class="comment"> */</span>
+00361
+<a name="l00362"></a><a class="code" href="map_8c.html#a12">00362</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a12">_stp_map_key_long_str</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">long</span> key1, <span class="keywordtype">char</span> *key2)
+00363 {
+00364 <span class="keywordtype">unsigned</span> hv;
+00365 <span class="keyword">struct </span>hlist_head *head;
+00366 <span class="keyword">struct </span>hlist_node *e;
+00367
+00368 <span class="keywordflow">if</span> (map == NULL)
+00369 <span class="keywordflow">return</span>;
+00370
+00371 hv = mixed_hash(key2, key1);
+00372 head = &amp;map-&gt;<a class="code" href="structmap__root.html#o13">hashes</a>[hv];
+00373 dbug (<span class="stringliteral">"hash for %ld,%s is %d\n"</span>, key1, key2, hv);
+00374
+00375 hlist_for_each(e, head) {
+00376 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *n =
+00377 (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)((long)e - <span class="keyword">sizeof</span>(<span class="keyword">struct </span>hlist_node));
+00378 dbug (<span class="stringliteral">"e =%lx key=%ld,%s\n"</span>, (<span class="keywordtype">long</span>)e, n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o0">val</a>,n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>);
+00379 <span class="keywordflow">if</span> (key1 == n-&gt;<a class="code" href="structmap__node.html#o2">key1</a>.<a class="code" href="unionkey__data.html#o0">val</a> &amp;&amp; strcmp(key2, n-&gt;<a class="code" href="structmap__node.html#o3">key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>) == 0) {
+00380 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = n;
+00381 dbug (<span class="stringliteral">"saving key %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
+00382 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 0;
+00383 <span class="keywordflow">return</span>;
+00384 }
+00385 }
+00386
+00387 map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o0">val</a> = key1;
+00388 map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o1">str</a> = key2;
+00389 map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a> = LONG;
+00390 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = STR;
+00391 map-&gt;<a class="code" href="structmap__root.html#o10">c_keyhead</a> = head;
+00392 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 1;
+00393 }
+00394 <span class="comment"></span>
+00395 <span class="comment">/** Set the map's key to a string.</span>
+00396 <span class="comment"> * This sets the current element based on a string key. If the key is</span>
+00397 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
+00398 <span class="comment"> * call.</span>
+00399 <span class="comment"> * @param map</span>
+00400 <span class="comment"> * @param key</span>
+00401 <span class="comment"> */</span>
+00402
+<a name="l00403"></a><a class="code" href="map_8c.html#a13">00403</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a13">_stp_map_key_str</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">char</span> *key)
+00404 {
+00405 <span class="keywordflow">if</span> (map == NULL)
+00406 <span class="keywordflow">return</span>;
+00407 <a class="code" href="map_8c.html#a10">_stp_map_key_str_str</a>(map, key, NULL);
+00408 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = NONE;
+00409 }
+00410 <span class="comment"></span>
+00411 <span class="comment">/** Set the map's key to a long.</span>
+00412 <span class="comment"> * This sets the current element based on a long key. If the key is</span>
+00413 <span class="comment"> * not found, a new element will not be created until a &lt;i&gt;_stp_map_set_xxx&lt;/i&gt;</span>
+00414 <span class="comment"> * call.</span>
+00415 <span class="comment"> * @param map</span>
+00416 <span class="comment"> * @param key </span>
+00417 <span class="comment"> */</span>
+00418
+<a name="l00419"></a><a class="code" href="map_8c.html#a14">00419</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a14">_stp_map_key_long</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">long</span> key)
+00420 {
+00421 <span class="keywordflow">if</span> (map == NULL)
+00422 <span class="keywordflow">return</span>;
+00423 <a class="code" href="map_8c.html#a9">_stp_map_key_long_long</a>(map, key, 0);
+00424 map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a> = NONE;
+00425 }
+00426
+00427 <span class="comment">/********************** SET/GET VALUES *********************/</span>
+00428
+00429 <span class="keyword">static</span> <span class="keywordtype">void</span> map_copy_keys(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *m)
+00430 {
+00431 m-&gt;key1type = map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a>;
+00432 m-&gt;key2type = map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a>;
+00433 <span class="keywordflow">switch</span> (map-&gt;<a class="code" href="structmap__root.html#o8">c_key1type</a>) {
+00434 <span class="keywordflow">case</span> STR:
+00435 m-&gt;key1.str = <a class="code" href="alloc_8h.html#a3">_stp_alloc</a>(strlen(map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>) + 1);
+00436 strcpy(m-&gt;key1.str, map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o1">str</a>);
+00437 <span class="keywordflow">break</span>;
+00438 <span class="keywordflow">case</span> LONG:
+00439 m-&gt;key1.val = map-&gt;<a class="code" href="structmap__root.html#o11">c_key1</a>.<a class="code" href="unionkey__data.html#o0">val</a>;
+00440 <span class="keywordflow">break</span>;
+00441 <span class="keywordflow">case</span> NONE:
+00442 <span class="comment">/* ERROR */</span>
+00443 <span class="keywordflow">break</span>;
+00444 }
+00445 <span class="keywordflow">switch</span> (map-&gt;<a class="code" href="structmap__root.html#o9">c_key2type</a>) {
+00446 <span class="keywordflow">case</span> STR:
+00447 m-&gt;key2.<a class="code" href="unionkey__data.html#o1">str</a> = <a class="code" href="alloc_8h.html#a3">_stp_alloc</a>(strlen(map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>) + 1);
+00448 strcpy(m-&gt;key2.str, map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o1">str</a>);
+00449 <span class="keywordflow">break</span>;
+00450 <span class="keywordflow">case</span> LONG:
+00451 m-&gt;key2.<a class="code" href="unionkey__data.html#o0">val</a> = map-&gt;<a class="code" href="structmap__root.html#o12">c_key2</a>.<a class="code" href="unionkey__data.html#o0">val</a>;
+00452 <span class="keywordflow">break</span>;
+00453 <span class="keywordflow">case</span> NONE:
+00454 <span class="keywordflow">break</span>;
+00455 }
+00456
+00457 <span class="comment">/* add node to new hash list */</span>
+00458 hlist_add_head(&amp;m-&gt;hnode, map-&gt;<a class="code" href="structmap__root.html#o10">c_keyhead</a>);
+00459
+00460 map-&gt;<a class="code" href="structmap__root.html#o6">key</a> = m;
+00461 map-&gt;<a class="code" href="structmap__root.html#o7">create</a> = 0;
+00462 map-&gt;<a class="code" href="structmap__root.html#o2">num</a>++;
+00463 }
+00464
+00465 <span class="keyword">static</span> <span class="keywordtype">void</span> __stp_map_set_int64(<a class="code" href="structmap__root.html">MAP</a> map, int64_t val, <span class="keywordtype">int</span> add)
+00466 {
+00467 <span class="keyword">struct </span><a class="code" href="structmap__node__int64.html">map_node_int64</a> *m;
+00468
+00469 <span class="keywordflow">if</span> (map == NULL)
+00470 return;
+00471
+00472 if (map-&gt;create) {
+00473 <span class="keywordflow">if</span> (val == 0)
+00474 return;
+00475
+00476 if (map-&gt;maxnum) {
+00477 <span class="keywordflow">if</span> (list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>)) {
+00478 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o3">no_wrap</a>) {
+00479 <span class="comment">/* ERROR. FIXME */</span>
+00480 <span class="keywordflow">return</span>;
+00481 }
+00482 m = (<span class="keyword">struct </span><a class="code" href="structmap__node__int64.html">map_node_int64</a> *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
+00483 hlist_del_init(&amp;m-&gt;<a class="code" href="structmap__node__int64.html#o0">n</a>.<a class="code" href="structmap__node.html#o1">hnode</a>);
+00484 map_free_strings(map, (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)m);
+00485 dbug (<span class="stringliteral">"got %lx off head\n"</span>, (<span class="keywordtype">long</span>)m);
+00486 } <span class="keywordflow">else</span> {
+00487 m = (<span class="keyword">struct </span><a class="code" href="structmap__node__int64.html">map_node_int64</a> *)map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>.next;
+00488 dbug (<span class="stringliteral">"got %lx off pool\n"</span>, (<span class="keywordtype">long</span>)m);
+00489 }
+00490 list_move_tail(&amp;m-&gt;<a class="code" href="structmap__node__int64.html#o0">n</a>.<a class="code" href="structmap__node.html#o0">lnode</a>, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
+00491 } <span class="keywordflow">else</span> {
+00492 m = (<span class="keyword">struct </span><a class="code" href="structmap__node__int64.html">map_node_int64</a> *)
+00493 <a class="code" href="alloc_8h.html#a4">_stp_calloc</a>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> <a class="code" href="structmap__node__int64.html">map_node_int64</a>));
+00494 <span class="comment">/* add node to list */</span>
+00495 list_add_tail(&amp;m-&gt;<a class="code" href="structmap__node__int64.html#o0">n</a>.<a class="code" href="structmap__node.html#o0">lnode</a>, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
+00496 }
+00497
+00498 <span class="comment">/* copy the key(s) */</span>
+00499 map_copy_keys(map, &amp;m-&gt;<a class="code" href="structmap__node__int64.html#o0">n</a>);
+00500
+00501 <span class="comment">/* set the value */</span>
+00502 m-&gt;<a class="code" href="structmap__node__int64.html#o1">val</a> = val;
+00503 } <span class="keywordflow">else</span> {
+00504 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
+00505 return;
+00506
+00507 if (val) {
+00508 m = (<span class="keyword">struct </span><a class="code" href="structmap__node__int64.html">map_node_int64</a> *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
+00509 <span class="keywordflow">if</span> (add)
+00510 m-&gt;val += val;
+00511 else
+00512 m-&gt;val = val;
+00513 } else if (!add) {
+00514 <span class="comment">/* setting value to 0 is the same as deleting */</span>
+00515 <a class="code" href="map_8c.html#a5">_stp_map_key_del</a>(map);
+00516 }
+00517 }
+00518 }
+00519 <span class="comment"></span>
+00520 <span class="comment">/** Set the current element's value to an int64.</span>
+00521 <span class="comment"> * This sets the current element's value to an int64. The map must have been created</span>
+00522 <span class="comment"> * to hold int64s using _stp_map_new()</span>
+00523 <span class="comment"> *</span>
+00524 <span class="comment"> * If the element doesn't exist, it is created. If no current element (key)</span>
+00525 <span class="comment"> * is set for the map, this function does nothing.</span>
+00526 <span class="comment"> * @param map</span>
+00527 <span class="comment"> * @param val new value</span>
+00528 <span class="comment"> * @sa _stp_map_add_int64</span>
+00529 <span class="comment"> */</span>
+<a name="l00530"></a><a class="code" href="map_8c.html#a17">00530</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a17">_stp_map_set_int64</a>(<a class="code" href="structmap__root.html">MAP</a> map, int64_t val)
+00531 {
+00532 __stp_map_set_int64 (map, val, 0);
+00533 }
+00534
+00535 <span class="comment"></span>
+00536 <span class="comment">/** Adds an int64 to the current element's value.</span>
+00537 <span class="comment"> * This adds an int64 to the current element's value. The map must have been created</span>
+00538 <span class="comment"> * to hold int64s using _stp_map_new()</span>
+00539 <span class="comment"> *</span>
+00540 <span class="comment"> * If the element doesn't exist, it is created. If no current element (key)</span>
+00541 <span class="comment"> * is set for the map, this function does nothing.</span>
+00542 <span class="comment"> * @param map</span>
+00543 <span class="comment"> * @param val value</span>
+00544 <span class="comment"> * @sa _stp_map_set_int64</span>
+00545 <span class="comment"> */</span>
+00546
+<a name="l00547"></a><a class="code" href="map_8c.html#a18">00547</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a18">_stp_map_add_int64</a>(<a class="code" href="structmap__root.html">MAP</a> map, int64_t val)
+00548 {
+00549 __stp_map_set_int64 (map, val, 1);
+00550 }
+00551 <span class="comment"></span>
+00552 <span class="comment">/** Gets the current element's value.</span>
+00553 <span class="comment"> * @param map</span>
+00554 <span class="comment"> * @returns The value. If the current element is not set or doesn't exist, returns 0.</span>
+00555 <span class="comment"> */</span>
+00556
+<a name="l00557"></a><a class="code" href="map_8c.html#a19">00557</a> int64_t <a class="code" href="map_8c.html#a19">_stp_map_get_int64</a>(<a class="code" href="structmap__root.html">MAP</a> map)
+00558 {
+00559 <span class="keyword">struct </span><a class="code" href="structmap__node__int64.html">map_node_int64</a> *m;
+00560 <span class="keywordflow">if</span> (map == NULL || map-&gt;<a class="code" href="structmap__root.html#o7">create</a> || map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
+00561 <span class="keywordflow">return</span> 0;
+00562 dbug (<span class="stringliteral">"%lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
+00563 m = (<span class="keyword">struct </span><a class="code" href="structmap__node__int64.html">map_node_int64</a> *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
+00564 <span class="keywordflow">return</span> m-&gt;<a class="code" href="structmap__node__int64.html#o1">val</a>;
+00565 }
+00566 <span class="comment"></span>
+00567 <span class="comment">/** Set the current element's value to a string.</span>
+00568 <span class="comment"> * This sets the current element's value to an string. The map must have been created</span>
+00569 <span class="comment"> * to hold int64s using &lt;i&gt;_stp_map_new(xxx, STRING)&lt;/i&gt;</span>
+00570 <span class="comment"> *</span>
+00571 <span class="comment"> * If the element doesn't exist, it is created. If no current element (key)</span>
+00572 <span class="comment"> * is set for the map, this function does nothing.</span>
+00573 <span class="comment"> * @param map</span>
+00574 <span class="comment"> * @param val new string</span>
+00575 <span class="comment"> */</span>
+00576
+<a name="l00577"></a><a class="code" href="map_8c.html#a20">00577</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a20">_stp_map_set_str</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">char</span> *val)
+00578 {
+00579 <span class="keyword">struct </span>map_node_str *m;
+00580
+00581 <span class="keywordflow">if</span> (map == NULL)
+00582 <span class="keywordflow">return</span>;
+00583
+00584 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o7">create</a>) {
+00585 <span class="keywordflow">if</span> (val == NULL)
+00586 <span class="keywordflow">return</span>;
+00587
+00588 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o1">maxnum</a>) {
+00589 <span class="keywordflow">if</span> (list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>)) {
+00590 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o3">no_wrap</a>) {
+00591 <span class="comment">/* ERROR. FIXME */</span>
+00592 <span class="keywordflow">return</span>;
+00593 }
+00594 m = (<span class="keyword">struct </span>map_node_str *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
+00595 hlist_del_init(&amp;m-&gt;<a class="code" href="structmap__node__str.html#o0">n</a>.<a class="code" href="structmap__node.html#o1">hnode</a>);
+00596 map_free_strings(map, (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)m);
+00597 dbug (<span class="stringliteral">"got %lx off head\n"</span>, (<span class="keywordtype">long</span>)m);
+00598 } <span class="keywordflow">else</span> {
+00599 m = (<span class="keyword">struct </span>map_node_str *)map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>.next;
+00600 dbug (<span class="stringliteral">"got %lx off pool\n"</span>, (<span class="keywordtype">long</span>)m);
+00601 }
+00602 list_move_tail(&amp;m-&gt;<a class="code" href="structmap__node__str.html#o0">n</a>.<a class="code" href="structmap__node.html#o0">lnode</a>, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
+00603 } <span class="keywordflow">else</span> {
+00604 m = (<span class="keyword">struct </span>map_node_str *)
+00605 <a class="code" href="alloc_8h.html#a4">_stp_calloc</a>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> map_node_str));
+00606 <span class="comment">/* add node to list */</span>
+00607 list_add_tail(&amp;m-&gt;<a class="code" href="structmap__node__str.html#o0">n</a>.<a class="code" href="structmap__node.html#o0">lnode</a>, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
+00608 }
+00609
+00610 <span class="comment">/* copy the key(s) */</span>
+00611 map_copy_keys(map, &amp;m-&gt;<a class="code" href="structmap__node__str.html#o0">n</a>);
+00612
+00613 <span class="comment">/* set the value */</span>
+00614 m-&gt;<a class="code" href="structmap__node__str.html#o1">str</a> = <a class="code" href="alloc_8h.html#a3">_stp_alloc</a>(strlen(val) + 1);
+00615 strcpy(m-&gt;<a class="code" href="structmap__node__str.html#o1">str</a>, val);
+00616 } <span class="keywordflow">else</span> {
+00617 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
+00618 <span class="keywordflow">return</span>;
+00619
+00620 <span class="keywordflow">if</span> (val) {
+00621 m = (<span class="keyword">struct </span>map_node_str *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
+00622 <span class="keywordflow">if</span> (m-&gt;<a class="code" href="structmap__node__str.html#o1">str</a>)
+00623 <a class="code" href="alloc_8h.html#a6">_stp_free</a>(m-&gt;<a class="code" href="structmap__node__str.html#o1">str</a>);
+00624 m-&gt;<a class="code" href="structmap__node__str.html#o1">str</a> = <a class="code" href="alloc_8h.html#a3">_stp_alloc</a>(strlen(val) + 1);
+00625 strcpy(m-&gt;<a class="code" href="structmap__node__str.html#o1">str</a>, val);
+00626 } <span class="keywordflow">else</span> {
+00627 <span class="comment">/* setting value to 0 is the same as deleting */</span>
+00628 <a class="code" href="map_8c.html#a5">_stp_map_key_del</a>(map);
+00629 }
+00630 }
+00631 }
+00632 <span class="comment"></span>
+00633 <span class="comment">/** Gets the current element's value.</span>
+00634 <span class="comment"> * @param map</span>
+00635 <span class="comment"> * @returns A string pointer. If the current element is not set or doesn't exist, returns NULL.</span>
+00636 <span class="comment"> */</span>
+00637
+<a name="l00638"></a><a class="code" href="map_8c.html#a21">00638</a> <span class="keywordtype">char</span> *<a class="code" href="map_8c.html#a21">_stp_map_get_str</a>(<a class="code" href="structmap__root.html">MAP</a> map)
+00639 {
+00640 <span class="keyword">struct </span>map_node_str *m;
+00641 <span class="keywordflow">if</span> (map == NULL || map-&gt;<a class="code" href="structmap__root.html#o7">create</a> || map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
+00642 <span class="keywordflow">return</span> NULL;
+00643 dbug (<span class="stringliteral">"%lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
+00644 m = (<span class="keyword">struct </span>map_node_str *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
+00645 <span class="keywordflow">return</span> m-&gt;<a class="code" href="structmap__node__str.html#o1">str</a>;
+00646 }
+00647 <span class="comment"></span>
+00648 <span class="comment">/** Set the current element's value to a stat.</span>
+00649 <span class="comment"> * This sets the current element's value to an stat struct. The map must have been created</span>
+00650 <span class="comment"> * to hold stats using &lt;i&gt;_stp_map_new(xxx, STAT)&lt;/i&gt;. This function would only be used</span>
+00651 <span class="comment"> * if we wanted to set stats to something other than the normal initial values (count = 0,</span>
+00652 <span class="comment"> * sum = 0, etc). It may be deleted if it doesn't turn out to be useful.</span>
+00653 <span class="comment"> * @sa _stp_map_stat_add </span>
+00654 <span class="comment"> *</span>
+00655 <span class="comment"> * If the element doesn't exist, it is created. If no current element (key)</span>
+00656 <span class="comment"> * is set for the map, this function does nothing.</span>
+00657 <span class="comment"> * @param map</span>
+00658 <span class="comment"> * @param stats pointer to stats struct.</span>
+00659 <span class="comment"> * @todo Histograms don't work yet.</span>
+00660 <span class="comment"> */</span>
+00661
+<a name="l00662"></a><a class="code" href="map_8c.html#a22">00662</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a22">_stp_map_set_stat</a>(<a class="code" href="structmap__root.html">MAP</a> map, <a class="code" href="structstat.html">stat</a> * stats)
+00663 {
+00664 <span class="keyword">struct </span>map_node_stat *m;
+00665
+00666 <span class="keywordflow">if</span> (map == NULL)
+00667 <span class="keywordflow">return</span>;
+00668 dbug (<span class="stringliteral">"set_stat %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
+00669
+00670 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o7">create</a>) {
+00671 <span class="keywordflow">if</span> (stats == NULL)
+00672 <span class="keywordflow">return</span>;
+00673
+00674 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o1">maxnum</a>) {
+00675 <span class="keywordflow">if</span> (list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>)) {
+00676 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o3">no_wrap</a>) {
+00677 <span class="comment">/* ERROR. FIXME */</span>
+00678 <span class="keywordflow">return</span>;
+00679 }
+00680 m = (<span class="keyword">struct </span>map_node_stat *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
+00681 hlist_del_init(&amp;m-&gt;<a class="code" href="structmap__node__stat.html#o0">n</a>.<a class="code" href="structmap__node.html#o1">hnode</a>);
+00682 map_free_strings(map, (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)m);
+00683 dbug (<span class="stringliteral">"got %lx off head\n"</span>, (<span class="keywordtype">long</span>)m);
+00684 } <span class="keywordflow">else</span> {
+00685 m = (<span class="keyword">struct </span>map_node_stat *)map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>.next;
+00686 dbug (<span class="stringliteral">"got %lx off pool\n"</span>, (<span class="keywordtype">long</span>)m);
+00687 }
+00688 list_move_tail(&amp;m-&gt;<a class="code" href="structmap__node__stat.html#o0">n</a>.<a class="code" href="structmap__node.html#o0">lnode</a>, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
+00689 } <span class="keywordflow">else</span> {
+00690 m = (<span class="keyword">struct </span>map_node_stat *)
+00691 <a class="code" href="alloc_8h.html#a4">_stp_calloc</a>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> map_node_stat));
+00692 <span class="comment">/* add node to list */</span>
+00693 list_add_tail(&amp;m-&gt;<a class="code" href="structmap__node__stat.html#o0">n</a>.<a class="code" href="structmap__node.html#o0">lnode</a>, &amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>);
+00694 }
+00695
+00696 <span class="comment">/* copy the key(s) */</span>
+00697 map_copy_keys(map, &amp;m-&gt;<a class="code" href="structmap__node__stat.html#o0">n</a>);
+00698
+00699 <span class="comment">/* set the value */</span>
+00700 memcpy(&amp;m-&gt;<a class="code" href="structmap__node__stat.html#o1">stats</a>, stats, <span class="keyword">sizeof</span>(<a class="code" href="structstat.html">stat</a>));
+00701 } <span class="keywordflow">else</span> {
+00702 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
+00703 <span class="keywordflow">return</span>;
+00704
+00705 <span class="keywordflow">if</span> (stats) {
+00706 m = (<span class="keyword">struct </span>map_node_stat *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
+00707 memcpy(&amp;m-&gt;<a class="code" href="structmap__node__stat.html#o1">stats</a>, stats, <span class="keyword">sizeof</span>(<a class="code" href="structstat.html">stat</a>));
+00708 } <span class="keywordflow">else</span> {
+00709 <span class="comment">/* setting value to NULL is the same as deleting */</span>
+00710 <a class="code" href="map_8c.html#a5">_stp_map_key_del</a>(map);
+00711 }
+00712 }
+00713 }
+00714 <span class="comment"></span>
+00715 <span class="comment">/** Gets the current element's value.</span>
+00716 <span class="comment"> * @param map</span>
+00717 <span class="comment"> * @returns A pointer to the stats struct. If the current element is not set </span>
+00718 <span class="comment"> * or doesn't exist, returns NULL.</span>
+00719 <span class="comment"> */</span>
+00720
+<a name="l00721"></a><a class="code" href="map_8c.html#a23">00721</a> <a class="code" href="structstat.html">stat</a> *<a class="code" href="map_8c.html#a23">_stp_map_get_stat</a>(<a class="code" href="structmap__root.html">MAP</a> map)
+00722 {
+00723 <span class="keyword">struct </span>map_node_stat *m;
+00724 <span class="keywordflow">if</span> (map == NULL || map-&gt;<a class="code" href="structmap__root.html#o7">create</a> || map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
+00725 <span class="keywordflow">return</span> NULL;
+00726 dbug (<span class="stringliteral">"%lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
+00727 m = (<span class="keyword">struct </span>map_node_stat *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
+00728 <span class="keywordflow">return</span> &amp;m-&gt;<a class="code" href="structmap__node__stat.html#o1">stats</a>;
+00729 }
+00730 <span class="comment"></span>
+00731 <span class="comment">/** Add to the current element's statistics.</span>
+00732 <span class="comment"> * Increments the statistics counter by one and the sum by &lt;i&gt;val&lt;/i&gt;.</span>
+00733 <span class="comment"> * Adjusts minimum, maximum, and histogram.</span>
+00734 <span class="comment"> *</span>
+00735 <span class="comment"> * If the element doesn't exist, it is created. If no current element (key)</span>
+00736 <span class="comment"> * is set for the map, this function does nothing.</span>
+00737 <span class="comment"> * @param map</span>
+00738 <span class="comment"> * @param val value to add to the statistics</span>
+00739 <span class="comment"> * @todo Histograms don't work yet.</span>
+00740 <span class="comment"> */</span>
+00741
+<a name="l00742"></a><a class="code" href="map_8c.html#a24">00742</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a24">_stp_map_stat_add</a>(<a class="code" href="structmap__root.html">MAP</a> map, int64_t val)
+00743 {
+00744 <span class="keyword">struct </span>map_node_stat *m;
+00745 <span class="keywordflow">if</span> (map == NULL)
+00746 <span class="keywordflow">return</span>;
+00747
+00748 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o7">create</a>) {
+00749 <a class="code" href="structstat.html">stat</a> st = { 1, val, val, val };
+00750 <span class="comment">/* histogram */</span>
+00751 <a class="code" href="map_8c.html#a22">_stp_map_set_stat</a>(map, &amp;st);
+00752 <span class="keywordflow">return</span>;
+00753 }
+00754
+00755 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o6">key</a> == NULL)
+00756 <span class="keywordflow">return</span>;
+00757
+00758 dbug (<span class="stringliteral">"add_stat %lx\n"</span>, (<span class="keywordtype">long</span>)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>);
+00759 m = (<span class="keyword">struct </span>map_node_stat *)map-&gt;<a class="code" href="structmap__root.html#o6">key</a>;
+00760 m-&gt;<a class="code" href="structmap__node__stat.html#o1">stats</a>.<a class="code" href="structstat.html#o0">count</a>++;
+00761 m-&gt;<a class="code" href="structmap__node__stat.html#o1">stats</a>.<a class="code" href="structstat.html#o1">sum</a> += val;
+00762 <span class="keywordflow">if</span> (val &gt; m-&gt;<a class="code" href="structmap__node__stat.html#o1">stats</a>.<a class="code" href="structstat.html#o3">max</a>)
+00763 m-&gt;<a class="code" href="structmap__node__stat.html#o1">stats</a>.<a class="code" href="structstat.html#o3">max</a> = val;
+00764 <span class="keywordflow">if</span> (val &lt; m-&gt;stats.min)
+00765 m-&gt;<a class="code" href="structmap__node__stat.html#o1">stats</a>.<a class="code" href="structstat.html#o2">min</a> = val;
+00766 <span class="comment">/* histogram */</span>
+00767 }
+00768
+00769 <span class="comment">/********************** List Functions *********************/</span>
+00770 <span class="comment"></span>
+00771 <span class="comment">/** Create a new list.</span>
+00772 <span class="comment"> * A list is a map that internally has an incrementing long key for each member.</span>
+00773 <span class="comment"> * Lists do not wrap if elements are added to exceed their maximum size.</span>
+00774 <span class="comment"> * @param max_entries The maximum number of entries allowed. Currently that number will</span>
+00775 <span class="comment"> * be preallocated. If max_entries is 0, there will be no maximum and entries</span>
+00776 <span class="comment"> * will be allocated dynamically.</span>
+00777 <span class="comment"> * @param type Type of values stored in this list. </span>
+00778 <span class="comment"> * @return A MAP on success or NULL on failure.</span>
+00779 <span class="comment"> * @sa foreach</span>
+00780 <span class="comment"> */</span>
+00781
+<a name="l00782"></a><a class="code" href="map_8c.html#a25">00782</a> <a class="code" href="structmap__root.html">MAP</a> <a class="code" href="map_8c.html#a25">_stp_list_new</a>(<span class="keywordtype">unsigned</span> max_entries, <span class="keyword">enum</span> valtype type)
+00783 {
+00784 <a class="code" href="structmap__root.html">MAP</a> map = <a class="code" href="map_8c.html#a3">_stp_map_new</a> (max_entries, type);
+00785 map-&gt;<a class="code" href="structmap__root.html#o3">no_wrap</a> = 1;
+00786 <span class="keywordflow">return</span> map;
+00787 }
+00788 <span class="comment"></span>
+00789 <span class="comment">/** Clears a list.</span>
+00790 <span class="comment"> * All elements in the list are deleted.</span>
+00791 <span class="comment"> * @param map </span>
+00792 <span class="comment"> */</span>
+00793
+<a name="l00794"></a><a class="code" href="map_8c.html#a26">00794</a> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a26">_stp_list_clear</a>(<a class="code" href="structmap__root.html">MAP</a> map)
+00795 {
+00796 <span class="keywordflow">if</span> (map == NULL)
+00797 <span class="keywordflow">return</span>;
+00798
+00799 <span class="keywordflow">if</span> (!list_empty(&amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>)) {
+00800 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *ptr = (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)map-&gt;<a class="code" href="structmap__root.html#o4">head</a>.next;
+00801
+00802 <span class="keywordflow">while</span> (ptr &amp;&amp; ptr != (<span class="keyword">struct</span> <a class="code" href="structmap__node.html">map_node</a> *)&amp;map-&gt;<a class="code" href="structmap__root.html#o4">head</a>) {
+00803 <span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *next = (<span class="keyword">struct </span><a class="code" href="structmap__node.html">map_node</a> *)ptr-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>.next;
+00804
+00805 <span class="comment">/* remove node from old hash list */</span>
+00806 hlist_del_init(&amp;ptr-&gt;<a class="code" href="structmap__node.html#o1">hnode</a>);
+00807
+00808 <span class="comment">/* remove from entry list */</span>
+00809 list_del(&amp;ptr-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>);
+00810
+00811 <span class="comment">/* remove any allocated string storage */</span>
+00812 map_free_strings(map, ptr);
+00813
+00814 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o1">maxnum</a>)
+00815 list_add(&amp;ptr-&gt;<a class="code" href="structmap__node.html#o0">lnode</a>, &amp;map-&gt;<a class="code" href="structmap__root.html#o5">pool</a>);
+00816 <span class="keywordflow">else</span>
+00817 <a class="code" href="alloc_8h.html#a6">_stp_free</a>(ptr);
+00818
+00819 map-&gt;<a class="code" href="structmap__root.html#o2">num</a>--;
+00820 ptr = next;
+00821 }
+00822 }
+00823
+00824 <span class="keywordflow">if</span> (map-&gt;<a class="code" href="structmap__root.html#o2">num</a> != 0) {
+00825 <a class="code" href="io_8c.html#a4">dlog</a> (<span class="stringliteral">"ERROR: list is supposed to be empty (has %d)\n"</span>, map-&gt;<a class="code" href="structmap__root.html#o2">num</a>);
+00826 }
+00827 }
+00828 <span class="comment"></span>
+00829 <span class="comment">/** Adds a string to a list.</span>
+00830 <span class="comment"> * @param map</span>
+00831 <span class="comment"> * @param str</span>
+00832 <span class="comment"> */</span>
+00833
+<a name="l00834"></a><a class="code" href="map_8c.html#a27">00834</a> <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a27">_stp_list_add_str</a>(<a class="code" href="structmap__root.html">MAP</a> map, <span class="keywordtype">char</span> *str)
+00835 {
+00836 <a class="code" href="map_8c.html#a14">_stp_map_key_long</a>(map, map-&gt;<a class="code" href="structmap__root.html#o2">num</a>);
+00837 <a class="code" href="map_8c.html#a20">_stp_map_set_str</a>(map, str);
+00838 }
+00839 <span class="comment"></span>
+00840 <span class="comment">/** Adds an int64 to a list.</span>
+00841 <span class="comment"> * @param map</span>
+00842 <span class="comment"> * @param val</span>
+00843 <span class="comment"> */</span>
+00844
+<a name="l00845"></a><a class="code" href="map_8c.html#a28">00845</a> <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="map_8c.html#a28">_stp_list_add_int64</a>(<a class="code" href="structmap__root.html">MAP</a> map, int64_t val)
+00846 {
+00847 <a class="code" href="map_8c.html#a14">_stp_map_key_long</a>(map, map-&gt;<a class="code" href="structmap__root.html#o2">num</a>);
+00848 <a class="code" href="map_8c.html#a17">_stp_map_set_int64</a>(map, val);
+00849 }
+00850 <span class="comment"></span>
+00851 <span class="comment">/** Get the number of elements in a list.</span>
+00852 <span class="comment"> * @param map</span>
+00853 <span class="comment"> * @returns The number of elements in a list.</span>
+00854 <span class="comment"> */</span>
+00855
+<a name="l00856"></a><a class="code" href="map_8c.html#a29">00856</a> <span class="keyword">inline</span> <span class="keywordtype">int</span> <a class="code" href="map_8c.html#a29">_stp_list_size</a>(<a class="code" href="structmap__root.html">MAP</a> map)
+00857 {
+00858 <span class="keywordflow">return</span> map-&gt;<a class="code" href="structmap__root.html#o2">num</a>;
+00859 }
</pre></div><hr size="1"><address style="align: right;"><small>
-Generated on Tue Mar 22 00:32:02 2005 for SystemTap.</small></body>
+Generated on Tue Mar 22 10:27:36 2005 for SystemTap.</small></body>
</html>