~ubuntu-branches/ubuntu/lucid/judy/lucid

« back to all changes in this revision

Viewing changes to src/JudyCommon/JudyFreeArray.c

  • Committer: Bazaar Package Importer
  • Author(s): Theodore Y. Ts'o
  • Date: 2004-01-17 00:04:53 UTC
  • Revision ID: james.westby@ubuntu.com-20040117000453-d5sj6uoon2v1g4gf
Tags: upstream-0.0.4
ImportĀ upstreamĀ versionĀ 0.0.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
 
2
//
 
3
// This program is free software; you can redistribute it and/or modify it
 
4
// under the term of the GNU Lesser General Public License as published by the
 
5
// Free Software Foundation; either version 2 of the License, or (at your
 
6
// option) any later version.
 
7
//
 
8
// This program is distributed in the hope that it will be useful, but WITHOUT
 
9
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
10
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 
11
// for more details.
 
12
//
 
13
// You should have received a copy of the GNU Lesser General Public License
 
14
// along with this program; if not, write to the Free Software Foundation,
 
15
// Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
// _________________
 
17
 
 
18
// @(#) $Revision: 4.51 $ $Source: /judy/src/JudyCommon/JudyFreeArray.c $
 
19
//
 
20
// Judy1FreeArray() and JudyLFreeArray() functions for Judy1 and JudyL.
 
21
// Compile with one of -DJUDY1 or -DJUDYL.
 
22
// Return the number of bytes freed from the array.
 
23
 
 
24
#if (! (JUDY1 || JUDYL))
 
25
    Error:  One of -DJUDY1 or -DJUDYL must be specified.
 
26
#endif
 
27
 
 
28
#ifdef JUDY1
 
29
#include "Judy1.h"
 
30
#else
 
31
#include "JudyL.h"
 
32
#endif
 
33
 
 
34
#include "JudyPrivate1L.h"
 
35
 
 
36
DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);)
 
37
 
 
38
 
 
39
// ****************************************************************************
 
40
// J U D Y   1   F R E E   A R R A Y
 
41
// J U D Y   L   F R E E   A R R A Y
 
42
//
 
43
// See the Judy*(3C) manual entry for details.
 
44
//
 
45
// This code is written recursively, at least at first, because that's much
 
46
// simpler.  Hope it's fast enough.
 
47
 
 
48
#ifdef JUDY1
 
49
FUNCTION Word_t Judy1FreeArray(
 
50
#else
 
51
FUNCTION Word_t JudyLFreeArray(
 
52
#endif
 
53
        PPvoid_t  PPArray,      // array to free.
 
54
        PJError_t PJError)      // optional, for returning error info.
 
55
{
 
56
        jpm_t     jpm;          // local to accumulate free statistics.
 
57
        Word_t    JAPtype;      // JAP type part of *PPArray.
 
58
 
 
59
 
 
60
// CHECK FOR NULL POINTER (error by caller):
 
61
 
 
62
        if (PPArray == (PPvoid_t) NULL)
 
63
        {
 
64
            JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
 
65
            return(JERR);
 
66
        }
 
67
 
 
68
        DBGCODE(JudyCheckPop(*PPArray);)
 
69
 
 
70
 
 
71
// PROCESS TOP LEVEL "JAP" BRANCHES AND LEAVES:
 
72
//
 
73
// Zero jpm.jpm_Pop0 (meaning the array will be empty in a moment) for accurate
 
74
// logging in TRACEMI2.
 
75
 
 
76
        jpm.jpm_Pop0          = 0;              // see above.
 
77
        jpm.jpm_TotalMemWords = 0;              // initialize memory freed.
 
78
 
 
79
// Get pointer and type from array pointer:
 
80
 
 
81
        JAPtype = JAPTYPE(*PPArray);
 
82
 
 
83
        switch (JAPtype)
 
84
        {
 
85
 
 
86
// Empty array:
 
87
//
 
88
// Note:  It is an error to have a JAPtype for a JAPNULL with the rest of the
 
89
// pointer not being null.
 
90
 
 
91
        case cJU_JAPNULL:
 
92
        {
 
93
            if (P_JLW(*PPArray) == (Pjlw_t) NULL) return(0);
 
94
            break;  // invalid JAP, although possibly a valid non-Judy pointer.
 
95
        }
 
96
 
 
97
// Rootstate leaves:  just free the leaf:
 
98
 
 
99
// Common code for returning the amount of memory freed.
 
100
//
 
101
// Note:  In a an ordinary JAPLEAF, pop0 = *PPArray[0].
 
102
//
 
103
// Accumulate (negative) words freed, while freeing objects.
 
104
// Return the positive bytes freed.
 
105
 
 
106
        case cJU_JAPLEAF:
 
107
        {
 
108
            Pjlw_t Pjlw = P_JLW(*PPArray);      // first word of leaf.
 
109
 
 
110
            __JudyFreeJLW(Pjlw, Pjlw[0] + 1, &jpm);
 
111
            *PPArray = (Pvoid_t) NULL;          // make an empty array.
 
112
            return (-(jpm.jpm_TotalMemWords * cJU_BYTESPERWORD));  // see above.
 
113
        }
 
114
 
 
115
#if (LOW_POP && JUDYL)
 
116
        case cJL_JAPLEAF_POPU1:
 
117
        {
 
118
            Pjlw_t Pjlw= P_JLW(*PPArray);       // first word of leaf.
 
119
 
 
120
            __JudyFreeJLW(Pjlw, 1, &jpm);
 
121
            *PPArray = (Pvoid_t) NULL;          // make an empty array.
 
122
            return (-(jpm.jpm_TotalMemWords * cJU_BYTESPERWORD));  // see above.
 
123
        }
 
124
        case cJL_JAPLEAF_POPU2:
 
125
        {
 
126
            Pjlw_t Pjlw = P_JLW(*PPArray);      // first word of leaf.
 
127
 
 
128
            __JudyFreeJLW(Pjlw, 2, &jpm);
 
129
            *PPArray = (Pvoid_t) NULL;          // make an empty array.
 
130
            return (-(jpm.jpm_TotalMemWords * cJU_BYTESPERWORD));  // see above.
 
131
        }
 
132
#endif
 
133
 
 
134
        case cJU_JAPBRANCH:
 
135
        {
 
136
            Pjpm_t Pjpm     = P_JPM(*PPArray);
 
137
            Word_t TotalMem = Pjpm->jpm_TotalMemWords;
 
138
 
 
139
            __JudyFreeSM(&(Pjpm->jpm_JP), &jpm);  // recurse through tree.
 
140
            __JudyFreeJPM(Pjpm, &jpm);
 
141
 
 
142
// Verify the array was not corrupt.  This means that amount of memory freed
 
143
// (which is negative) is equal to the initial amount:
 
144
 
 
145
            if (TotalMem + jpm.jpm_TotalMemWords)
 
146
            {
 
147
                JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
 
148
                return(JERR);
 
149
            }
 
150
 
 
151
            *PPArray = (Pvoid_t) NULL;          // make an empty array.
 
152
            return (TotalMem * cJU_BYTESPERWORD);
 
153
        }
 
154
 
 
155
// No match above implies invalid root pointer (JAP):
 
156
 
 
157
        default: break;
 
158
 
 
159
        } // switch (JAPtype)
 
160
 
 
161
        JUDY1CODE(JU_SET_ERRNO(PJError, JU_ERRNO_NOTJUDY1);)
 
162
        JUDYLCODE(JU_SET_ERRNO(PJError, JU_ERRNO_NOTJUDYL);)
 
163
        return(JERR);
 
164
 
 
165
} // Judy1FreeArray() / JudyLFreeArray()
 
166
 
 
167
 
 
168
// ****************************************************************************
 
169
// __ J U D Y   F R E E   S M
 
170
//
 
171
// Given a pointer to a JP, recursively visit and free (depth first) all nodes
 
172
// in a Judy array BELOW the JP, but not the JP itself.  Accumulate in *Pjpm
 
173
// the total words freed (as a negative value).  "SM" = State Machine.
 
174
//
 
175
// Note:  Corruption is not detected at this level because during a FreeArray,
 
176
// if the code hasn't already core dumped, it's better to remain silent, even
 
177
// if some memory has not been freed, than to bother the caller about the
 
178
// corruption.  TBD:  Is this true?  If not, must list all legitimate JPNULL
 
179
// and JPIMMED above first, and revert to returning bool_t (see 4.34).
 
180
 
 
181
FUNCTION void __JudyFreeSM(
 
182
        Pjp_t   Pjp,            // top of Judy (top-state).
 
183
        Pjpm_t  Pjpm)           // to return words freed.
 
184
{
 
185
        Word_t  Pop1;
 
186
 
 
187
        switch (Pjp->jp_Type)
 
188
        {
 
189
 
 
190
#ifdef JUDY1
 
191
 
 
192
// FULL EXPANSE -- nothing to free  for this jp_Type.
 
193
 
 
194
        case cJ1_JPFULLPOPU1:
 
195
            break;
 
196
#endif
 
197
 
 
198
// JUDY BRANCH -- free the sub-tree depth first:
 
199
 
 
200
// LINEAR BRANCH -- visit each JP in the JBL's list, then free the JBL:
 
201
//
 
202
// Note:  There are no null JPs in a JBL.
 
203
 
 
204
        case cJU_JPBRANCH_L:
 
205
        case cJU_JPBRANCH_L2:
 
206
        case cJU_JPBRANCH_L3:
 
207
#ifdef JU_64BIT
 
208
        case cJU_JPBRANCH_L4:
 
209
        case cJU_JPBRANCH_L5:
 
210
        case cJU_JPBRANCH_L6:
 
211
        case cJU_JPBRANCH_L7:
 
212
#endif // JU_64BIT
 
213
        {
 
214
            Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
 
215
            Word_t offset;
 
216
 
 
217
            for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset)
 
218
                __JudyFreeSM((Pjbl->jbl_jp) + offset, Pjpm);
 
219
 
 
220
            __JudyFreeJBL((Pjbl_t) (Pjp->jp_Addr), Pjpm);
 
221
            break;
 
222
        }
 
223
 
 
224
 
 
225
// BITMAP BRANCH -- visit each JP in the JBBs list based on the bitmap, also
 
226
//
 
227
// Note:  There are no null JPs in a JBB.
 
228
 
 
229
        case cJU_JPBRANCH_B:
 
230
        case cJU_JPBRANCH_B2:
 
231
        case cJU_JPBRANCH_B3:
 
232
#ifdef JU_64BIT
 
233
        case cJU_JPBRANCH_B4:
 
234
        case cJU_JPBRANCH_B5:
 
235
        case cJU_JPBRANCH_B6:
 
236
        case cJU_JPBRANCH_B7:
 
237
#endif // JU_64BIT
 
238
        {
 
239
            Word_t subexp;
 
240
            Word_t offset;
 
241
            Word_t jpcount;
 
242
 
 
243
            Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
 
244
 
 
245
            for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
 
246
            {
 
247
                jpcount = __JudyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
 
248
 
 
249
                if (jpcount)
 
250
                {
 
251
                    for (offset = 0; offset < jpcount; ++offset)
 
252
                    {
 
253
                       __JudyFreeSM(P_JP(JU_JBB_PJP(Pjbb, subexp)) + offset,
 
254
                                    Pjpm);
 
255
                    }
 
256
                    __JudyFreeJBBJP(JU_JBB_PJP(Pjbb, subexp), jpcount, Pjpm);
 
257
                }
 
258
            }
 
259
            __JudyFreeJBB((Pjbb_t) (Pjp->jp_Addr), Pjpm);
 
260
 
 
261
            break;
 
262
        }
 
263
 
 
264
 
 
265
// UNCOMPRESSED BRANCH -- visit each JP in the JBU array, then free the JBU
 
266
// itself:
 
267
//
 
268
// Note:  Null JPs are handled during recursion at a lower state.
 
269
 
 
270
        case cJU_JPBRANCH_U:
 
271
        case cJU_JPBRANCH_U2:
 
272
        case cJU_JPBRANCH_U3:
 
273
#ifdef JU_64BIT
 
274
        case cJU_JPBRANCH_U4:
 
275
        case cJU_JPBRANCH_U5:
 
276
        case cJU_JPBRANCH_U6:
 
277
        case cJU_JPBRANCH_U7:
 
278
#endif // JU_64BIT
 
279
        {
 
280
            Word_t offset;
 
281
            Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
 
282
 
 
283
            for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
 
284
                __JudyFreeSM((Pjbu->jbu_jp) + offset, Pjpm);
 
285
 
 
286
            __JudyFreeJBU((Pjbu_t) (Pjp->jp_Addr), Pjpm);
 
287
            break;
 
288
        }
 
289
 
 
290
 
 
291
// -- Cases below here terminate and do not recurse. --
 
292
 
 
293
 
 
294
// LINEAR LEAF -- just free the leaf; size is computed from jp_Type:
 
295
//
 
296
// Note:  cJU_JPLEAF1 is a special case, see discussion in ../Judy1/Judy1.h
 
297
 
 
298
#if (JUDYL || (! JU_64BIT ))
 
299
        case cJU_JPLEAF1:
 
300
            Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
 
301
            __JudyFreeJLL1((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
 
302
            break;
 
303
#endif
 
304
 
 
305
        case cJU_JPLEAF2:
 
306
            Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
 
307
            __JudyFreeJLL2((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
 
308
            break;
 
309
 
 
310
        case cJU_JPLEAF3:
 
311
            Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
 
312
            __JudyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
 
313
            break;
 
314
 
 
315
#ifdef JU_64BIT
 
316
        case cJU_JPLEAF4:
 
317
            Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
 
318
            __JudyFreeJLL4((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
 
319
            break;
 
320
 
 
321
        case cJU_JPLEAF5:
 
322
            Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
 
323
            __JudyFreeJLL5((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
 
324
            break;
 
325
 
 
326
        case cJU_JPLEAF6:
 
327
            Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
 
328
            __JudyFreeJLL6((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
 
329
            break;
 
330
 
 
331
        case cJU_JPLEAF7:
 
332
            Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
 
333
            __JudyFreeJLL7((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
 
334
            break;
 
335
#endif // JU_64BIT
 
336
 
 
337
 
 
338
// BITMAP LEAF -- free sub-expanse arrays of JPs, then free the JBB.
 
339
 
 
340
        case cJU_JPLEAF_B1:
 
341
        {
 
342
#ifdef JUDYL
 
343
            Word_t subexp;
 
344
            Word_t jpcount;
 
345
            Pjlb_t Pjlb = P_JLB(Pjp->jp_Addr);
 
346
 
 
347
// Free the value areas in the bitmap leaf:
 
348
 
 
349
            for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
 
350
            {
 
351
                jpcount = __JudyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
 
352
 
 
353
                if (jpcount)
 
354
                    __JudyLFreeJV(JL_JLB_PVALUE(Pjlb, subexp), jpcount, Pjpm);
 
355
            }
 
356
#endif // JUDYL
 
357
 
 
358
            __JudyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm);
 
359
            break;
 
360
 
 
361
        } // case cJU_JPLEAF_B1
 
362
 
 
363
#ifdef JUDYL
 
364
 
 
365
 
 
366
// IMMED*:
 
367
//
 
368
// For JUDYL, all non JPIMMED_*_01s have a LeafV which must be freed:
 
369
 
 
370
        case cJU_JPIMMED_1_02:
 
371
        case cJU_JPIMMED_1_03:
 
372
#ifdef JU_64BIT
 
373
        case cJU_JPIMMED_1_04:
 
374
        case cJU_JPIMMED_1_05:
 
375
        case cJU_JPIMMED_1_06:
 
376
        case cJU_JPIMMED_1_07:
 
377
#endif
 
378
            Pop1 = Pjp->jp_Type - cJU_JPIMMED_1_02 + 2;
 
379
            __JudyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
 
380
            break;
 
381
 
 
382
#ifdef JU_64BIT
 
383
        case cJU_JPIMMED_2_02:
 
384
        case cJU_JPIMMED_2_03:
 
385
 
 
386
            Pop1 = Pjp->jp_Type - cJU_JPIMMED_2_02 + 2;
 
387
            __JudyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
 
388
            break;
 
389
 
 
390
        case cJU_JPIMMED_3_02:
 
391
            __JudyLFreeJV((Pjv_t) (Pjp->jp_Addr), 2, Pjpm);
 
392
            break;
 
393
 
 
394
#endif // JU_64BIT
 
395
#endif // JUDYL
 
396
 
 
397
 
 
398
// OTHER JPNULL, JPIMMED, OR UNEXPECTED TYPE -- nothing to free for this type:
 
399
//
 
400
// Note:  Lump together no-op and invalid JP types; see function header
 
401
// comments.
 
402
 
 
403
        default: break;
 
404
 
 
405
        } // switch (Pjp -> jp_Type)
 
406
 
 
407
} // __JudyFreeSM()