~ubuntu-branches/ubuntu/trusty/judy/trusty

1 by Theodore Y. Ts'o
Import upstream version 0.0.4
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
1.1.1 by Troy Heber
Import upstream version 1.0.1
24
#if (! (defined(JUDY1) || defined(JUDYL)))
25
#error:  One of -DJUDY1 or -DJUDYL must be specified.
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
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
//
1.1.1 by Troy Heber
Import upstream version 1.0.1
45
// This code is written recursively, at least at first, because thats much
46
// simpler.  Hope its fast enough.
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
47
48
#ifdef JUDY1
1.1.1 by Troy Heber
Import upstream version 1.0.1
49
FUNCTION Word_t Judy1FreeArray
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
50
#else
1.1.1 by Troy Heber
Import upstream version 1.0.1
51
FUNCTION Word_t JudyLFreeArray
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
52
#endif
1.1.1 by Troy Heber
Import upstream version 1.0.1
53
        (
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
54
	PPvoid_t  PPArray,	// array to free.
1.1.1 by Troy Heber
Import upstream version 1.0.1
55
	PJError_t PJError	// optional, for returning error info.
56
        )
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
57
{
58
	jpm_t	  jpm;		// local to accumulate free statistics.
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
// Zero jpm.jpm_Pop0 (meaning the array will be empty in a moment) for accurate
71
// logging in TRACEMI2.
72
73
	jpm.jpm_Pop0	      = 0;		// see above.
74
	jpm.jpm_TotalMemWords = 0;		// initialize memory freed.
75
1.1.1 by Troy Heber
Import upstream version 1.0.1
76
// 	Empty array:
77
78
	if (P_JLW(*PPArray) == (Pjlw_t) NULL) return(0);
79
80
// PROCESS TOP LEVEL "JRP" BRANCHES AND LEAF:
81
82
	if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
83
	{
84
	    Pjlw_t Pjlw = P_JLW(*PPArray);	// first word of leaf.
85
86
	    j__udyFreeJLW(Pjlw, Pjlw[0] + 1, &jpm);
87
	    *PPArray = (Pvoid_t) NULL;		// make an empty array.
88
	    return (-(jpm.jpm_TotalMemWords * cJU_BYTESPERWORD));  // see above.
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
89
	}
1.1.1 by Troy Heber
Import upstream version 1.0.1
90
	else
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
91
92
// Rootstate leaves:  just free the leaf:
93
94
// Common code for returning the amount of memory freed.
95
//
1.1.1 by Troy Heber
Import upstream version 1.0.1
96
// Note:  In a an ordinary LEAFW, pop0 = *PPArray[0].
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
97
//
98
// Accumulate (negative) words freed, while freeing objects.
99
// Return the positive bytes freed.
100
101
	{
102
	    Pjpm_t Pjpm	    = P_JPM(*PPArray);
103
	    Word_t TotalMem = Pjpm->jpm_TotalMemWords;
104
1.1.1 by Troy Heber
Import upstream version 1.0.1
105
	    j__udyFreeSM(&(Pjpm->jpm_JP), &jpm);  // recurse through tree.
106
	    j__udyFreeJPM(Pjpm, &jpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
107
108
// Verify the array was not corrupt.  This means that amount of memory freed
109
// (which is negative) is equal to the initial amount:
110
111
	    if (TotalMem + jpm.jpm_TotalMemWords)
112
	    {
113
		JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
114
		return(JERR);
115
	    }
116
117
	    *PPArray = (Pvoid_t) NULL;		// make an empty array.
118
	    return (TotalMem * cJU_BYTESPERWORD);
119
	}
120
121
} // Judy1FreeArray() / JudyLFreeArray()
122
123
124
// ****************************************************************************
125
// __ J U D Y   F R E E   S M
126
//
127
// Given a pointer to a JP, recursively visit and free (depth first) all nodes
128
// in a Judy array BELOW the JP, but not the JP itself.  Accumulate in *Pjpm
129
// the total words freed (as a negative value).  "SM" = State Machine.
130
//
131
// Note:  Corruption is not detected at this level because during a FreeArray,
1.1.1 by Troy Heber
Import upstream version 1.0.1
132
// if the code hasnt already core dumped, its better to remain silent, even
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
133
// if some memory has not been freed, than to bother the caller about the
134
// corruption.  TBD:  Is this true?  If not, must list all legitimate JPNULL
135
// and JPIMMED above first, and revert to returning bool_t (see 4.34).
136
1.1.1 by Troy Heber
Import upstream version 1.0.1
137
FUNCTION void j__udyFreeSM(
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
138
	Pjp_t	Pjp,		// top of Judy (top-state).
139
	Pjpm_t	Pjpm)		// to return words freed.
140
{
141
	Word_t	Pop1;
142
1.1.1 by Troy Heber
Import upstream version 1.0.1
143
	switch (JU_JPTYPE(Pjp))
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
144
	{
145
146
#ifdef JUDY1
147
148
// FULL EXPANSE -- nothing to free  for this jp_Type.
149
150
	case cJ1_JPFULLPOPU1:
151
	    break;
152
#endif
153
154
// JUDY BRANCH -- free the sub-tree depth first:
155
1.1.1 by Troy Heber
Import upstream version 1.0.1
156
// LINEAR BRANCH -- visit each JP in the JBLs list, then free the JBL:
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
157
//
158
// Note:  There are no null JPs in a JBL.
159
160
	case cJU_JPBRANCH_L:
161
	case cJU_JPBRANCH_L2:
162
	case cJU_JPBRANCH_L3:
163
#ifdef JU_64BIT
164
	case cJU_JPBRANCH_L4:
165
	case cJU_JPBRANCH_L5:
166
	case cJU_JPBRANCH_L6:
167
	case cJU_JPBRANCH_L7:
168
#endif // JU_64BIT
169
	{
170
	    Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
171
	    Word_t offset;
172
173
	    for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset)
1.1.1 by Troy Heber
Import upstream version 1.0.1
174
	        j__udyFreeSM((Pjbl->jbl_jp) + offset, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
175
1.1.1 by Troy Heber
Import upstream version 1.0.1
176
	    j__udyFreeJBL((Pjbl_t) (Pjp->jp_Addr), Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
177
	    break;
178
	}
179
180
181
// BITMAP BRANCH -- visit each JP in the JBBs list based on the bitmap, also
182
//
183
// Note:  There are no null JPs in a JBB.
184
185
	case cJU_JPBRANCH_B:
186
	case cJU_JPBRANCH_B2:
187
	case cJU_JPBRANCH_B3:
188
#ifdef JU_64BIT
189
	case cJU_JPBRANCH_B4:
190
	case cJU_JPBRANCH_B5:
191
	case cJU_JPBRANCH_B6:
192
	case cJU_JPBRANCH_B7:
193
#endif // JU_64BIT
194
	{
195
	    Word_t subexp;
196
	    Word_t offset;
197
	    Word_t jpcount;
198
199
	    Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
200
201
	    for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
202
	    {
1.1.1 by Troy Heber
Import upstream version 1.0.1
203
	        jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
204
205
	        if (jpcount)
206
	        {
207
		    for (offset = 0; offset < jpcount; ++offset)
208
		    {
1.1.1 by Troy Heber
Import upstream version 1.0.1
209
		       j__udyFreeSM(P_JP(JU_JBB_PJP(Pjbb, subexp)) + offset,
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
210
				    Pjpm);
211
		    }
1.1.1 by Troy Heber
Import upstream version 1.0.1
212
		    j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, subexp), jpcount, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
213
	        }
214
	    }
1.1.1 by Troy Heber
Import upstream version 1.0.1
215
	    j__udyFreeJBB((Pjbb_t) (Pjp->jp_Addr), Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
216
217
	    break;
218
	}
219
220
221
// UNCOMPRESSED BRANCH -- visit each JP in the JBU array, then free the JBU
222
// itself:
223
//
224
// Note:  Null JPs are handled during recursion at a lower state.
225
226
	case cJU_JPBRANCH_U:
227
	case cJU_JPBRANCH_U2:
228
	case cJU_JPBRANCH_U3:
229
#ifdef JU_64BIT
230
	case cJU_JPBRANCH_U4:
231
	case cJU_JPBRANCH_U5:
232
	case cJU_JPBRANCH_U6:
233
	case cJU_JPBRANCH_U7:
234
#endif // JU_64BIT
235
	{
236
	    Word_t offset;
237
	    Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
238
239
	    for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
1.1.1 by Troy Heber
Import upstream version 1.0.1
240
	        j__udyFreeSM((Pjbu->jbu_jp) + offset, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
241
1.1.1 by Troy Heber
Import upstream version 1.0.1
242
	    j__udyFreeJBU((Pjbu_t) (Pjp->jp_Addr), Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
243
	    break;
244
	}
245
246
247
// -- Cases below here terminate and do not recurse. --
248
249
250
// LINEAR LEAF -- just free the leaf; size is computed from jp_Type:
251
//
252
// Note:  cJU_JPLEAF1 is a special case, see discussion in ../Judy1/Judy1.h
253
1.1.1 by Troy Heber
Import upstream version 1.0.1
254
#if (defined(JUDYL) || (! defined(JU_64BIT)))
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
255
	case cJU_JPLEAF1:
1.1.1 by Troy Heber
Import upstream version 1.0.1
256
	    Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
257
	    j__udyFreeJLL1((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
258
	    break;
259
#endif
260
261
	case cJU_JPLEAF2:
1.1.1 by Troy Heber
Import upstream version 1.0.1
262
	    Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
263
	    j__udyFreeJLL2((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
264
	    break;
265
266
	case cJU_JPLEAF3:
1.1.1 by Troy Heber
Import upstream version 1.0.1
267
	    Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
268
	    j__udyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
269
	    break;
270
271
#ifdef JU_64BIT
272
	case cJU_JPLEAF4:
1.1.1 by Troy Heber
Import upstream version 1.0.1
273
	    Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
274
	    j__udyFreeJLL4((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
275
	    break;
276
277
	case cJU_JPLEAF5:
1.1.1 by Troy Heber
Import upstream version 1.0.1
278
	    Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
279
	    j__udyFreeJLL5((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
280
	    break;
281
282
	case cJU_JPLEAF6:
1.1.1 by Troy Heber
Import upstream version 1.0.1
283
	    Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
284
	    j__udyFreeJLL6((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
285
	    break;
286
287
	case cJU_JPLEAF7:
1.1.1 by Troy Heber
Import upstream version 1.0.1
288
	    Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
289
	    j__udyFreeJLL7((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
290
	    break;
291
#endif // JU_64BIT
292
293
294
// BITMAP LEAF -- free sub-expanse arrays of JPs, then free the JBB.
295
296
	case cJU_JPLEAF_B1:
297
	{
298
#ifdef JUDYL
299
	    Word_t subexp;
300
	    Word_t jpcount;
301
	    Pjlb_t Pjlb = P_JLB(Pjp->jp_Addr);
302
303
// Free the value areas in the bitmap leaf:
304
305
	    for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
306
	    {
1.1.1 by Troy Heber
Import upstream version 1.0.1
307
	        jpcount = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
308
309
	        if (jpcount)
1.1.1 by Troy Heber
Import upstream version 1.0.1
310
		    j__udyLFreeJV(JL_JLB_PVALUE(Pjlb, subexp), jpcount, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
311
	    }
312
#endif // JUDYL
313
1.1.1 by Troy Heber
Import upstream version 1.0.1
314
	    j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
315
	    break;
316
317
	} // case cJU_JPLEAF_B1
318
319
#ifdef JUDYL
320
321
322
// IMMED*:
323
//
324
// For JUDYL, all non JPIMMED_*_01s have a LeafV which must be freed:
325
326
	case cJU_JPIMMED_1_02:
327
	case cJU_JPIMMED_1_03:
328
#ifdef JU_64BIT
329
	case cJU_JPIMMED_1_04:
330
	case cJU_JPIMMED_1_05:
331
	case cJU_JPIMMED_1_06:
332
	case cJU_JPIMMED_1_07:
333
#endif
1.1.1 by Troy Heber
Import upstream version 1.0.1
334
	    Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_02 + 2;
335
	    j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
336
	    break;
337
338
#ifdef JU_64BIT
339
	case cJU_JPIMMED_2_02:
340
	case cJU_JPIMMED_2_03:
341
1.1.1 by Troy Heber
Import upstream version 1.0.1
342
	    Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_2_02 + 2;
343
	    j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
344
	    break;
345
346
	case cJU_JPIMMED_3_02:
1.1.1 by Troy Heber
Import upstream version 1.0.1
347
	    j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), 2, Pjpm);
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
348
	    break;
349
350
#endif // JU_64BIT
351
#endif // JUDYL
352
353
354
// OTHER JPNULL, JPIMMED, OR UNEXPECTED TYPE -- nothing to free for this type:
355
//
356
// Note:  Lump together no-op and invalid JP types; see function header
357
// comments.
358
359
	default: break;
360
1.1.1 by Troy Heber
Import upstream version 1.0.1
361
	} // switch (JU_JPTYPE(Pjp))
1 by Theodore Y. Ts'o
Import upstream version 0.0.4
362
1.1.1 by Troy Heber
Import upstream version 1.0.1
363
} // j__udyFreeSM()