VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/string/strspace.cpp@ 27653

Last change on this file since 27653 was 26344, checked in by vboxsync, 15 years ago

Runtime: white space cleanup.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.9 KB
Line 
1/* $Id: strspace.cpp 26344 2010-02-09 03:39:45Z vboxsync $ */
2/** @file
3 * IPRT - Unique String Spaces.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#include <iprt/string.h>
36#include "internal/iprt.h"
37
38#include <iprt/assert.h>
39
40
41/*******************************************************************************
42* Defined Constants And Macros *
43*******************************************************************************/
44/*
45 * AVL configuration.
46 */
47#define KAVL_FN(a) rtstrspace##a
48#define KAVL_MAX_STACK 27 /* Up to 2^24 nodes. */
49#define KAVL_EQUAL_ALLOWED 1
50#define KAVLNODECORE RTSTRSPACECORE
51#define PKAVLNODECORE PRTSTRSPACECORE
52#define PPKAVLNODECORE PPRTSTRSPACECORE
53#define KAVLKEY uint32_t
54#define PKAVLKEY uint32_t *
55
56#define PKAVLCALLBACK PFNRTSTRSPACECALLBACK
57
58/*
59 * AVL Compare macros
60 */
61#define KAVL_G(key1, key2) (key1 > key2)
62#define KAVL_E(key1, key2) (key1 == key2)
63#define KAVL_NE(key1, key2) (key1 != key2)
64
65
66/*
67 * Include the code.
68 */
69#define SSToDS(ptr) ptr
70#define KMAX RT_MAX
71#define kASSERT Assert
72#include "../table/avl_Base.cpp.h"
73#include "../table/avl_Get.cpp.h"
74#include "../table/avl_DoWithAll.cpp.h"
75#include "../table/avl_Destroy.cpp.h"
76
77
78
79/* sdbm:
80 This algorithm was created for sdbm (a public-domain reimplementation of
81 ndbm) database library. it was found to do well in scrambling bits,
82 causing better distribution of the keys and fewer splits. it also happens
83 to be a good general hashing function with good distribution. the actual
84 function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below
85 is the faster version used in gawk. [there is even a faster, duff-device
86 version] the magic constant 65599 was picked out of thin air while
87 experimenting with different constants, and turns out to be a prime.
88 this is one of the algorithms used in berkeley db (see sleepycat) and
89 elsewhere. */
90inline uint32_t sdbm(const char *str, size_t *pcch)
91{
92 uint8_t *pu8 = (uint8_t *)str;
93 uint32_t hash = 0;
94 int c;
95
96 while ((c = *pu8++))
97 hash = c + (hash << 6) + (hash << 16) - hash;
98
99 *pcch = (uintptr_t)pu8 - (uintptr_t)str;
100 return hash;
101}
102
103
104/**
105 * Inserts a string into a unique string space.
106 *
107 * @returns true on success.
108 * @returns false if the string collieded with an existing string.
109 * @param pStrSpace The space to insert it into.
110 * @param pStr The string node.
111 */
112RTDECL(bool) RTStrSpaceInsert(PRTSTRSPACE pStrSpace, PRTSTRSPACECORE pStr)
113{
114 pStr->Key = sdbm(pStr->pszString, &pStr->cchString);
115 PRTSTRSPACECORE pMatch = KAVL_FN(Get)(pStrSpace, pStr->Key);
116 if (!pMatch)
117 return KAVL_FN(Insert)(pStrSpace, pStr);
118
119 /* Check for clashes. */
120 for (PRTSTRSPACECORE pCur = pMatch; pCur; pCur = pCur->pList)
121 if ( pCur->cchString == pStr->cchString
122 && !memcmp(pCur->pszString, pStr->pszString, pStr->cchString))
123 return false;
124 pStr->pList = pMatch->pList;
125 pMatch->pList = pStr;
126 return false;
127}
128RT_EXPORT_SYMBOL(RTStrSpaceInsert);
129
130
131/**
132 * Removes a string from a unique string space.
133 *
134 * @returns Pointer to the removed string node.
135 * @returns NULL if the string was not found in the string space.
136 * @param pStrSpace The space to insert it into.
137 * @param pszString The string to remove.
138 */
139RTDECL(PRTSTRSPACECORE) RTStrSpaceRemove(PRTSTRSPACE pStrSpace, const char *pszString)
140{
141 size_t cchString;
142 KAVLKEY Key = sdbm(pszString, &cchString);
143 PRTSTRSPACECORE pCur = KAVL_FN(Get)(pStrSpace, Key);
144 if (!pCur)
145 return NULL;
146
147 /* find the right one. */
148 PRTSTRSPACECORE pPrev = NULL;
149 for (; pCur; pPrev = pCur, pCur = pCur->pList)
150 if ( pCur->cchString == cchString
151 && !memcmp(pCur->pszString, pszString, cchString))
152 break;
153 if (pCur)
154 {
155 if (pPrev)
156 /* simple, it's in the linked list. */
157 pPrev->pList = pCur->pList;
158 else
159 {
160 /* in the tree. remove and reinsert list head. */
161 PRTSTRSPACECORE pInsert = pCur->pList;
162 pCur->pList = NULL;
163 pCur = KAVL_FN(Remove)(pStrSpace, Key);
164 Assert(pCur);
165 if (pInsert)
166 {
167 PRTSTRSPACECORE pList = pInsert->pList;
168 bool fRc = KAVL_FN(Insert)(pStrSpace, pInsert);
169 Assert(fRc); NOREF(fRc);
170 pInsert->pList = pList;
171 }
172 }
173 }
174
175 return pCur;
176}
177RT_EXPORT_SYMBOL(RTStrSpaceRemove);
178
179
180/**
181 * Gets a string from a unique string space.
182 *
183 * @returns Pointer to the string node.
184 * @returns NULL if the string was not found in the string space.
185 * @param pStrSpace The space to insert it into.
186 * @param pszString The string to get.
187 */
188RTDECL(PRTSTRSPACECORE) RTStrSpaceGet(PRTSTRSPACE pStrSpace, const char *pszString)
189{
190 size_t cchString;
191 KAVLKEY Key = sdbm(pszString, &cchString);
192 PRTSTRSPACECORE pCur = KAVL_FN(Get)(pStrSpace, Key);
193 if (!pCur)
194 return NULL;
195
196 /* Linear search. */
197 for (; pCur; pCur = pCur->pList)
198 if ( pCur->cchString == cchString
199 && !memcmp(pCur->pszString, pszString, cchString))
200 return pCur;
201 return NULL;
202}
203RT_EXPORT_SYMBOL(RTStrSpaceGet);
204
205
206
207/**
208 * Enumerates the string space.
209 * The caller supplies a callback which will be called for each of
210 * the string nodes.
211 *
212 * @returns 0 or what ever non-zero return value pfnCallback returned
213 * when aborting the destruction.
214 * @param pStrSpace The space to insert it into.
215 * @param pfnCallback The callback.
216 * @param pvUser The user argument.
217 */
218RTDECL(int) RTStrSpaceEnumerate(PRTSTRSPACE pStrSpace, PFNRTSTRSPACECALLBACK pfnCallback, void *pvUser)
219{
220 return KAVL_FN(DoWithAll)(pStrSpace, true, pfnCallback, pvUser);
221}
222RT_EXPORT_SYMBOL(RTStrSpaceEnumerate);
223
224
225/**
226 * Destroys the string space.
227 * The caller supplies a callback which will be called for each of
228 * the string nodes in for freeing their memory and other resources.
229 *
230 * @returns 0 or what ever non-zero return value pfnCallback returned
231 * when aborting the destruction.
232 * @param pStrSpace The space to insert it into.
233 * @param pfnCallback The callback.
234 * @param pvUser The user argument.
235 */
236RTDECL(int) RTStrSpaceDestroy(PRTSTRSPACE pStrSpace, PFNRTSTRSPACECALLBACK pfnCallback, void *pvUser)
237{
238 return KAVL_FN(Destroy)(pStrSpace, pfnCallback, pvUser);
239}
240RT_EXPORT_SYMBOL(RTStrSpaceDestroy);
241
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette