Added and working! Array module 1.65 is a go for release!

This commit is contained in:
Twilight Suzuka
2006-01-07 04:36:12 +00:00
parent e8a4b46cc5
commit a3572f7206
121 changed files with 80794 additions and 0 deletions

View File

@ -0,0 +1,551 @@
#ifndef _JUDY1_INCLUDED
#define _JUDY1_INCLUDED
// _________________
//
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
// ****************************************************************************
// JUDY1 -- SMALL/LARGE AND/OR CLUSTERED/SPARSE BIT ARRAYS
//
// -by-
//
// Douglas L. Baskins
// doug@sourcejudy.com
//
// Judy arrays are designed to be used instead of arrays. The performance
// suggests the reason why Judy arrays are thought of as arrays, instead of
// trees. They are remarkably memory efficient at all populations.
// Implemented as a hybrid digital tree (but really a state machine, see
// below), Judy arrays feature fast insert/retrievals, fast near neighbor
// searching, and contain a population tree for extremely fast ordinal related
// retrievals.
//
// CONVENTIONS:
//
// - The comments here refer to 32-bit [64-bit] systems.
//
// - BranchL, LeafL refer to linear branches and leaves (small populations),
// except LeafL does not actually appear as such; rather, Leaf1..3 [Leaf1..7]
// is used to represent leaf Index sizes, and LeafW refers to a Leaf with
// full (long) word Indexes, which is also a type of linear leaf. Note that
// root-level LeafW (Leaf4 [Leaf8]) leaves are also called LEAFW.
//
// - BranchB, LeafB1 refer to bitmap branches and leaves (intermediate
// populations).
//
// - BranchU refers to uncompressed branches. An uncompressed branch has 256
// JPs, some of which could be null. Note: All leaves are compressed (and
// sorted), or else an expanse is full (FullPopu), so there is no LeafU
// equivalent to BranchU.
//
// - "Popu" is short for "Population".
// - "Pop1" refers to actual population (base 1).
// - "Pop0" refers to Pop1 - 1 (base 0), the way populations are stored in data
// structures.
//
// - Branches and Leaves are both named by the number of bytes in their Pop0
// field. In the case of Leaves, the same number applies to the Index sizes.
//
// - The representation of many numbers as hex is a relatively safe and
// portable way to get desired bitpatterns as unsigned longs.
//
// - Some preprocessors cant handle single apostrophe characters within
// #ifndef code, so here, use delete all instead.
#include "JudyPrivate.h" // includes Judy.h in turn.
#include "JudyPrivateBranch.h"
// ****************************************************************************
// JUDY1 ROOT POINTER (JRP) AND JUDY1 POINTER (JP) TYPE FIELDS
// ****************************************************************************
//
// The following enum lists all possible JP Type fields.
typedef enum // uint8_t -- but C does not support this type of enum.
{
// JP NULL TYPES:
//
// There is a series of cJ1_JPNULL* Types because each one pre-records a
// different Index Size for when the first Index is inserted in the previously
// null JP. They must start >= 8 (three bits).
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPNULL1 = 1,
// Index Size 1[1] byte when 1 Index inserted.
cJ1_JPNULL2, // Index Size 2[2] bytes when 1 Index inserted.
cJ1_JPNULL3, // Index Size 3[3] bytes when 1 Index inserted.
#ifndef JU_64BIT
#define cJ1_JPNULLMAX cJ1_JPNULL3
#else
cJ1_JPNULL4, // Index Size 4[4] bytes when 1 Index inserted.
cJ1_JPNULL5, // Index Size 5[5] bytes when 1 Index inserted.
cJ1_JPNULL6, // Index Size 6[6] bytes when 1 Index inserted.
cJ1_JPNULL7, // Index Size 7[7] bytes when 1 Index inserted.
#define cJ1_JPNULLMAX cJ1_JPNULL7
#endif
// JP BRANCH TYPES:
//
// Note: There are no state-1 branches; only leaves reside at state 1.
// Linear branches:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPBRANCH_L2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPBRANCH_L3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPBRANCH_L4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPBRANCH_L5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPBRANCH_L6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPBRANCH_L7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
cJ1_JPBRANCH_L, // note: DcdPopO field not used.
// Bitmap branches:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPBRANCH_B2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPBRANCH_B3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPBRANCH_B4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPBRANCH_B5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPBRANCH_B6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPBRANCH_B7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
cJ1_JPBRANCH_B, // note: DcdPopO field not used.
// Uncompressed branches:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPBRANCH_U2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPBRANCH_U3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPBRANCH_U4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPBRANCH_U5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPBRANCH_U6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPBRANCH_U7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
cJ1_JPBRANCH_U, // note: DcdPopO field not used.
// JP LEAF TYPES:
// Linear leaves:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
//
// Note: There is no cJ1_JPLEAF1 for 64-bit for a subtle reason. An immediate
// JP can hold 15 1-byte Indexes, and a bitmap leaf would be used for 17
// Indexes, so rather than support a linear leaf for only the case of exactly
// 16 Indexes, a bitmap leaf is used in that case. See also below regarding
// cJ1_LEAF1_MAXPOP1 on 64-bit systems.
//
// Note: There is no full-word (4-byte [8-byte]) Index leaf under a JP because
// non-root-state leaves only occur under branches that decode at least one
// byte. Full-word, root-state leaves are under a JRP, not a JP. However, in
// the code a "fake" JP can be created temporarily above a root-state leaf.
#ifndef JU_64BIT // 32-bit only; see above.
cJ1_JPLEAF1, // 1 byte Pop0, 2 bytes Dcd.
#endif
cJ1_JPLEAF2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPLEAF3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPLEAF4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPLEAF5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPLEAF6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPLEAF7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
// Bitmap leaf; Index Size == 1:
//
// Note: These are currently only supported at state 1. At other states the
// bitmap would grow from 256 to 256^2, 256^3, ... bits, which would not be
// efficient..
cJ1_JPLEAF_B1, // 1[1] byte Pop0, 2[6] bytes Dcd.
// Full population; Index Size == 1 virtual leaf:
//
// Note: These are currently only supported at state 1. At other states they
// could be used, but they would be rare and the savings are dubious.
cJ1_JPFULLPOPU1, // 1[1] byte Pop0, 2[6] bytes Dcd.
#ifdef notdef // for future enhancements
cJ1_JPFULLPOPU1m1, // Full Population - 1
cJ1_JPFULLPOPU1m2, // Full Population - 2
cJ1_JPFULLPOPU1m3, // Full Population - 3
cJ1_JPFULLPOPU1m4, // Full Population - 4
cJ1_JPFULLPOPU1m5, // Full Population - 5
cJ1_JPFULLPOPU1m6, // Full Population - 6
cJ1_JPFULLPOPU1m7, // Full Population - 7
#ifdef JU_64BIT
cJ1_JPFULLPOPU1m8, // Full Population - 8
cJ1_JPFULLPOPU1m9, // Full Population - 9
cJ1_JPFULLPOPU1m10, // Full Population - 10
cJ1_JPFULLPOPU1m11, // Full Population - 11
cJ1_JPFULLPOPU1m12, // Full Population - 12
cJ1_JPFULLPOPU1m13, // Full Population - 13
cJ1_JPFULLPOPU1m14, // Full Population - 14
cJ1_JPFULLPOPU1m15, // Full Population - 15
#endif
#endif // notdef -- for future enhancements
// JP IMMEDIATES; leaves (Indexes) stored inside a JP:
//
// The second numeric suffix is the Pop1 for each type. As the Index Size
// increases, the maximum possible population decreases.
//
// Note: These Types must be in sequential order in each group (Index Size),
// and the groups in correct order too, for doing relative calculations between
// them. For example, since these Types enumerate the Pop1 values (unlike
// other JP Types where there is a Pop0 value in the JP), the maximum Pop1 for
// each Index Size is computable.
cJ1_JPIMMED_1_01, // Index Size = 1, Pop1 = 1.
cJ1_JPIMMED_2_01, // Index Size = 2, Pop1 = 1.
cJ1_JPIMMED_3_01, // Index Size = 3, Pop1 = 1.
#ifdef JU_64BIT
cJ1_JPIMMED_4_01, // Index Size = 4, Pop1 = 1.
cJ1_JPIMMED_5_01, // Index Size = 5, Pop1 = 1.
cJ1_JPIMMED_6_01, // Index Size = 6, Pop1 = 1.
cJ1_JPIMMED_7_01, // Index Size = 7, Pop1 = 1.
#endif
cJ1_JPIMMED_1_02, // Index Size = 1, Pop1 = 2.
cJ1_JPIMMED_1_03, // Index Size = 1, Pop1 = 3.
cJ1_JPIMMED_1_04, // Index Size = 1, Pop1 = 4.
cJ1_JPIMMED_1_05, // Index Size = 1, Pop1 = 5.
cJ1_JPIMMED_1_06, // Index Size = 1, Pop1 = 6.
cJ1_JPIMMED_1_07, // Index Size = 1, Pop1 = 7.
#ifdef JU_64BIT
cJ1_JPIMMED_1_08, // Index Size = 1, Pop1 = 8.
cJ1_JPIMMED_1_09, // Index Size = 1, Pop1 = 9.
cJ1_JPIMMED_1_10, // Index Size = 1, Pop1 = 10.
cJ1_JPIMMED_1_11, // Index Size = 1, Pop1 = 11.
cJ1_JPIMMED_1_12, // Index Size = 1, Pop1 = 12.
cJ1_JPIMMED_1_13, // Index Size = 1, Pop1 = 13.
cJ1_JPIMMED_1_14, // Index Size = 1, Pop1 = 14.
cJ1_JPIMMED_1_15, // Index Size = 1, Pop1 = 15.
#endif
cJ1_JPIMMED_2_02, // Index Size = 2, Pop1 = 2.
cJ1_JPIMMED_2_03, // Index Size = 2, Pop1 = 3.
#ifdef JU_64BIT
cJ1_JPIMMED_2_04, // Index Size = 2, Pop1 = 4.
cJ1_JPIMMED_2_05, // Index Size = 2, Pop1 = 5.
cJ1_JPIMMED_2_06, // Index Size = 2, Pop1 = 6.
cJ1_JPIMMED_2_07, // Index Size = 2, Pop1 = 7.
#endif
cJ1_JPIMMED_3_02, // Index Size = 3, Pop1 = 2.
#ifdef JU_64BIT
cJ1_JPIMMED_3_03, // Index Size = 3, Pop1 = 3.
cJ1_JPIMMED_3_04, // Index Size = 3, Pop1 = 4.
cJ1_JPIMMED_3_05, // Index Size = 3, Pop1 = 5.
cJ1_JPIMMED_4_02, // Index Size = 4, Pop1 = 2.
cJ1_JPIMMED_4_03, // Index Size = 4, Pop1 = 3.
cJ1_JPIMMED_5_02, // Index Size = 5, Pop1 = 2.
cJ1_JPIMMED_5_03, // Index Size = 3, Pop1 = 3.
cJ1_JPIMMED_6_02, // Index Size = 6, Pop1 = 2.
cJ1_JPIMMED_7_02, // Index Size = 7, Pop1 = 2.
#endif
// This special Type is merely a sentinel for doing relative calculations.
// This value should not be used in switch statements (to avoid allocating code
// for it), which is also why it appears at the end of the enum list.
cJ1_JPIMMED_CAP
} jp1_Type_t;
// RELATED VALUES:
//
// Index Size (state) for leaf JP, and JP type based on Index Size (state):
#ifndef JU_64BIT // 32-bit
#define J1_LEAFINDEXSIZE(jpType) ((jpType) - cJ1_JPLEAF1 + 1)
#define J1_LEAFTYPE(IndexSize) ((IndexSize) + cJ1_JPLEAF1 - 1)
#else
#define J1_LEAFINDEXSIZE(jpType) ((jpType) - cJ1_JPLEAF2 + 2)
#define J1_LEAFTYPE(IndexSize) ((IndexSize) + cJ1_JPLEAF2 - 2)
#endif
// ****************************************************************************
// JUDY1 POINTER (JP) -- RELATED MACROS AND CONSTANTS
// ****************************************************************************
// MAXIMUM POPULATIONS OF LINEAR LEAVES:
//
// Allow up to 2 cache lines per leaf, with N bytes per index.
//
// J_1_MAXB is the maximum number of bytes (sort of) to allocate per leaf.
// ALLOCSIZES is defined here, not there, for single-point control of these key
// definitions. See JudyTables.c for "TERMINATOR".
#define J_1_MAXB (sizeof(Word_t) * 32)
#define ALLOCSIZES { 3, 5, 7, 11, 15, 23, 32, 47, 64, TERMINATOR } // in words.
#define cJ1_LEAF1_MAXWORDS 5 // Leaf1 max alloc size in words.
// Under JRP (root-state leaves):
//
// Includes a count (Population) word.
//
// Under JP (non-root-state leaves), which have no count (Population) words:
//
// When a 1-byte index leaf grows above cJ1_LEAF1_MAXPOP1 Indexes (bytes),
// the memory chunk required grows to a size where a bitmap is just as
// efficient, so use a bitmap instead for all greater Populations, on both
// 32-bit and 64-bit systems. However, on a 32-bit system this occurs upon
// going from 6 to 8 words (24 to 32 bytes) in the memory chunk, but on a
// 64-bit system this occurs upon going from 2 to 4 words (16 to 32 bytes). It
// would be silly to go from a 15-Index Immediate JP to a 16-Index linear leaf
// to a 17-Index bitmap leaf, so just use a bitmap leaf for 16+ Indexes, which
// means set cJ1_LEAF1_MAXPOP1 to cJ1_IMMED1_MAXPOP1 (15) to cause the
// transition at that point.
//
// Note: cJ1_LEAF1_MAXPOP1 is not used on 64-bit systems.
#ifndef JU_64BIT // 32-bit
#define cJ1_LEAF1_MAXPOP1 (cJ1_LEAF1_MAXWORDS * cJU_BYTESPERWORD)
#define cJ1_LEAF2_MAXPOP1 (J_1_MAXB / 2)
#define cJ1_LEAF3_MAXPOP1 (J_1_MAXB / 3)
#define cJ1_LEAFW_MAXPOP1 ((J_1_MAXB - cJU_BYTESPERWORD) / cJU_BYTESPERWORD)
#else // 64-bit
// #define cJ1_LEAF1_MAXPOP1 // no LEAF1 in 64-bit.
#define cJ1_LEAF2_MAXPOP1 (J_1_MAXB / 2)
#define cJ1_LEAF3_MAXPOP1 (J_1_MAXB / 3)
#define cJ1_LEAF4_MAXPOP1 (J_1_MAXB / 4)
#define cJ1_LEAF5_MAXPOP1 (J_1_MAXB / 5)
#define cJ1_LEAF6_MAXPOP1 (J_1_MAXB / 6)
#define cJ1_LEAF7_MAXPOP1 (J_1_MAXB / 7)
#define cJ1_LEAFW_MAXPOP1 ((J_1_MAXB - cJU_BYTESPERWORD) / cJU_BYTESPERWORD)
#endif
// MAXIMUM POPULATIONS OF IMMEDIATE JPs:
//
// These specify the maximum Population of immediate JPs with various Index
// Sizes (== sizes of remaining undecoded Index bits).
#define cJ1_IMMED1_MAXPOP1 ((sizeof(jp_t) - 1) / 1) // 7 [15].
#define cJ1_IMMED2_MAXPOP1 ((sizeof(jp_t) - 1) / 2) // 3 [7].
#define cJ1_IMMED3_MAXPOP1 ((sizeof(jp_t) - 1) / 3) // 2 [5].
#ifdef JU_64BIT
#define cJ1_IMMED4_MAXPOP1 ((sizeof(jp_t) - 1) / 4) // [3].
#define cJ1_IMMED5_MAXPOP1 ((sizeof(jp_t) - 1) / 5) // [3].
#define cJ1_IMMED6_MAXPOP1 ((sizeof(jp_t) - 1) / 6) // [2].
#define cJ1_IMMED7_MAXPOP1 ((sizeof(jp_t) - 1) / 7) // [2].
#endif
// ****************************************************************************
// JUDY1 BITMAP LEAF (J1LB) SUPPORT
// ****************************************************************************
#define J1_JLB_BITMAP(Pjlb,Subexp) ((Pjlb)->j1lb_Bitmap[Subexp])
typedef struct J__UDY1_BITMAP_LEAF
{
BITMAPL_t j1lb_Bitmap[cJU_NUMSUBEXPL];
} j1lb_t, * Pj1lb_t;
// ****************************************************************************
// MEMORY ALLOCATION SUPPORT
// ****************************************************************************
// ARRAY-GLOBAL INFORMATION:
//
// At the cost of an occasional additional cache fill, this object, which is
// pointed at by a JRP and in turn points to a JP_BRANCH*, carries array-global
// information about a Judy1 array that has sufficient population to amortize
// the cost. The jpm_Pop0 field prevents having to add up the total population
// for the array in insert, delete, and count code. The jpm_JP field prevents
// having to build a fake JP for entry to a state machine; however, the
// jp_DcdPopO field in jpm_JP, being one byte too small, is not used.
//
// Note: Struct fields are ordered to keep "hot" data in the first 8 words
// (see left-margin comments) for machines with 8-word cache lines, and to keep
// sub-word fields together for efficient packing.
typedef struct J_UDY1_POPULATION_AND_MEMORY
{
/* 1 */ Word_t jpm_Pop0; // total population-1 in array.
/* 2 */ jp_t jpm_JP; // JP to first branch; see above.
/* 4 */ Word_t jpm_LastUPop0; // last jpm_Pop0 when convert to BranchU
// Note: Field names match PJError_t for convenience in macros:
/* 7 */ char je_Errno; // one of the enums in Judy.h.
/* 7/8 */ int je_ErrID; // often an internal source line number.
/* 8/9 */ Word_t jpm_TotalMemWords; // words allocated in array.
} j1pm_t, *Pj1pm_t;
// TABLES FOR DETERMINING IF LEAVES HAVE ROOM TO GROW:
//
// These tables indicate if a given memory chunk can support growth of a given
// object into wasted (rounded-up) memory in the chunk. This violates the
// hiddenness of the JudyMalloc code.
//
// Also define macros to hide the details in the code using these tables.
#ifndef JU_64BIT
extern const uint8_t j__1_Leaf1PopToWords[cJ1_LEAF1_MAXPOP1 + 1];
#endif
extern const uint8_t j__1_Leaf2PopToWords[cJ1_LEAF2_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf3PopToWords[cJ1_LEAF3_MAXPOP1 + 1];
#ifdef JU_64BIT
extern const uint8_t j__1_Leaf4PopToWords[cJ1_LEAF4_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf5PopToWords[cJ1_LEAF5_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf6PopToWords[cJ1_LEAF6_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf7PopToWords[cJ1_LEAF7_MAXPOP1 + 1];
#endif
extern const uint8_t j__1_LeafWPopToWords[cJ1_LEAFW_MAXPOP1 + 1];
// Check if increase of population will fit in same leaf:
#ifndef JU_64BIT
#define J1_LEAF1GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF1_MAXPOP1, j__1_Leaf1PopToWords)
#endif
#define J1_LEAF2GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF2_MAXPOP1, j__1_Leaf2PopToWords)
#define J1_LEAF3GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF3_MAXPOP1, j__1_Leaf3PopToWords)
#ifdef JU_64BIT
#define J1_LEAF4GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF4_MAXPOP1, j__1_Leaf4PopToWords)
#define J1_LEAF5GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF5_MAXPOP1, j__1_Leaf5PopToWords)
#define J1_LEAF6GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF6_MAXPOP1, j__1_Leaf6PopToWords)
#define J1_LEAF7GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF7_MAXPOP1, j__1_Leaf7PopToWords)
#endif
#define J1_LEAFWGROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAFW_MAXPOP1, j__1_LeafWPopToWords)
#ifndef JU_64BIT
#define J1_LEAF1POPTOWORDS(Pop1) (j__1_Leaf1PopToWords[Pop1])
#endif
#define J1_LEAF2POPTOWORDS(Pop1) (j__1_Leaf2PopToWords[Pop1])
#define J1_LEAF3POPTOWORDS(Pop1) (j__1_Leaf3PopToWords[Pop1])
#ifdef JU_64BIT
#define J1_LEAF4POPTOWORDS(Pop1) (j__1_Leaf4PopToWords[Pop1])
#define J1_LEAF5POPTOWORDS(Pop1) (j__1_Leaf5PopToWords[Pop1])
#define J1_LEAF6POPTOWORDS(Pop1) (j__1_Leaf6PopToWords[Pop1])
#define J1_LEAF7POPTOWORDS(Pop1) (j__1_Leaf7PopToWords[Pop1])
#endif
#define J1_LEAFWPOPTOWORDS(Pop1) (j__1_LeafWPopToWords[Pop1])
// FUNCTIONS TO ALLOCATE OBJECTS:
Pj1pm_t j__udy1AllocJ1PM(void); // constant size.
Pjbl_t j__udy1AllocJBL( Pj1pm_t); // constant size.
Pjbb_t j__udy1AllocJBB( Pj1pm_t); // constant size.
Pjp_t j__udy1AllocJBBJP(Word_t, Pj1pm_t);
Pjbu_t j__udy1AllocJBU( Pj1pm_t); // constant size.
#ifndef JU_64BIT
Pjll_t j__udy1AllocJLL1( Word_t, Pj1pm_t);
#endif
Pjll_t j__udy1AllocJLL2( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL3( Word_t, Pj1pm_t);
#ifdef JU_64BIT
Pjll_t j__udy1AllocJLL4( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL5( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL6( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL7( Word_t, Pj1pm_t);
#endif
Pjlw_t j__udy1AllocJLW( Word_t ); // no Pj1pm needed.
Pj1lb_t j__udy1AllocJLB1( Pj1pm_t); // constant size.
// FUNCTIONS TO FREE OBJECTS:
void j__udy1FreeJ1PM( Pj1pm_t, Pj1pm_t); // constant size.
void j__udy1FreeJBL( Pjbl_t, Pj1pm_t); // constant size.
void j__udy1FreeJBB( Pjbb_t, Pj1pm_t); // constant size.
void j__udy1FreeJBBJP(Pjp_t, Word_t, Pj1pm_t);
void j__udy1FreeJBU( Pjbu_t, Pj1pm_t); // constant size.
#ifndef JU_64BIT
void j__udy1FreeJLL1( Pjll_t, Word_t, Pj1pm_t);
#endif
void j__udy1FreeJLL2( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL3( Pjll_t, Word_t, Pj1pm_t);
#ifdef JU_64BIT
void j__udy1FreeJLL4( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL5( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL6( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL7( Pjll_t, Word_t, Pj1pm_t);
#endif
void j__udy1FreeJLW( Pjlw_t, Word_t, Pj1pm_t);
void j__udy1FreeJLB1( Pj1lb_t, Pj1pm_t); // constant size.
void j__udy1FreeSM( Pjp_t, Pj1pm_t); // everything below Pjp.
#endif // ! _JUDY1_INCLUDED

View File

@ -0,0 +1,954 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy*ByCount() function for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
//
// Compile with -DNOSMARTJBB, -DNOSMARTJBU, and/or -DNOSMARTJLB to build a
// version with cache line optimizations deleted, for testing.
//
// Judy*ByCount() is a conceptual although not literal inverse of Judy*Count().
// Judy*Count() takes a pair of Indexes, and allows finding the ordinal of a
// given Index (that is, its position in the list of valid indexes from the
// beginning) as a degenerate case, because in general the count between two
// Indexes, inclusive, is not always just the difference in their ordinals.
// However, it suffices for Judy*ByCount() to simply be an ordinal-to-Index
// mapper.
//
// Note: Like Judy*Count(), this code must "count sideways" in branches, which
// can result in a lot of cache line fills. However, unlike Judy*Count(), this
// code does not receive a specific Index, hence digit, where to start in each
// branch, so it cant accurately calculate cache line fills required in each
// direction. The best it can do is an approximation based on the total
// population of the expanse (pop1 from Pjp) and the ordinal of the target
// Index (see SETOFFSET()) within the expanse.
//
// Compile with -DSMARTMETRICS to obtain global variables containing smart
// cache line metrics. Note: Dont turn this on simultaneously for this file
// and JudyCount.c because they export the same globals.
// ****************************************************************************
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// These are imported from JudyCount.c:
//
// TBD: Should this be in common code? Exported from a header file?
#ifdef JUDY1
extern Word_t j__udy1JPPop1(const Pjp_t Pjp);
#define j__udyJPPop1 j__udy1JPPop1
#else
extern Word_t j__udyLJPPop1(const Pjp_t Pjp);
#define j__udyJPPop1 j__udyLJPPop1
#endif
// Avoid duplicate symbols since this file is multi-compiled:
#ifdef SMARTMETRICS
#ifdef JUDY1
Word_t jbb_upward = 0; // counts of directions taken:
Word_t jbb_downward = 0;
Word_t jbu_upward = 0;
Word_t jbu_downward = 0;
Word_t jlb_upward = 0;
Word_t jlb_downward = 0;
#else
extern Word_t jbb_upward;
extern Word_t jbb_downward;
extern Word_t jbu_upward;
extern Word_t jbu_downward;
extern Word_t jlb_upward;
extern Word_t jlb_downward;
#endif
#endif
// ****************************************************************************
// J U D Y 1 B Y C O U N T
// J U D Y L B Y C O U N T
//
// See the manual entry.
#ifdef JUDY1
FUNCTION int Judy1ByCount
#else
FUNCTION PPvoid_t JudyLByCount
#endif
(
Pcvoid_t PArray, // root pointer to first branch/leaf in SM.
Word_t Count, // ordinal of Index to find, 1..MAX.
Word_t * PIndex, // to return found Index.
PJError_t PJError // optional, for returning error info.
)
{
Word_t Count0; // Count, base-0, to match pop0.
Word_t state; // current state in SM.
Word_t pop1; // of current branch or leaf, or of expanse.
Word_t pop1lower; // pop1 of expanses (JPs) below that for Count.
Word_t digit; // current word in branch.
Word_t jpcount; // JPs in a BranchB subexpanse.
long jpnum; // JP number in a branch (base 0).
long subexp; // for stepping through layer 1 (subexpanses).
int offset; // index ordinal within a leaf, base 0.
Pjp_t Pjp; // current JP in branch.
Pjll_t Pjll; // current Judy linear leaf.
// CHECK FOR EMPTY ARRAY OR NULL PINDEX:
if (PArray == (Pvoid_t) NULL) JU_RET_NOTFOUND;
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Convert Count to Count0; assume special case of Count = 0 maps to ~0, as
// desired, to represent the last index in a full array:
//
// Note: Think of Count0 as a reliable "number of Indexes below the target."
Count0 = Count - 1;
assert((Count || Count0 == ~0)); // ensure CPU is sane about 0 - 1.
pop1lower = 0;
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
if (Count0 > Pjlw[0]) JU_RET_NOTFOUND; // too high.
*PIndex = Pjlw[Count]; // Index, base 1.
JU_RET_FOUND_LEAFW(Pjlw, Pjlw[0] + 1, Count0);
}
else
{
Pjpm_t Pjpm = P_JPM(PArray);
if (Count0 > (Pjpm->jpm_Pop0)) JU_RET_NOTFOUND; // too high.
Pjp = &(Pjpm->jpm_JP);
pop1 = (Pjpm->jpm_Pop0) + 1;
// goto SMByCount;
}
// COMMON CODE:
//
// Prepare to handle a root-level or lower-level branch: Save the current
// state, obtain the total population for the branch in a state-dependent way,
// and then branch to common code for multiple cases.
//
// For root-level branches, the state is always cJU_ROOTSTATE, and the array
// population must already be set in pop1; it is not available in jp_DcdPopO.
//
// Note: The total population is only needed in cases where the common code
// "counts down" instead of up to minimize cache line fills. However, its
// available cheaply, and its better to do it with a constant shift (constant
// state value) instead of a variable shift later "when needed".
#define PREPB_ROOT(Next) \
state = cJU_ROOTSTATE; \
goto Next
// Use PREPB_DCD() to first copy the Dcd bytes to *PIndex if there are any
// (only if state < cJU_ROOTSTATE - 1):
#define PREPB_DCD(Pjp,cState,Next) \
JU_SETDCD(*PIndex, Pjp, cState); \
PREPB((Pjp), cState, Next)
#define PREPB(Pjp,cState,Next) \
state = (cState); \
pop1 = JU_JPBRANCH_POP0(Pjp, (cState)) + 1; \
goto Next
// Calculate whether the ordinal of an Index within a given expanse falls in
// the lower or upper half of the expanses population, taking care with
// unsigned math and boundary conditions:
//
// Note: Assume the ordinal falls within the expanses population, that is,
// 0 < (Count - Pop1lower) <= Pop1exp (assuming infinite math).
//
// Note: If the ordinal is the middle element, it doesnt matter whether
// LOWERHALF() is TRUE or FALSE.
#define LOWERHALF(Count0,Pop1lower,Pop1exp) \
(((Count0) - (Pop1lower)) < ((Pop1exp) / 2))
// Calculate the (signed) offset within a leaf to the desired ordinal (Count -
// Pop1lower; offset is one less), and optionally ensure its in range:
#define SETOFFSET(Offset,Count0,Pop1lower,Pjp) \
(Offset) = (Count0) - (Pop1lower); \
assert((Offset) >= 0); \
assert((Offset) <= JU_JPLEAF_POP0(Pjp))
// Variations for immediate indexes, with and without pop1-specific assertions:
#define SETOFFSET_IMM_CK(Offset,Count0,Pop1lower,cPop1) \
(Offset) = (Count0) - (Pop1lower); \
assert((Offset) >= 0); \
assert((Offset) < (cPop1))
#define SETOFFSET_IMM(Offset,Count0,Pop1lower) \
(Offset) = (Count0) - (Pop1lower)
// STATE MACHINE -- TRAVERSE TREE:
//
// In branches, look for the expanse (digit), if any, where the total pop1
// below or at that expanse would meet or exceed Count, meaning the Index must
// be in this expanse.
SMByCount: // return here for next branch/leaf.
switch (JU_JPTYPE(Pjp))
{
// ----------------------------------------------------------------------------
// LINEAR BRANCH; count populations in JPs in the JBL upwards until finding the
// expanse (digit) containing Count, and "recurse".
//
// Note: There are no null JPs in a JBL; watch out for pop1 == 0.
//
// Note: A JBL should always fit in one cache line => no need to count up
// versus down to save cache line fills.
//
// TBD: The previous is no longer true. Consider enhancing this code to count
// up/down, but it can wait for a later tuning phase. In the meantime, PREPB()
// sets pop1 for the whole array, but that value is not used here. 001215:
// Maybe its true again?
case cJU_JPBRANCH_L2: PREPB_DCD(Pjp, 2, BranchL);
#ifndef JU_64BIT
case cJU_JPBRANCH_L3: PREPB( Pjp, 3, BranchL);
#else
case cJU_JPBRANCH_L3: PREPB_DCD(Pjp, 3, BranchL);
case cJU_JPBRANCH_L4: PREPB_DCD(Pjp, 4, BranchL);
case cJU_JPBRANCH_L5: PREPB_DCD(Pjp, 5, BranchL);
case cJU_JPBRANCH_L6: PREPB_DCD(Pjp, 6, BranchL);
case cJU_JPBRANCH_L7: PREPB( Pjp, 7, BranchL);
#endif
case cJU_JPBRANCH_L: PREPB_ROOT( BranchL);
{
Pjbl_t Pjbl;
// Common code (state-independent) for all cases of linear branches:
BranchL:
Pjbl = P_JBL(Pjp->jp_Addr);
for (jpnum = 0; jpnum < (Pjbl->jbl_NumJPs); ++jpnum)
{
if ((pop1 = j__udyJPPop1((Pjbl->jbl_jp) + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, so do not subtract 1 and compare
// >=, but instead use the following expression:
if (pop1lower + pop1 > Count0) // Index is in this expanse.
{
JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[jpnum], state);
Pjp = (Pjbl->jbl_jp) + jpnum;
goto SMByCount; // look under this expanse.
}
pop1lower += pop1; // add this JPs pop1.
}
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_L
// ----------------------------------------------------------------------------
// BITMAP BRANCH; count populations in JPs in the JBB upwards or downwards
// until finding the expanse (digit) containing Count, and "recurse".
//
// Note: There are no null JPs in a JBB; watch out for pop1 == 0.
case cJU_JPBRANCH_B2: PREPB_DCD(Pjp, 2, BranchB);
#ifndef JU_64BIT
case cJU_JPBRANCH_B3: PREPB( Pjp, 3, BranchB);
#else
case cJU_JPBRANCH_B3: PREPB_DCD(Pjp, 3, BranchB);
case cJU_JPBRANCH_B4: PREPB_DCD(Pjp, 4, BranchB);
case cJU_JPBRANCH_B5: PREPB_DCD(Pjp, 5, BranchB);
case cJU_JPBRANCH_B6: PREPB_DCD(Pjp, 6, BranchB);
case cJU_JPBRANCH_B7: PREPB( Pjp, 7, BranchB);
#endif
case cJU_JPBRANCH_B: PREPB_ROOT( BranchB);
{
Pjbb_t Pjbb;
// Common code (state-independent) for all cases of bitmap branches:
BranchB:
Pjbb = P_JBB(Pjp->jp_Addr);
// Shorthand for one subexpanse in a bitmap and for one JP in a bitmap branch:
//
// Note: BMPJP0 exists separately to support assertions.
#define BMPJP0(Subexp) (P_JP(JU_JBB_PJP(Pjbb, Subexp)))
#define BMPJP(Subexp,JPnum) (BMPJP0(Subexp) + (JPnum))
// Common code for descending through a JP:
//
// Determine the digit for the expanse and save it in *PIndex; then "recurse".
#define JBB_FOUNDEXPANSE \
{ \
JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb,subexp), jpnum); \
JU_SETDIGIT(*PIndex, digit, state); \
Pjp = BMPJP(subexp, jpnum); \
goto SMByCount; \
}
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
// in JPs upwards, or subtracting the pop1s in JPs downwards:
//
// See header comments about limitations of this for Judy*ByCount().
#endif
// COUNT UPWARD, adding each "below" JPs pop1:
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jbb_upward;
#endif
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,subexp)))
&& (BMPJP0(subexp) == (Pjp_t) NULL))
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Note: An empty subexpanse (jpcount == 0) is handled "for free":
for (jpnum = 0; jpnum < jpcount; ++jpnum)
{
if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
JBB_FOUNDEXPANSE; // Index is in this expanse.
pop1lower += pop1; // add this JPs pop1.
}
}
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting each "above" JPs pop1 from the whole expanses
// pop1:
else
{
#ifdef SMARTMETRICS
++jbb_downward;
#endif
pop1lower += pop1; // add whole branch to start.
for (subexp = cJU_NUMSUBEXPB - 1; subexp >= 0; --subexp)
{
if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)))
&& (BMPJP0(subexp) == (Pjp_t) NULL))
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Note: An empty subexpanse (jpcount == 0) is handled "for free":
for (jpnum = jpcount - 1; jpnum >= 0; --jpnum)
{
if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
pop1lower -= pop1;
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
JBB_FOUNDEXPANSE; // Index is in this expanse.
}
}
}
#endif // NOSMARTJBB
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_B
// ----------------------------------------------------------------------------
// UNCOMPRESSED BRANCH; count populations in JPs in the JBU upwards or
// downwards until finding the expanse (digit) containing Count, and "recurse".
case cJU_JPBRANCH_U2: PREPB_DCD(Pjp, 2, BranchU);
#ifndef JU_64BIT
case cJU_JPBRANCH_U3: PREPB( Pjp, 3, BranchU);
#else
case cJU_JPBRANCH_U3: PREPB_DCD(Pjp, 3, BranchU);
case cJU_JPBRANCH_U4: PREPB_DCD(Pjp, 4, BranchU);
case cJU_JPBRANCH_U5: PREPB_DCD(Pjp, 5, BranchU);
case cJU_JPBRANCH_U6: PREPB_DCD(Pjp, 6, BranchU);
case cJU_JPBRANCH_U7: PREPB( Pjp, 7, BranchU);
#endif
case cJU_JPBRANCH_U: PREPB_ROOT( BranchU);
{
Pjbu_t Pjbu;
// Common code (state-independent) for all cases of uncompressed branches:
BranchU:
Pjbu = P_JBU(Pjp->jp_Addr);
// Common code for descending through a JP:
//
// Save the digit for the expanse in *PIndex, then "recurse".
#define JBU_FOUNDEXPANSE \
{ \
JU_SETDIGIT(*PIndex, jpnum, state); \
Pjp = (Pjbu->jbu_jp) + jpnum; \
goto SMByCount; \
}
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
// in JPs upwards, or subtracting the pop1s in JPs downwards:
//
// See header comments about limitations of this for Judy*ByCount().
#endif
// COUNT UPWARD, simply adding the pop1 of each JP:
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jbu_upward;
#endif
for (jpnum = 0; jpnum < cJU_BRANCHUNUMJPS; ++jpnum)
{
// shortcut, save a function call:
if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
continue;
if ((pop1 = j__udyJPPop1((Pjbu->jbu_jp) + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
JBU_FOUNDEXPANSE; // Index is in this expanse.
pop1lower += pop1; // add this JPs pop1.
}
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting the pop1 of each JP above from the whole
// expanses pop1:
else
{
#ifdef SMARTMETRICS
++jbu_downward;
#endif
pop1lower += pop1; // add whole branch to start.
for (jpnum = cJU_BRANCHUNUMJPS - 1; jpnum >= 0; --jpnum)
{
// shortcut, save a function call:
if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
continue;
if ((pop1 = j__udyJPPop1(Pjbu->jbu_jp + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
pop1lower -= pop1;
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
JBU_FOUNDEXPANSE; // Index is in this expanse.
}
}
#endif // NOSMARTJBU
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_U
// ----------------------------------------------------------------------------
// LINEAR LEAF:
//
// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf. First
// copy Dcd bytes, if there are any (only if state < cJU_ROOTSTATE - 1), to
// *PIndex.
//
// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
// (linear leaf) as a side-effect, but dont depend on that (for JUDYL, which
// is the only cases that need it anyway).
#define PREPL_DCD(cState) \
JU_SETDCD(*PIndex, Pjp, cState); \
PREPL
#ifdef JUDY1
#define PREPL_SETPOP1 // not needed in any cases.
#else
#define PREPL_SETPOP1 pop1 = JU_JPLEAF_POP0(Pjp) + 1
#endif
#define PREPL \
Pjll = P_JLL(Pjp->jp_Addr); \
PREPL_SETPOP1; \
SETOFFSET(offset, Count0, pop1lower, Pjp)
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1:
PREPL_DCD(1);
JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]);
JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
#endif
case cJU_JPLEAF2:
PREPL_DCD(2);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
| ((uint16_t *) Pjll)[offset];
JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
#ifndef JU_64BIT
case cJU_JPLEAF3:
{
Word_t lsb;
PREPL;
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
}
#else
case cJU_JPLEAF3:
{
Word_t lsb;
PREPL_DCD(3);
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
}
case cJU_JPLEAF4:
PREPL_DCD(4);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
| ((uint32_t *) Pjll)[offset];
JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
case cJU_JPLEAF5:
{
Word_t lsb;
PREPL_DCD(5);
JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
}
case cJU_JPLEAF6:
{
Word_t lsb;
PREPL_DCD(6);
JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
}
case cJU_JPLEAF7:
{
Word_t lsb;
PREPL;
JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
}
#endif
// ----------------------------------------------------------------------------
// BITMAP LEAF:
//
// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf by
// counting bits. First copy Dcd bytes (always present since state 1 <
// cJU_ROOTSTATE) to *PIndex.
//
// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
// (bitmap leaf) as a side-effect, but dont depend on that.
case cJU_JPLEAF_B1:
{
Pjlb_t Pjlb;
JU_SETDCD(*PIndex, Pjp, 1);
Pjlb = P_JLB(Pjp->jp_Addr);
pop1 = JU_JPLEAF_POP0(Pjp) + 1;
// COUNT UPWARD, adding the pop1 of each subexpanse:
//
// The entire bitmap should fit in one cache line, but still try to save some
// CPU time by counting the fewest possible number of subexpanses from the
// bitmap.
//
// See header comments about limitations of this for Judy*ByCount().
#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jlb_upward;
#endif
for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
{
pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
goto LeafB1; // Index is in this subexpanse.
pop1lower += pop1; // add this subexpanses pop1.
}
#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting each "above" subexpanses pop1 from the whole
// expanses pop1:
else
{
#ifdef SMARTMETRICS
++jlb_downward;
#endif
pop1lower += pop1; // add whole leaf to start.
for (subexp = cJU_NUMSUBEXPL - 1; subexp >= 0; --subexp)
{
pop1lower -= j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
goto LeafB1; // Index is in this subexpanse.
}
}
#endif // NOSMARTJLB
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
// RETURN INDEX FOUND:
//
// Come here with subexp set to the correct subexpanse, and pop1lower set to
// the sum for all lower expanses and subexpanses in the Judy tree. Calculate
// and save in *PIndex the digit corresponding to the ordinal in this
// subexpanse.
LeafB1:
SETOFFSET(offset, Count0, pop1lower, Pjp);
JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset);
JU_SETDIGIT1(*PIndex, digit);
JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + offset))
} // case cJU_JPLEAF_B1
#ifdef JUDY1
// ----------------------------------------------------------------------------
// FULL POPULATION:
//
// Copy Dcd bytes (always present since state 1 < cJU_ROOTSTATE) to *PIndex,
// then set the appropriate digit for the ordinal (see SETOFFSET()) in the leaf
// as the LSB in *PIndex.
case cJ1_JPFULLPOPU1:
JU_SETDCD(*PIndex, Pjp, 1);
SETOFFSET(offset, Count0, pop1lower, Pjp);
assert(offset >= 0);
assert(offset <= cJU_JPFULLPOPU1_POP0);
JU_SETDIGIT1(*PIndex, offset);
JU_RET_FOUND_FULLPOPU1;
#endif
// ----------------------------------------------------------------------------
// IMMEDIATE:
//
// Locate the Index with the proper ordinal (see SETOFFSET()) in the Immediate,
// depending on leaf Index Size and pop1. Note: There are no Dcd bytes in an
// Immediate JP, but in a cJU_JPIMMED_*_01 JP, the field holds the least bytes
// of the immediate Index.
#define SET_01(cState) JU_SETDIGITS(*PIndex, JU_JPDCDPOP0(Pjp), cState)
case cJU_JPIMMED_1_01: SET_01(1); goto Imm_01;
case cJU_JPIMMED_2_01: SET_01(2); goto Imm_01;
case cJU_JPIMMED_3_01: SET_01(3); goto Imm_01;
#ifdef JU_64BIT
case cJU_JPIMMED_4_01: SET_01(4); goto Imm_01;
case cJU_JPIMMED_5_01: SET_01(5); goto Imm_01;
case cJU_JPIMMED_6_01: SET_01(6); goto Imm_01;
case cJU_JPIMMED_7_01: SET_01(7); goto Imm_01;
#endif
Imm_01:
DBGCODE(SETOFFSET_IMM_CK(offset, Count0, pop1lower, 1);)
JU_RET_FOUND_IMM_01(Pjp);
// Shorthand for where to find start of Index bytes array:
#ifdef JUDY1
#define PJI (Pjp->jp_1Index)
#else
#define PJI (Pjp->jp_LIndex)
#endif
// Optional code to check the remaining ordinal (see SETOFFSET_IMM()) against
// the Index Size of the Immediate:
#ifndef DEBUG // simple placeholder:
#define IMM(cPop1,Next) \
goto Next
#else // extra pop1-specific checking:
#define IMM(cPop1,Next) \
SETOFFSET_IMM_CK(offset, Count0, pop1lower, cPop1); \
goto Next
#endif
case cJU_JPIMMED_1_02: IMM( 2, Imm1);
case cJU_JPIMMED_1_03: IMM( 3, Imm1);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_1_04: IMM( 4, Imm1);
case cJU_JPIMMED_1_05: IMM( 5, Imm1);
case cJU_JPIMMED_1_06: IMM( 6, Imm1);
case cJU_JPIMMED_1_07: IMM( 7, Imm1);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_1_08: IMM( 8, Imm1);
case cJ1_JPIMMED_1_09: IMM( 9, Imm1);
case cJ1_JPIMMED_1_10: IMM(10, Imm1);
case cJ1_JPIMMED_1_11: IMM(11, Imm1);
case cJ1_JPIMMED_1_12: IMM(12, Imm1);
case cJ1_JPIMMED_1_13: IMM(13, Imm1);
case cJ1_JPIMMED_1_14: IMM(14, Imm1);
case cJ1_JPIMMED_1_15: IMM(15, Imm1);
#endif
Imm1: SETOFFSET_IMM(offset, Count0, pop1lower);
JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]);
JU_RET_FOUND_IMM(Pjp, offset);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_2_02: IMM(2, Imm2);
case cJU_JPIMMED_2_03: IMM(3, Imm2);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_2_04: IMM(4, Imm2);
case cJ1_JPIMMED_2_05: IMM(5, Imm2);
case cJ1_JPIMMED_2_06: IMM(6, Imm2);
case cJ1_JPIMMED_2_07: IMM(7, Imm2);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
Imm2: SETOFFSET_IMM(offset, Count0, pop1lower);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
| ((uint16_t *) PJI)[offset];
JU_RET_FOUND_IMM(Pjp, offset);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_3_02: IMM(2, Imm3);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_3_03: IMM(3, Imm3);
case cJ1_JPIMMED_3_04: IMM(4, Imm3);
case cJ1_JPIMMED_3_05: IMM(5, Imm3);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
Imm3:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_4_02: IMM(2, Imm4);
case cJ1_JPIMMED_4_03: IMM(3, Imm4);
Imm4: SETOFFSET_IMM(offset, Count0, pop1lower);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
| ((uint32_t *) PJI)[offset];
JU_RET_FOUND_IMM(Pjp, offset);
case cJ1_JPIMMED_5_02: IMM(2, Imm5);
case cJ1_JPIMMED_5_03: IMM(3, Imm5);
Imm5:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
case cJ1_JPIMMED_6_02: IMM(2, Imm6);
Imm6:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
case cJ1_JPIMMED_7_02: IMM(2, Imm7);
Imm7:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
#endif // (JUDY1 && JU_64BIT)
// ----------------------------------------------------------------------------
// UNEXPECTED JP TYPES:
default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // SMByCount switch.
/*NOTREACHED*/
} // Judy1ByCount() / JudyLByCount()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,314 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
// Branch creation functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// ****************************************************************************
// J U D Y C R E A T E B R A N C H L
//
// Build a BranchL from an array of JPs and associated 1 byte digits
// (expanses). Return with Pjp pointing to the BranchL. Caller must
// deallocate passed arrays, if necessary.
//
// We have no idea what kind of BranchL it is, so caller must set the jp_Type.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchL(
Pjp_t Pjp, // Build JPs from this place
Pjp_t PJPs, // Array of JPs to put into Bitmap branch
uint8_t Exp[], // Array of expanses to put into bitmap
Word_t ExpCnt, // Number of above JPs and Expanses
Pvoid_t Pjpm)
{
Pjbl_t PjblRaw; // pointer to linear branch.
Pjbl_t Pjbl;
assert(ExpCnt <= cJU_BRANCHLMAXJPS);
PjblRaw = j__udyAllocJBL(Pjpm);
if (PjblRaw == (Pjbl_t) NULL) return(-1);
Pjbl = P_JBL(PjblRaw);
// Build a Linear Branch
Pjbl->jbl_NumJPs = ExpCnt;
// Copy from the Linear branch from splayed leaves
JU_COPYMEM(Pjbl->jbl_Expanse, Exp, ExpCnt);
JU_COPYMEM(Pjbl->jbl_jp, PJPs, ExpCnt);
// Pass back new pointer to the Linear branch in JP
Pjp->jp_Addr = (Word_t) PjblRaw;
return(1);
} // j__udyCreateBranchL()
// ****************************************************************************
// J U D Y C R E A T E B R A N C H B
//
// Build a BranchB from an array of JPs and associated 1 byte digits
// (expanses). Return with Pjp pointing to the BranchB. Caller must
// deallocate passed arrays, if necessary.
//
// We have no idea what kind of BranchB it is, so caller must set the jp_Type.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchB(
Pjp_t Pjp, // Build JPs from this place
Pjp_t PJPs, // Array of JPs to put into Bitmap branch
uint8_t Exp[], // Array of expanses to put into bitmap
Word_t ExpCnt, // Number of above JPs and Expanses
Pvoid_t Pjpm)
{
Pjbb_t PjbbRaw; // pointer to bitmap branch.
Pjbb_t Pjbb;
Word_t ii, jj; // Temps
uint8_t CurrSubExp; // Current sub expanse for BM
// This assertion says the number of populated subexpanses is not too large.
// This function is only called when a BranchL overflows to a BranchB or when a
// cascade occurs, meaning a leaf overflows. Either way ExpCnt cant be very
// large, in fact a lot smaller than cJU_BRANCHBMAXJPS. (Otherwise a BranchU
// would be used.) Popping this assertion means something (unspecified) has
// gone very wrong, or else Judys design criteria have changed, although in
// fact there should be no HARM in creating a BranchB with higher actual
// fanout.
assert(ExpCnt <= cJU_BRANCHBMAXJPS);
// Get memory for a Bitmap branch
PjbbRaw = j__udyAllocJBB(Pjpm);
if (PjbbRaw == (Pjbb_t) NULL) return(-1);
Pjbb = P_JBB(PjbbRaw);
// Get 1st "sub" expanse (0..7) of bitmap branch
CurrSubExp = Exp[0] / cJU_BITSPERSUBEXPB;
// Index thru all 1 byte sized expanses:
for (jj = ii = 0; ii <= ExpCnt; ii++)
{
Word_t SubExp; // Cannot be a uint8_t
// Make sure we cover the last one
if (ii == ExpCnt)
{
SubExp = cJU_ALLONES; // Force last one
}
else
{
// Calculate the "sub" expanse of the byte expanse
SubExp = Exp[ii] / cJU_BITSPERSUBEXPB; // Bits 5..7.
// Set the bit that represents the expanse in Exp[]
JU_JBB_BITMAP(Pjbb, SubExp) |= JU_BITPOSMASKB(Exp[ii]);
}
// Check if a new "sub" expanse range needed
if (SubExp != CurrSubExp)
{
// Get number of JPs in this sub expanse
Word_t NumJP = ii - jj;
Pjp_t PjpRaw;
Pjp_t Pjp;
PjpRaw = j__udyAllocJBBJP(NumJP, Pjpm);
Pjp = P_JP(PjpRaw);
if (PjpRaw == (Pjp_t) NULL) // out of memory.
{
// Free any previous allocations:
while(CurrSubExp--)
{
NumJP = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,
CurrSubExp));
if (NumJP)
{
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb,
CurrSubExp), NumJP, Pjpm);
}
}
j__udyFreeJBB(PjbbRaw, Pjpm);
return(-1);
}
// Place the array of JPs in bitmap branch:
JU_JBB_PJP(Pjbb, CurrSubExp) = PjpRaw;
// Copy the JPs to new leaf:
JU_COPYMEM(Pjp, PJPs + jj, NumJP);
// On to the next bitmap branch "sub" expanse:
jj = ii;
CurrSubExp = SubExp;
}
} // for each 1-byte expanse
// Pass back some of the JP to the new Bitmap branch:
Pjp->jp_Addr = (Word_t) PjbbRaw;
return(1);
} // j__udyCreateBranchB()
// ****************************************************************************
// J U D Y C R E A T E B R A N C H U
//
// Build a BranchU from a BranchB. Return with Pjp pointing to the BranchU.
// Free the BranchB and its JP subarrays.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchU(
Pjp_t Pjp,
Pvoid_t Pjpm)
{
jp_t JPNull;
Pjbu_t PjbuRaw;
Pjbu_t Pjbu;
Pjbb_t PjbbRaw;
Pjbb_t Pjbb;
Word_t ii, jj;
BITMAPB_t BitMap;
Pjp_t PDstJP;
#ifdef JU_STAGED_EXP
jbu_t BranchU; // Staged uncompressed branch
#else
// Allocate memory for a BranchU:
PjbuRaw = j__udyAllocJBU(Pjpm);
if (PjbuRaw == (Pjbu_t) NULL) return(-1);
Pjbu = P_JBU(PjbuRaw);
#endif
JU_JPSETADT(&JPNull, 0, 0, JU_JPTYPE(Pjp) - cJU_JPBRANCH_B2 + cJU_JPNULL1);
// Get the pointer to the BranchB:
PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
Pjbb = P_JBB(PjbbRaw);
// Set the pointer to the Uncompressed branch
#ifdef JU_STAGED_EXP
PDstJP = BranchU.jbu_jp;
#else
PDstJP = Pjbu->jbu_jp;
#endif
for (ii = 0; ii < cJU_NUMSUBEXPB; ii++)
{
Pjp_t PjpA;
Pjp_t PjpB;
PjpB = PjpA = P_JP(JU_JBB_PJP(Pjbb, ii));
// Get the bitmap for this subexpanse
BitMap = JU_JBB_BITMAP(Pjbb, ii);
// NULL empty subexpanses
if (BitMap == 0)
{
// But, fill with NULLs
for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++)
{
PDstJP[jj] = JPNull;
}
PDstJP += cJU_BITSPERSUBEXPB;
continue;
}
// Check if Uncompressed subexpanse
if (BitMap == cJU_FULLBITMAPB)
{
// Copy subexpanse to the Uncompressed branch intact
JU_COPYMEM(PDstJP, PjpA, cJU_BITSPERSUBEXPB);
// Bump to next subexpanse
PDstJP += cJU_BITSPERSUBEXPB;
// Set length of subexpanse
jj = cJU_BITSPERSUBEXPB;
}
else
{
for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++)
{
// Copy JP or NULLJP depending on bit
if (BitMap & 1) { *PDstJP = *PjpA++; }
else { *PDstJP = JPNull; }
PDstJP++; // advance to next JP
BitMap >>= 1;
}
jj = PjpA - PjpB;
}
// Free the subexpanse:
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, ii), jj, Pjpm);
} // for each JP in BranchU
#ifdef JU_STAGED_EXP
// Allocate memory for a BranchU:
PjbuRaw = j__udyAllocJBU(Pjpm);
if (PjbuRaw == (Pjbu_t) NULL) return(-1);
Pjbu = P_JBU(PjbuRaw);
// Copy staged branch to newly allocated branch:
//
// TBD: I think this code is broken.
*Pjbu = BranchU;
#endif // JU_STAGED_EXP
// Finally free the BranchB and put the BranchU in its place:
j__udyFreeJBB(PjbbRaw, Pjpm);
Pjp->jp_Addr = (Word_t) PjbuRaw;
Pjp->jp_Type += cJU_JPBRANCH_U - cJU_JPBRANCH_B;
return(1);
} // j__udyCreateBranchU()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,213 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy*First[Empty]() and Judy*Last[Empty]() routines for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
//
// These are inclusive versions of Judy*Next[Empty]() and Judy*Prev[Empty]().
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
// ****************************************************************************
// J U D Y 1 F I R S T
// J U D Y L F I R S T
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1First
#else
FUNCTION PPvoid_t JudyLFirst
#endif
(
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError // optional, for returning error info.
)
{
if (PIndex == (PWord_t) NULL) // caller error:
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 1: return(1); // found *PIndex itself.
case 0: return(Judy1Next(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(PPJERR);
if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex.
return(JudyLNext(PArray, PIndex, PJError));
}
#endif
} // Judy1First() / JudyLFirst()
// ****************************************************************************
// J U D Y 1 L A S T
// J U D Y L L A S T
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1Last(
#else
FUNCTION PPvoid_t JudyLLast(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 1: return(1); // found *PIndex itself.
case 0: return(Judy1Prev(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(PPJERR);
if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex.
return(JudyLPrev(PArray, PIndex, PJError));
}
#endif
} // Judy1Last() / JudyLLast()
// ****************************************************************************
// J U D Y 1 F I R S T E M P T Y
// J U D Y L F I R S T E M P T Y
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1FirstEmpty(
#else
FUNCTION int JudyLFirstEmpty(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL) // caller error:
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
return(JERRI);
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 0: return(1); // found *PIndex itself.
case 1: return(Judy1NextEmpty(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(JERRI);
if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex.
return(JudyLNextEmpty(PArray, PIndex, PJError));
}
#endif
} // Judy1FirstEmpty() / JudyLFirstEmpty()
// ****************************************************************************
// J U D Y 1 L A S T E M P T Y
// J U D Y L L A S T E M P T Y
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1LastEmpty(
#else
FUNCTION int JudyLLastEmpty(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error.
return(JERRI);
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 0: return(1); // found *PIndex itself.
case 1: return(Judy1PrevEmpty(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(JERRI);
if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex.
return(JudyLPrevEmpty(PArray, PIndex, PJError));
}
#endif
} // Judy1LastEmpty() / JudyLLastEmpty()

View File

@ -0,0 +1,363 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy1FreeArray() and JudyLFreeArray() functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
// Return the number of bytes freed from the array.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);)
// ****************************************************************************
// J U D Y 1 F R E E A R R A Y
// J U D Y L F R E E A R R A Y
//
// See the Judy*(3C) manual entry for details.
//
// This code is written recursively, at least at first, because thats much
// simpler. Hope its fast enough.
#ifdef JUDY1
FUNCTION Word_t Judy1FreeArray
#else
FUNCTION Word_t JudyLFreeArray
#endif
(
PPvoid_t PPArray, // array to free.
PJError_t PJError // optional, for returning error info.
)
{
jpm_t jpm; // local to accumulate free statistics.
// CHECK FOR NULL POINTER (error by caller):
if (PPArray == (PPvoid_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
return(JERR);
}
DBGCODE(JudyCheckPop(*PPArray);)
// Zero jpm.jpm_Pop0 (meaning the array will be empty in a moment) for accurate
// logging in TRACEMI2.
jpm.jpm_Pop0 = 0; // see above.
jpm.jpm_TotalMemWords = 0; // initialize memory freed.
// Empty array:
if (P_JLW(*PPArray) == (Pjlw_t) NULL) return(0);
// PROCESS TOP LEVEL "JRP" BRANCHES AND LEAF:
if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
j__udyFreeJLW(Pjlw, Pjlw[0] + 1, &jpm);
*PPArray = (Pvoid_t) NULL; // make an empty array.
return (-(jpm.jpm_TotalMemWords * cJU_BYTESPERWORD)); // see above.
}
else
// Rootstate leaves: just free the leaf:
// Common code for returning the amount of memory freed.
//
// Note: In a an ordinary LEAFW, pop0 = *PPArray[0].
//
// Accumulate (negative) words freed, while freeing objects.
// Return the positive bytes freed.
{
Pjpm_t Pjpm = P_JPM(*PPArray);
Word_t TotalMem = Pjpm->jpm_TotalMemWords;
j__udyFreeSM(&(Pjpm->jpm_JP), &jpm); // recurse through tree.
j__udyFreeJPM(Pjpm, &jpm);
// Verify the array was not corrupt. This means that amount of memory freed
// (which is negative) is equal to the initial amount:
if (TotalMem + jpm.jpm_TotalMemWords)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
return(JERR);
}
*PPArray = (Pvoid_t) NULL; // make an empty array.
return (TotalMem * cJU_BYTESPERWORD);
}
} // Judy1FreeArray() / JudyLFreeArray()
// ****************************************************************************
// __ J U D Y F R E E S M
//
// Given a pointer to a JP, recursively visit and free (depth first) all nodes
// in a Judy array BELOW the JP, but not the JP itself. Accumulate in *Pjpm
// the total words freed (as a negative value). "SM" = State Machine.
//
// Note: Corruption is not detected at this level because during a FreeArray,
// if the code hasnt already core dumped, its better to remain silent, even
// if some memory has not been freed, than to bother the caller about the
// corruption. TBD: Is this true? If not, must list all legitimate JPNULL
// and JPIMMED above first, and revert to returning bool_t (see 4.34).
FUNCTION void j__udyFreeSM(
Pjp_t Pjp, // top of Judy (top-state).
Pjpm_t Pjpm) // to return words freed.
{
Word_t Pop1;
switch (JU_JPTYPE(Pjp))
{
#ifdef JUDY1
// FULL EXPANSE -- nothing to free for this jp_Type.
case cJ1_JPFULLPOPU1:
break;
#endif
// JUDY BRANCH -- free the sub-tree depth first:
// LINEAR BRANCH -- visit each JP in the JBLs list, then free the JBL:
//
// Note: There are no null JPs in a JBL.
case cJU_JPBRANCH_L:
case cJU_JPBRANCH_L2:
case cJU_JPBRANCH_L3:
#ifdef JU_64BIT
case cJU_JPBRANCH_L4:
case cJU_JPBRANCH_L5:
case cJU_JPBRANCH_L6:
case cJU_JPBRANCH_L7:
#endif // JU_64BIT
{
Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
Word_t offset;
for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset)
j__udyFreeSM((Pjbl->jbl_jp) + offset, Pjpm);
j__udyFreeJBL((Pjbl_t) (Pjp->jp_Addr), Pjpm);
break;
}
// BITMAP BRANCH -- visit each JP in the JBBs list based on the bitmap, also
//
// Note: There are no null JPs in a JBB.
case cJU_JPBRANCH_B:
case cJU_JPBRANCH_B2:
case cJU_JPBRANCH_B3:
#ifdef JU_64BIT
case cJU_JPBRANCH_B4:
case cJU_JPBRANCH_B5:
case cJU_JPBRANCH_B6:
case cJU_JPBRANCH_B7:
#endif // JU_64BIT
{
Word_t subexp;
Word_t offset;
Word_t jpcount;
Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
if (jpcount)
{
for (offset = 0; offset < jpcount; ++offset)
{
j__udyFreeSM(P_JP(JU_JBB_PJP(Pjbb, subexp)) + offset,
Pjpm);
}
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, subexp), jpcount, Pjpm);
}
}
j__udyFreeJBB((Pjbb_t) (Pjp->jp_Addr), Pjpm);
break;
}
// UNCOMPRESSED BRANCH -- visit each JP in the JBU array, then free the JBU
// itself:
//
// Note: Null JPs are handled during recursion at a lower state.
case cJU_JPBRANCH_U:
case cJU_JPBRANCH_U2:
case cJU_JPBRANCH_U3:
#ifdef JU_64BIT
case cJU_JPBRANCH_U4:
case cJU_JPBRANCH_U5:
case cJU_JPBRANCH_U6:
case cJU_JPBRANCH_U7:
#endif // JU_64BIT
{
Word_t offset;
Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
j__udyFreeSM((Pjbu->jbu_jp) + offset, Pjpm);
j__udyFreeJBU((Pjbu_t) (Pjp->jp_Addr), Pjpm);
break;
}
// -- Cases below here terminate and do not recurse. --
// LINEAR LEAF -- just free the leaf; size is computed from jp_Type:
//
// Note: cJU_JPLEAF1 is a special case, see discussion in ../Judy1/Judy1.h
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL1((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#endif
case cJU_JPLEAF2:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL2((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF3:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#ifdef JU_64BIT
case cJU_JPLEAF4:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL4((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF5:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL5((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF6:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL6((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF7:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL7((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#endif // JU_64BIT
// BITMAP LEAF -- free sub-expanse arrays of JPs, then free the JBB.
case cJU_JPLEAF_B1:
{
#ifdef JUDYL
Word_t subexp;
Word_t jpcount;
Pjlb_t Pjlb = P_JLB(Pjp->jp_Addr);
// Free the value areas in the bitmap leaf:
for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
{
jpcount = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
if (jpcount)
j__udyLFreeJV(JL_JLB_PVALUE(Pjlb, subexp), jpcount, Pjpm);
}
#endif // JUDYL
j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm);
break;
} // case cJU_JPLEAF_B1
#ifdef JUDYL
// IMMED*:
//
// For JUDYL, all non JPIMMED_*_01s have a LeafV which must be freed:
case cJU_JPIMMED_1_02:
case cJU_JPIMMED_1_03:
#ifdef JU_64BIT
case cJU_JPIMMED_1_04:
case cJU_JPIMMED_1_05:
case cJU_JPIMMED_1_06:
case cJU_JPIMMED_1_07:
#endif
Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_02 + 2;
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#ifdef JU_64BIT
case cJU_JPIMMED_2_02:
case cJU_JPIMMED_2_03:
Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_2_02 + 2;
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPIMMED_3_02:
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), 2, Pjpm);
break;
#endif // JU_64BIT
#endif // JUDYL
// OTHER JPNULL, JPIMMED, OR UNEXPECTED TYPE -- nothing to free for this type:
//
// Note: Lump together no-op and invalid JP types; see function header
// comments.
default: break;
} // switch (JU_JPTYPE(Pjp))
} // j__udyFreeSM()

View File

@ -0,0 +1,135 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
// BranchL insertion functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
extern int j__udyCreateBranchL(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
// ****************************************************************************
// __ J U D Y I N S E R T B R A N C H
//
// Insert 2-element BranchL in between Pjp and Pjp->jp_Addr.
//
// Return -1 if out of memory, otherwise return 1.
FUNCTION int j__udyInsertBranch(
Pjp_t Pjp, // JP containing narrow pointer.
Word_t Index, // outlier to Pjp.
Word_t BranchLevel, // of what JP points to, mapped from JP type.
Pjpm_t Pjpm) // for global accounting.
{
jp_t JP2 [2];
jp_t JP;
Pjp_t PjpNull;
Word_t XorExp;
Word_t Inew, Iold;
Word_t DCDMask; // initially for original BranchLevel.
int Ret;
uint8_t Exp2[2];
uint8_t DecodeByteN, DecodeByteO;
// Get the current mask for the DCD digits:
DCDMask = cJU_DCDMASK(BranchLevel);
// Obtain Dcd bits that differ between Index and JP, shifted so the
// digit for BranchLevel is the LSB:
XorExp = ((Index ^ JU_JPDCDPOP0(Pjp)) & (cJU_ALLONES >> cJU_BITSPERBYTE))
>> (BranchLevel * cJU_BITSPERBYTE);
assert(XorExp); // Index must be an outlier.
// Count levels between object under narrow pointer and the level at which
// the outlier diverges from it, which is always at least initial
// BranchLevel + 1, to end up with the level (JP type) at which to insert
// the new intervening BranchL:
do { ++BranchLevel; } while ((XorExp >>= cJU_BITSPERBYTE));
assert((BranchLevel > 1) && (BranchLevel < cJU_ROOTSTATE));
// Get the MSB (highest digit) that differs between the old expanse and
// the new Index to insert:
DecodeByteO = JU_DIGITATSTATE(JU_JPDCDPOP0(Pjp), BranchLevel);
DecodeByteN = JU_DIGITATSTATE(Index, BranchLevel);
assert(DecodeByteO != DecodeByteN);
// Determine sorted order for old expanse and new Index digits:
if (DecodeByteN > DecodeByteO) { Iold = 0; Inew = 1; }
else { Iold = 1; Inew = 0; }
// Copy old JP into staging area for new Branch
JP2 [Iold] = *Pjp;
Exp2[Iold] = DecodeByteO;
Exp2[Inew] = DecodeByteN;
// Create a 2 Expanse Linear branch
//
// Note: Pjp->jp_Addr is set by j__udyCreateBranchL()
Ret = j__udyCreateBranchL(Pjp, JP2, Exp2, 2, Pjpm);
if (Ret == -1) return(-1);
// Get Pjp to the NULL of where to do insert
PjpNull = ((P_JBL(Pjp->jp_Addr))->jbl_jp) + Inew;
// Convert to a cJU_JPIMMED_*_01 at the correct level:
// Build JP and set type below to: cJU_JPIMMED_X_01
JU_JPSETADT(PjpNull, 0, Index, cJU_JPIMMED_1_01 - 2 + BranchLevel);
// Return pointer to Value area in cJU_JPIMMED_X_01
JUDYLCODE(Pjpm->jpm_PValue = (Pjv_t) PjpNull;)
// The old JP now points to a BranchL that is at higher level. Therefore
// it contains excess DCD bits (in the least significant position) that
// must be removed (zeroed); that is, they become part of the Pop0
// subfield. Note that the remaining (lower) bytes in the Pop0 field do
// not change.
//
// Take from the old DCDMask, which went "down" to a lower BranchLevel,
// and zero any high bits that are still in the mask at the new, higher
// BranchLevel; then use this mask to zero the bits in jp_DcdPopO:
// Set old JP to a BranchL at correct level
Pjp->jp_Type = cJU_JPBRANCH_L2 - 2 + BranchLevel;
DCDMask ^= cJU_DCDMASK(BranchLevel);
DCDMask = ~DCDMask & JU_JPDCDPOP0(Pjp);
JP = *Pjp;
JU_JPSETADT(Pjp, JP.jp_Addr, DCDMask, JP.jp_Type);
return(1);
} // j__udyInsertBranch()

View File

@ -0,0 +1,782 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy malloc/free interface functions for Judy1 and JudyL.
//
// Compile with one of -DJUDY1 or -DJUDYL.
//
// Compile with -DTRACEMI (Malloc Interface) to turn on tracing of malloc/free
// calls at the interface level. (See also TRACEMF in lower-level code.)
// Use -DTRACEMI2 for a terser format suitable for trace analysis.
//
// There can be malloc namespace bits in the LSBs of "raw" addresses from most,
// but not all, of the j__udy*Alloc*() functions; see also JudyPrivate.h. To
// test the Judy code, compile this file with -DMALLOCBITS and use debug flavor
// only (for assertions). This test ensures that (a) all callers properly mask
// the namespace bits out before dereferencing a pointer (or else a core dump
// occurs), and (b) all callers send "raw" (unmasked) addresses to
// j__udy*Free*() calls.
//
// Note: Currently -DDEBUG turns on MALLOCBITS automatically.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// Set "hidden" global j__uMaxWords to the maximum number of words to allocate
// to any one array (large enough to have a JPM, otherwise j__uMaxWords is
// ignored), to trigger a fake malloc error when the number is exceeded. Note,
// this code is always executed, not #ifdefd, because its virtually free.
//
// Note: To keep the MALLOC macro faster and simpler, set j__uMaxWords to
// MAXINT, not zero, by default.
Word_t j__uMaxWords = ~0UL;
// This macro hides the faking of a malloc failure:
//
// Note: To keep this fast, just compare WordsPrev to j__uMaxWords without the
// complexity of first adding WordsNow, meaning the trigger point is not
// exactly where you might assume, but it shouldnt matter.
#define MALLOC(MallocFunc,WordsPrev,WordsNow) \
(((WordsPrev) > j__uMaxWords) ? 0UL : MallocFunc(WordsNow))
// Clear words starting at address:
//
// Note: Only use this for objects that care; in other cases, it doesnt
// matter if the objects memory is pre-zeroed.
#define ZEROWORDS(Addr,Words) \
{ \
Word_t Words__ = (Words); \
PWord_t Addr__ = (PWord_t) (Addr); \
while (Words__--) *Addr__++ = 0UL; \
}
#ifdef TRACEMI
// TRACING SUPPORT:
//
// Note: For TRACEMI, use a format for address printing compatible with other
// tracing facilities; in particular, %x not %lx, to truncate the "noisy" high
// part on 64-bit systems.
//
// TBD: The trace macros need fixing for alternate address types.
//
// Note: TRACEMI2 supports trace analysis no matter the underlying malloc/free
// engine used.
#include <stdio.h>
static Word_t j__udyMemSequence = 0L; // event sequence number.
#define TRACE_ALLOC5(a,b,c,d,e) (void) printf(a, (b), c, d)
#define TRACE_FREE5( a,b,c,d,e) (void) printf(a, (b), c, d)
#define TRACE_ALLOC6(a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
#define TRACE_FREE6( a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
#else
#ifdef TRACEMI2
#include <stdio.h>
#define b_pw cJU_BYTESPERWORD
#define TRACE_ALLOC5(a,b,c,d,e) \
(void) printf("a %lx %lx %lx\n", (b), (d) * b_pw, e)
#define TRACE_FREE5( a,b,c,d,e) \
(void) printf("f %lx %lx %lx\n", (b), (d) * b_pw, e)
#define TRACE_ALLOC6(a,b,c,d,e,f) \
(void) printf("a %lx %lx %lx\n", (b), (e) * b_pw, f)
#define TRACE_FREE6( a,b,c,d,e,f) \
(void) printf("f %lx %lx %lx\n", (b), (e) * b_pw, f)
static Word_t j__udyMemSequence = 0L; // event sequence number.
#else
#define TRACE_ALLOC5(a,b,c,d,e) // null.
#define TRACE_FREE5( a,b,c,d,e) // null.
#define TRACE_ALLOC6(a,b,c,d,e,f) // null.
#define TRACE_FREE6( a,b,c,d,e,f) // null.
#endif // ! TRACEMI2
#endif // ! TRACEMI
// MALLOC NAMESPACE SUPPORT:
#if (defined(DEBUG) && (! defined(MALLOCBITS))) // for now, DEBUG => MALLOCBITS:
#define MALLOCBITS 1
#endif
#ifdef MALLOCBITS
#define MALLOCBITS_VALUE 0x3 // bit pattern to use.
#define MALLOCBITS_MASK 0x7 // note: matches mask__ in JudyPrivate.h.
#define MALLOCBITS_SET( Type,Addr) \
((Addr) = (Type) ((Word_t) (Addr) | MALLOCBITS_VALUE))
#define MALLOCBITS_TEST(Type,Addr) \
assert((((Word_t) (Addr)) & MALLOCBITS_MASK) == MALLOCBITS_VALUE); \
((Addr) = (Type) ((Word_t) (Addr) & ~MALLOCBITS_VALUE))
#else
#define MALLOCBITS_SET( Type,Addr) // null.
#define MALLOCBITS_TEST(Type,Addr) // null.
#endif
// SAVE ERROR INFORMATION IN A Pjpm:
//
// "Small" (invalid) Addr values are used to distinguish overrun and no-mem
// errors. (TBD, non-zero invalid values are no longer returned from
// lower-level functions, that is, JU_ERRNO_OVERRUN is no longer detected.)
#define J__UDYSETALLOCERROR(Addr) \
{ \
JU_ERRID(Pjpm) = __LINE__; \
if ((Word_t) (Addr) > 0) JU_ERRNO(Pjpm) = JU_ERRNO_OVERRUN; \
else JU_ERRNO(Pjpm) = JU_ERRNO_NOMEM; \
return(0); \
}
// ****************************************************************************
// ALLOCATION FUNCTIONS:
//
// To help the compiler catch coding errors, each function returns a specific
// object type.
//
// Note: Only j__udyAllocJPM() and j__udyAllocJLW() return multiple values <=
// sizeof(Word_t) to indicate the type of memory allocation failure. Other
// allocation functions convert this failure to a JU_ERRNO.
// Note: Unlike other j__udyAlloc*() functions, Pjpms are returned non-raw,
// that is, without malloc namespace or root pointer type bits:
FUNCTION Pjpm_t j__udyAllocJPM(void)
{
Word_t Words = sizeof(jpm_t) / cJU_BYTESPERWORD;
Pjpm_t Pjpm = (Pjpm_t) MALLOC(JudyMalloc, Words, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jpm_t));
if ((Word_t) Pjpm > sizeof(Word_t))
{
ZEROWORDS(Pjpm, Words);
Pjpm->jpm_TotalMemWords = Words;
}
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJPM(), Words = %lu\n",
Pjpm, j__udyMemSequence++, Words, cJU_LEAFW_MAXPOP1 + 1);
// MALLOCBITS_SET(Pjpm_t, Pjpm); // see above.
return(Pjpm);
} // j__udyAllocJPM()
FUNCTION Pjbl_t j__udyAllocJBL(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
Pjbl_t PjblRaw = (Pjbl_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbl_t));
if ((Word_t) PjblRaw > sizeof(Word_t))
{
ZEROWORDS(P_JBL(PjblRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjblRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBL(), Words = %lu\n", PjblRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbl_t, PjblRaw);
return(PjblRaw);
} // j__udyAllocJBL()
FUNCTION Pjbb_t j__udyAllocJBB(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
Pjbb_t PjbbRaw = (Pjbb_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbb_t));
if ((Word_t) PjbbRaw > sizeof(Word_t))
{
ZEROWORDS(P_JBB(PjbbRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjbbRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBB(), Words = %lu\n", PjbbRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbb_t, PjbbRaw);
return(PjbbRaw);
} // j__udyAllocJBB()
FUNCTION Pjp_t j__udyAllocJBBJP(Word_t NumJPs, Pjpm_t Pjpm)
{
Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
Pjp_t PjpRaw;
PjpRaw = (Pjp_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjpRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjpRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJBBJP(%lu), Words = %lu\n", PjpRaw,
j__udyMemSequence++, NumJPs, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjp_t, PjpRaw);
return(PjpRaw);
} // j__udyAllocJBBJP()
FUNCTION Pjbu_t j__udyAllocJBU(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
Pjbu_t PjbuRaw = (Pjbu_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbu_t));
if ((Word_t) PjbuRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjbuRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBU(), Words = %lu\n", PjbuRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbu_t, PjbuRaw);
return(PjbuRaw);
} // j__udyAllocJBU()
#if (defined(JUDYL) || (! defined(JU_64BIT)))
FUNCTION Pjll_t j__udyAllocJLL1(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL1(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL1()
#endif // (JUDYL || (! JU_64BIT))
FUNCTION Pjll_t j__udyAllocJLL2(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL2(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL2()
FUNCTION Pjll_t j__udyAllocJLL3(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL3(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL3()
#ifdef JU_64BIT
FUNCTION Pjll_t j__udyAllocJLL4(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL4(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL4()
FUNCTION Pjll_t j__udyAllocJLL5(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL5(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL5()
FUNCTION Pjll_t j__udyAllocJLL6(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL6(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL6()
FUNCTION Pjll_t j__udyAllocJLL7(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL7(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL7()
#endif // JU_64BIT
// Note: Root-level leaf addresses are always whole words (Pjlw_t), and unlike
// other j__udyAlloc*() functions, they are returned non-raw, that is, without
// malloc namespace or root pointer type bits (the latter are added later by
// the caller):
FUNCTION Pjlw_t j__udyAllocJLW(Word_t Pop1)
{
Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
Pjlw_t Pjlw = (Pjlw_t) MALLOC(JudyMalloc, Words, Words);
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLW(%lu), Words = %lu\n", Pjlw,
j__udyMemSequence++, Pop1, Words, Pop1);
// MALLOCBITS_SET(Pjlw_t, Pjlw); // see above.
return(Pjlw);
} // j__udyAllocJLW()
FUNCTION Pjlb_t j__udyAllocJLB1(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
Pjlb_t PjlbRaw;
PjlbRaw = (Pjlb_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jlb_t));
if ((Word_t) PjlbRaw > sizeof(Word_t))
{
ZEROWORDS(P_JLB(PjlbRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjlbRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJLB1(), Words = %lu\n", PjlbRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjlb_t, PjlbRaw);
return(PjlbRaw);
} // j__udyAllocJLB1()
#ifdef JUDYL
FUNCTION Pjv_t j__udyLAllocJV(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
Pjv_t PjvRaw;
PjvRaw = (Pjv_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjvRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjvRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyLAllocJV(%lu), Words = %lu\n", PjvRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjv_t, PjvRaw);
return(PjvRaw);
} // j__udyLAllocJV()
#endif // JUDYL
// ****************************************************************************
// FREE FUNCTIONS:
//
// To help the compiler catch coding errors, each function takes a specific
// object type to free.
// Note: j__udyFreeJPM() receives a root pointer with NO root pointer type
// bits present, that is, they must be stripped by the caller using P_JPM():
FUNCTION void j__udyFreeJPM(Pjpm_t PjpmFree, Pjpm_t PjpmStats)
{
Word_t Words = sizeof(jpm_t) / cJU_BYTESPERWORD;
// MALLOCBITS_TEST(Pjpm_t, PjpmFree); // see above.
JudyFree((Pvoid_t) PjpmFree, Words);
if (PjpmStats != (Pjpm_t) NULL) PjpmStats->jpm_TotalMemWords -= Words;
// Note: Log PjpmFree->jpm_Pop0, similar to other j__udyFree*() functions, not
// an assumed value of cJU_LEAFW_MAXPOP1, for when the caller is
// Judy*FreeArray(), jpm_Pop0 is set to 0, and the population after the free
// really will be 0, not cJU_LEAFW_MAXPOP1.
TRACE_FREE6("0x%x %8lu = j__udyFreeJPM(%lu), Words = %lu\n", PjpmFree,
j__udyMemSequence++, Words, Words, PjpmFree->jpm_Pop0);
} // j__udyFreeJPM()
FUNCTION void j__udyFreeJBL(Pjbl_t Pjbl, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbl_t, Pjbl);
JudyFreeVirtual((Pvoid_t) Pjbl, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBL(), Words = %lu\n", Pjbl,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBL()
FUNCTION void j__udyFreeJBB(Pjbb_t Pjbb, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbb_t, Pjbb);
JudyFreeVirtual((Pvoid_t) Pjbb, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBB(), Words = %lu\n", Pjbb,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBB()
FUNCTION void j__udyFreeJBBJP(Pjp_t Pjp, Word_t NumJPs, Pjpm_t Pjpm)
{
Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
MALLOCBITS_TEST(Pjp_t, Pjp);
JudyFree((Pvoid_t) Pjp, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJBBJP(%lu), Words = %lu\n", Pjp,
j__udyMemSequence++, NumJPs, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBBJP()
FUNCTION void j__udyFreeJBU(Pjbu_t Pjbu, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbu_t, Pjbu);
JudyFreeVirtual((Pvoid_t) Pjbu, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBU(), Words = %lu\n", Pjbu,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBU()
#if (defined(JUDYL) || (! defined(JU_64BIT)))
FUNCTION void j__udyFreeJLL1(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL1(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL1()
#endif // (JUDYL || (! JU_64BIT))
FUNCTION void j__udyFreeJLL2(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL2(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL2()
FUNCTION void j__udyFreeJLL3(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL3(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL3()
#ifdef JU_64BIT
FUNCTION void j__udyFreeJLL4(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL4(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL4()
FUNCTION void j__udyFreeJLL5(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL5(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL5()
FUNCTION void j__udyFreeJLL6(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL6(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL6()
FUNCTION void j__udyFreeJLL7(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL7(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL7()
#endif // JU_64BIT
// Note: j__udyFreeJLW() receives a root pointer with NO root pointer type
// bits present, that is, they are stripped by P_JLW():
FUNCTION void j__udyFreeJLW(Pjlw_t Pjlw, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
// MALLOCBITS_TEST(Pjlw_t, Pjlw); // see above.
JudyFree((Pvoid_t) Pjlw, Words);
if (Pjpm) Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLW(%lu), Words = %lu\n", Pjlw,
j__udyMemSequence++, Pop1, Words, Pop1 - 1);
} // j__udyFreeJLW()
FUNCTION void j__udyFreeJLB1(Pjlb_t Pjlb, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjlb_t, Pjlb);
JudyFree((Pvoid_t) Pjlb, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJLB1(), Words = %lu\n", Pjlb,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLB1()
#ifdef JUDYL
FUNCTION void j__udyLFreeJV(Pjv_t Pjv, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjv_t, Pjv);
JudyFree((Pvoid_t) Pjv, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyLFreeJV(%lu), Words = %lu\n", Pjv,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyLFreeJV()
#endif // JUDYL

View File

@ -0,0 +1,259 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Return number of bytes of memory used to support a Judy1/L array.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
FUNCTION static Word_t j__udyGetMemActive(Pjp_t);
// ****************************************************************************
// J U D Y 1 M E M A C T I V E
// J U D Y L M E M A C T I V E
#ifdef JUDY1
FUNCTION Word_t Judy1MemActive
#else
FUNCTION Word_t JudyLMemActive
#endif
(
Pcvoid_t PArray // from which to retrieve.
)
{
if (PArray == (Pcvoid_t)NULL) return(0);
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
Word_t Words = Pjlw[0] + 1; // population.
#ifdef JUDY1
return((Words + 1) * sizeof(Word_t));
#else
return(((Words * 2) + 1) * sizeof(Word_t));
#endif
}
else
{
Pjpm_t Pjpm = P_JPM(PArray);
return(j__udyGetMemActive(&Pjpm->jpm_JP) + sizeof(jpm_t));
}
} // JudyMemActive()
// ****************************************************************************
// __ J U D Y G E T M E M A C T I V E
FUNCTION static Word_t j__udyGetMemActive(
Pjp_t Pjp) // top of subtree.
{
Word_t offset; // in a branch.
Word_t Bytes = 0; // actual bytes used at this level.
Word_t IdxSz; // bytes per index in leaves
switch (JU_JPTYPE(Pjp))
{
case cJU_JPBRANCH_L2:
case cJU_JPBRANCH_L3:
#ifdef JU_64BIT
case cJU_JPBRANCH_L4:
case cJU_JPBRANCH_L5:
case cJU_JPBRANCH_L6:
case cJU_JPBRANCH_L7:
#endif
case cJU_JPBRANCH_L:
{
Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
for (offset = 0; offset < (Pjbl->jbl_NumJPs); ++offset)
Bytes += j__udyGetMemActive((Pjbl->jbl_jp) + offset);
return(Bytes + sizeof(jbl_t));
}
case cJU_JPBRANCH_B2:
case cJU_JPBRANCH_B3:
#ifdef JU_64BIT
case cJU_JPBRANCH_B4:
case cJU_JPBRANCH_B5:
case cJU_JPBRANCH_B6:
case cJU_JPBRANCH_B7:
#endif
case cJU_JPBRANCH_B:
{
Word_t subexp;
Word_t jpcount;
Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
Bytes += jpcount * sizeof(jp_t);
for (offset = 0; offset < jpcount; ++offset)
{
Bytes += j__udyGetMemActive(P_JP(JU_JBB_PJP(Pjbb, subexp))
+ offset);
}
}
return(Bytes + sizeof(jbb_t));
}
case cJU_JPBRANCH_U2:
case cJU_JPBRANCH_U3:
#ifdef JU_64BIT
case cJU_JPBRANCH_U4:
case cJU_JPBRANCH_U5:
case cJU_JPBRANCH_U6:
case cJU_JPBRANCH_U7:
#endif
case cJU_JPBRANCH_U:
{
Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
{
if (((Pjbu->jbu_jp[offset].jp_Type) >= cJU_JPNULL1)
&& ((Pjbu->jbu_jp[offset].jp_Type) <= cJU_JPNULLMAX))
{
continue; // skip null JP to save time.
}
Bytes += j__udyGetMemActive(Pjbu->jbu_jp + offset);
}
return(Bytes + sizeof(jbu_t));
}
// -- Cases below here terminate and do not recurse. --
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1: IdxSz = 1; goto LeafWords;
#endif
case cJU_JPLEAF2: IdxSz = 2; goto LeafWords;
case cJU_JPLEAF3: IdxSz = 3; goto LeafWords;
#ifdef JU_64BIT
case cJU_JPLEAF4: IdxSz = 4; goto LeafWords;
case cJU_JPLEAF5: IdxSz = 5; goto LeafWords;
case cJU_JPLEAF6: IdxSz = 6; goto LeafWords;
case cJU_JPLEAF7: IdxSz = 7; goto LeafWords;
#endif
LeafWords:
#ifdef JUDY1
return(IdxSz * (JU_JPLEAF_POP0(Pjp) + 1));
#else
return((IdxSz + sizeof(Word_t))
* (JU_JPLEAF_POP0(Pjp) + 1));
#endif
case cJU_JPLEAF_B1:
{
#ifdef JUDY1
return(sizeof(jlb_t));
#else
Bytes = (JU_JPLEAF_POP0(Pjp) + 1) * sizeof(Word_t);
return(Bytes + sizeof(jlb_t));
#endif
}
JUDY1CODE(case cJ1_JPFULLPOPU1: return(0);)
#ifdef JUDY1
#define J__Mpy 0
#else
#define J__Mpy sizeof(Word_t)
#endif
case cJU_JPIMMED_1_01: return(0);
case cJU_JPIMMED_2_01: return(0);
case cJU_JPIMMED_3_01: return(0);
#ifdef JU_64BIT
case cJU_JPIMMED_4_01: return(0);
case cJU_JPIMMED_5_01: return(0);
case cJU_JPIMMED_6_01: return(0);
case cJU_JPIMMED_7_01: return(0);
#endif
case cJU_JPIMMED_1_02: return(J__Mpy * 2);
case cJU_JPIMMED_1_03: return(J__Mpy * 3);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_1_04: return(J__Mpy * 4);
case cJU_JPIMMED_1_05: return(J__Mpy * 5);
case cJU_JPIMMED_1_06: return(J__Mpy * 6);
case cJU_JPIMMED_1_07: return(J__Mpy * 7);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_1_08: return(0);
case cJ1_JPIMMED_1_09: return(0);
case cJ1_JPIMMED_1_10: return(0);
case cJ1_JPIMMED_1_11: return(0);
case cJ1_JPIMMED_1_12: return(0);
case cJ1_JPIMMED_1_13: return(0);
case cJ1_JPIMMED_1_14: return(0);
case cJ1_JPIMMED_1_15: return(0);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_2_02: return(J__Mpy * 2);
case cJU_JPIMMED_2_03: return(J__Mpy * 3);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_2_04: return(0);
case cJ1_JPIMMED_2_05: return(0);
case cJ1_JPIMMED_2_06: return(0);
case cJ1_JPIMMED_2_07: return(0);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_3_02: return(J__Mpy * 2);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_3_03: return(0);
case cJ1_JPIMMED_3_04: return(0);
case cJ1_JPIMMED_3_05: return(0);
case cJ1_JPIMMED_4_02: return(0);
case cJ1_JPIMMED_4_03: return(0);
case cJ1_JPIMMED_5_02: return(0);
case cJ1_JPIMMED_5_03: return(0);
case cJ1_JPIMMED_6_02: return(0);
case cJ1_JPIMMED_7_02: return(0);
#endif
} // switch (JU_JPTYPE(Pjp))
return(0); // to make some compilers happy.
} // j__udyGetMemActive()

View File

@ -0,0 +1,61 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Return number of bytes of memory used to support a Judy1/L array.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
#ifdef JUDY1
FUNCTION Word_t Judy1MemUsed
#else // JUDYL
FUNCTION Word_t JudyLMemUsed
#endif
(
Pcvoid_t PArray // from which to retrieve.
)
{
Word_t Words = 0;
if (PArray == (Pcvoid_t) NULL) return(0);
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
Words = JU_LEAFWPOPTOWORDS(Pjlw[0] + 1); // based on pop1.
}
else
{
Pjpm_t Pjpm = P_JPM(PArray);
Words = Pjpm->jpm_TotalMemWords;
}
return(Words * sizeof(Word_t)); // convert to bytes.
} // Judy1MemUsed() / JudyLMemUsed()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,72 @@
// @(#) From generation tool: $Revision$ $Source$
//
#include "Judy1.h"
// Leave the malloc() sizes readable in the binary (via strings(1)):
const char * Judy1MallocSizes = "Judy1MallocSizes = 3, 5, 7, 11, 15, 23, 32, 47, 64, Leaf1 = 20";
// object uses 64 words
// cJU_BITSPERSUBEXPB = 32
const uint8_t
j__1_BranchBJPPopToWords[cJU_BITSPERSUBEXPB + 1] =
{
0,
3, 5, 7, 11, 11, 15, 15, 23,
23, 23, 23, 32, 32, 32, 32, 32,
47, 47, 47, 47, 47, 47, 47, 64,
64, 64, 64, 64, 64, 64, 64, 64
};
// object uses 5 words
// cJ1_LEAF1_MAXPOP1 = 20
const uint8_t
j__1_Leaf1PopToWords[cJ1_LEAF1_MAXPOP1 + 1] =
{
0,
3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 5, 5, 5, 5,
5, 5, 5, 5
};
// object uses 32 words
// cJ1_LEAF2_MAXPOP1 = 64
const uint8_t
j__1_Leaf2PopToWords[cJ1_LEAF2_MAXPOP1 + 1] =
{
0,
3, 3, 3, 3, 3, 3, 5, 5,
5, 5, 7, 7, 7, 7, 11, 11,
11, 11, 11, 11, 11, 11, 15, 15,
15, 15, 15, 15, 15, 15, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32
};
// object uses 32 words
// cJ1_LEAF3_MAXPOP1 = 42
const uint8_t
j__1_Leaf3PopToWords[cJ1_LEAF3_MAXPOP1 + 1] =
{
0,
3, 3, 3, 3, 5, 5, 7, 7,
7, 11, 11, 11, 11, 11, 15, 15,
15, 15, 15, 15, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32
};
// object uses 32 words
// cJ1_LEAFW_MAXPOP1 = 31
const uint8_t
j__1_LeafWPopToWords[cJ1_LEAFW_MAXPOP1 + 1] =
{
0,
3, 3, 5, 5, 7, 7, 11, 11,
11, 11, 15, 15, 15, 15, 23, 23,
23, 23, 23, 23, 23, 23, 32, 32,
32, 32, 32, 32, 32, 32, 32
};

View File

@ -0,0 +1,296 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
#ifndef JU_WIN
#include <unistd.h> // unavailable on win_*.
#endif
#include <stdlib.h>
#include <stdio.h>
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#define TERMINATOR 999 // terminator for Alloc tables
#define BPW sizeof(Word_t) // define bytes per word
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
FILE *fd;
// Definitions come from header files Judy1.h and JudyL.h:
int AllocSizes[] = ALLOCSIZES;
#define ROUNDUP(BYTES,BPW,OFFSETW) \
((((BYTES) + (BPW) - 1) / (BPW)) + (OFFSETW))
// ****************************************************************************
// G E N T A B L E
//
// Note: "const" is required for newer compilers.
FUNCTION void GenTable(
const char * TableName, // name of table string
const char * TableSize, // dimentioned size string
int IndexBytes, // bytes per Index
int LeafSize, // number elements in object
int ValueBytes, // bytes per Value
int OffsetWords) // 1 for LEAFW
{
int * PAllocSizes = AllocSizes;
int OWord;
int CurWord;
int IWord;
int ii;
int BytesOfIndex;
int BytesOfObject;
int Index;
int LastWords;
int Words [1000] = { 0 };
int Offset[1000] = { 0 };
int MaxWords;
MaxWords = ROUNDUP((IndexBytes + ValueBytes) * LeafSize, BPW, OffsetWords);
Words[0] = 0;
Offset[0] = 0;
CurWord = TERMINATOR;
// Walk through all number of Indexes in table:
for (Index = 1; /* null */; ++Index)
{
// Calculate byte required for next size:
BytesOfIndex = IndexBytes * Index;
BytesOfObject = (IndexBytes + ValueBytes) * Index;
// Round up and calculate words required for next size:
OWord = ROUNDUP(BytesOfObject, BPW, OffsetWords);
IWord = ROUNDUP(BytesOfIndex, BPW, OffsetWords);
// Root-level leaves of population of 1 and 2 do not have the 1 word offset:
// Save minimum value of offset:
Offset[Index] = IWord;
// Round up to next available size of words:
while (OWord > *PAllocSizes) PAllocSizes++;
if (Index == LeafSize)
{
CurWord = Words[Index] = OWord;
break;
}
// end of available sizes ?
if (*PAllocSizes == TERMINATOR)
{
fprintf(stderr, "BUG, in %sPopToWords, sizes not big enough for object\n", TableName);
exit(1);
}
// Save words required and last word:
if (*PAllocSizes < MaxWords) { CurWord = Words[Index] = *PAllocSizes; }
else { CurWord = Words[Index] = MaxWords; }
} // for each index
LastWords = TERMINATOR;
// Round up to largest size in each group of malloc sizes:
for (ii = LeafSize; ii > 0; ii--)
{
if (LastWords > (Words[ii] - ii)) LastWords = Offset[ii];
else Offset[ii] = LastWords;
}
// Print the PopToWords[] table:
fprintf(fd,"\n//\tobject uses %d words\n", CurWord);
fprintf(fd,"//\t%s = %d\n", TableSize, LeafSize);
fprintf(fd,"const uint8_t\n");
fprintf(fd,"%sPopToWords[%s + 1] =\n", TableName, TableSize);
fprintf(fd,"{\n\t 0,");
for (ii = 1; ii <= LeafSize; ii++)
{
// 8 columns per line, starting with 1:
if ((ii % 8) == 1) fprintf(fd,"\n\t");
fprintf(fd,"%2d", Words[ii]);
// If not last number place comma:
if (ii != LeafSize) fprintf(fd,", ");
}
fprintf(fd,"\n};\n");
// Print the Offset table if needed:
if (! ValueBytes) return;
fprintf(fd,"const uint8_t\n");
fprintf(fd,"%sOffset[%s + 1] =\n", TableName, TableSize);
fprintf(fd,"{\n");
fprintf(fd,"\t 0,");
for (ii = 1; ii <= LeafSize; ii++)
{
if ((ii % 8) == 1) fprintf(fd,"\n\t");
fprintf(fd,"%2d", Offset[ii]);
if (ii != LeafSize) fprintf(fd,", ");
}
fprintf(fd,"\n};\n");
} // GenTable()
// ****************************************************************************
// M A I N
FUNCTION int main()
{
int ii;
#ifdef JUDY1
char *fname = "Judy1Tables.c";
#else
char *fname = "JudyLTables.c";
#endif
if ((fd = fopen(fname, "w")) == NULL){
perror("FATAL ERROR: could not write to Judy[1L]Tables.c file\n");
return (-1);
}
fprintf(fd,"// @(#) From generation tool: $Revision$ $Source$\n");
fprintf(fd,"//\n\n");
// ================================ Judy1 =================================
#ifdef JUDY1
fprintf(fd,"#include \"Judy1.h\"\n");
fprintf(fd,"// Leave the malloc() sizes readable in the binary (via "
"strings(1)):\n");
fprintf(fd,"const char * Judy1MallocSizes = \"Judy1MallocSizes =");
for (ii = 0; AllocSizes[ii] != TERMINATOR; ii++)
fprintf(fd," %d,", AllocSizes[ii]);
#ifndef JU_64BIT
fprintf(fd," Leaf1 = %d\";\n\n", cJ1_LEAF1_MAXPOP1);
#else
fprintf(fd,"\";\n\n"); // no Leaf1 in this case.
#endif
// ================================ 32 bit ================================
#ifndef JU_64BIT
GenTable("j__1_BranchBJP","cJU_BITSPERSUBEXPB", 8, cJU_BITSPERSUBEXPB,0,0);
GenTable("j__1_Leaf1", "cJ1_LEAF1_MAXPOP1", 1, cJ1_LEAF1_MAXPOP1, 0, 0);
GenTable("j__1_Leaf2", "cJ1_LEAF2_MAXPOP1", 2, cJ1_LEAF2_MAXPOP1, 0, 0);
GenTable("j__1_Leaf3", "cJ1_LEAF3_MAXPOP1", 3, cJ1_LEAF3_MAXPOP1, 0, 0);
GenTable("j__1_LeafW", "cJ1_LEAFW_MAXPOP1", 4, cJ1_LEAFW_MAXPOP1, 0, 1);
#endif
// ================================ 64 bit ================================
#ifdef JU_64BIT
GenTable("j__1_BranchBJP","cJU_BITSPERSUBEXPB",16, cJU_BITSPERSUBEXPB,0,0);
GenTable("j__1_Leaf2", "cJ1_LEAF2_MAXPOP1", 2, cJ1_LEAF2_MAXPOP1, 0, 0);
GenTable("j__1_Leaf3", "cJ1_LEAF3_MAXPOP1", 3, cJ1_LEAF3_MAXPOP1, 0, 0);
GenTable("j__1_Leaf4", "cJ1_LEAF4_MAXPOP1", 4, cJ1_LEAF4_MAXPOP1, 0, 0);
GenTable("j__1_Leaf5", "cJ1_LEAF5_MAXPOP1", 5, cJ1_LEAF5_MAXPOP1, 0, 0);
GenTable("j__1_Leaf6", "cJ1_LEAF6_MAXPOP1", 6, cJ1_LEAF6_MAXPOP1, 0, 0);
GenTable("j__1_Leaf7", "cJ1_LEAF7_MAXPOP1", 7, cJ1_LEAF7_MAXPOP1, 0, 0);
GenTable("j__1_LeafW", "cJ1_LEAFW_MAXPOP1", 8, cJ1_LEAFW_MAXPOP1, 0, 1);
#endif
#endif // JUDY1
// ================================ JudyL =================================
#ifdef JUDYL
fprintf(fd,"#include \"JudyL.h\"\n");
fprintf(fd,"// Leave the malloc() sizes readable in the binary (via "
"strings(1)):\n");
fprintf(fd,"const char * JudyLMallocSizes = \"JudyLMallocSizes =");
for (ii = 0; AllocSizes[ii] != TERMINATOR; ii++)
fprintf(fd," %d,", AllocSizes[ii]);
fprintf(fd," Leaf1 = %ld\";\n\n", (Word_t)cJL_LEAF1_MAXPOP1);
#ifndef JU_64BIT
// ================================ 32 bit ================================
GenTable("j__L_BranchBJP","cJU_BITSPERSUBEXPB", 8, cJU_BITSPERSUBEXPB, 0,0);
GenTable("j__L_Leaf1", "cJL_LEAF1_MAXPOP1", 1, cJL_LEAF1_MAXPOP1, BPW,0);
GenTable("j__L_Leaf2", "cJL_LEAF2_MAXPOP1", 2, cJL_LEAF2_MAXPOP1, BPW,0);
GenTable("j__L_Leaf3", "cJL_LEAF3_MAXPOP1", 3, cJL_LEAF3_MAXPOP1, BPW,0);
GenTable("j__L_LeafW", "cJL_LEAFW_MAXPOP1", 4, cJL_LEAFW_MAXPOP1, BPW,1);
GenTable("j__L_LeafV", "cJU_BITSPERSUBEXPL", 4, cJU_BITSPERSUBEXPL, 0,0);
#endif // 32 BIT
#ifdef JU_64BIT
// ================================ 64 bit ================================
GenTable("j__L_BranchBJP","cJU_BITSPERSUBEXPB",16, cJU_BITSPERSUBEXPB, 0,0);
GenTable("j__L_Leaf1", "cJL_LEAF1_MAXPOP1", 1, cJL_LEAF1_MAXPOP1, BPW,0);
GenTable("j__L_Leaf2", "cJL_LEAF2_MAXPOP1", 2, cJL_LEAF2_MAXPOP1, BPW,0);
GenTable("j__L_Leaf3", "cJL_LEAF3_MAXPOP1", 3, cJL_LEAF3_MAXPOP1, BPW,0);
GenTable("j__L_Leaf4", "cJL_LEAF4_MAXPOP1", 4, cJL_LEAF4_MAXPOP1, BPW,0);
GenTable("j__L_Leaf5", "cJL_LEAF5_MAXPOP1", 5, cJL_LEAF5_MAXPOP1, BPW,0);
GenTable("j__L_Leaf6", "cJL_LEAF6_MAXPOP1", 6, cJL_LEAF6_MAXPOP1, BPW,0);
GenTable("j__L_Leaf7", "cJL_LEAF7_MAXPOP1", 7, cJL_LEAF7_MAXPOP1, BPW,0);
GenTable("j__L_LeafW", "cJL_LEAFW_MAXPOP1", 8, cJL_LEAFW_MAXPOP1, BPW,1);
GenTable("j__L_LeafV", "cJU_BITSPERSUBEXPL", 8, cJU_BITSPERSUBEXPL, 0,0);
#endif // 64 BIT
#endif // JUDYL
fclose(fd);
return(0);
} // main()

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
INCLUDES = -I. -I.. -I../JudyCommon/
AM_CFLAGS = -DJUDY1 @WARN_CFLAGS@
noinst_LTLIBRARIES = libJudy1.la libnext.la libprev.la libcount.la libinline.la
libJudy1_la_SOURCES = Judy1Test.c Judy1Tables.c Judy1Set.c Judy1SetArray.c Judy1Unset.c Judy1Cascade.c Judy1Count.c Judy1CreateBranch.c Judy1Decascade.c Judy1First.c Judy1FreeArray.c Judy1InsertBranch.c Judy1MallocIF.c Judy1MemActive.c Judy1MemUsed.c
libnext_la_SOURCES = Judy1Next.c Judy1NextEmpty.c
libnext_la_CFLAGS = $(AM_CFLAGS) -DJUDYNEXT
libprev_la_SOURCES = Judy1Prev.c Judy1PrevEmpty.c
libprev_la_CFLAGS = $(AM_CFLAGS) -DJUDYPREV
libcount_la_SOURCES = Judy1ByCount.c
libcount_la_CFLAGS = $(AM_CFLAGS) -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB
libinline_la_SOURCES = j__udy1Test.c
libinline_la_CFLAGS = $(AM_CFLAGS) -DJUDYGETINLINE
Judy1Tables.c: Judy1TablesGen.c
$(CC) $(INCLUDES) $(AM_CFLAGS) @CFLAGS@ -o Judy1TablesGen Judy1TablesGen.c; ./Judy1TablesGen
Judy1Test.c: copies
copies:
cp -f ../JudyCommon/JudyByCount.c Judy1ByCount.c
cp -f ../JudyCommon/JudyCascade.c Judy1Cascade.c
cp -f ../JudyCommon/JudyCount.c Judy1Count.c
cp -f ../JudyCommon/JudyCreateBranch.c Judy1CreateBranch.c
cp -f ../JudyCommon/JudyDecascade.c Judy1Decascade.c
cp -f ../JudyCommon/JudyDel.c Judy1Unset.c
cp -f ../JudyCommon/JudyFirst.c Judy1First.c
cp -f ../JudyCommon/JudyFreeArray.c Judy1FreeArray.c
cp -f ../JudyCommon/JudyGet.c Judy1Test.c
cp -f ../JudyCommon/JudyGet.c j__udy1Test.c
cp -f ../JudyCommon/JudyInsArray.c Judy1SetArray.c
cp -f ../JudyCommon/JudyIns.c Judy1Set.c
cp -f ../JudyCommon/JudyInsertBranch.c Judy1InsertBranch.c
cp -f ../JudyCommon/JudyMallocIF.c Judy1MallocIF.c
cp -f ../JudyCommon/JudyMemActive.c Judy1MemActive.c
cp -f ../JudyCommon/JudyMemUsed.c Judy1MemUsed.c
cp -f ../JudyCommon/JudyPrevNext.c Judy1Next.c
cp -f ../JudyCommon/JudyPrevNext.c Judy1Prev.c
cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1NextEmpty.c
cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1PrevEmpty.c
cp -f ../JudyCommon/JudyTables.c Judy1TablesGen.c

View File

@ -0,0 +1,558 @@
# Makefile.in generated by automake 1.9.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SOURCES = $(libJudy1_la_SOURCES) $(libcount_la_SOURCES) $(libinline_la_SOURCES) $(libnext_la_SOURCES) $(libprev_la_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/Judy1
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libJudy1_la_LIBADD =
am_libJudy1_la_OBJECTS = Judy1Test.lo Judy1Tables.lo Judy1Set.lo \
Judy1SetArray.lo Judy1Unset.lo Judy1Cascade.lo Judy1Count.lo \
Judy1CreateBranch.lo Judy1Decascade.lo Judy1First.lo \
Judy1FreeArray.lo Judy1InsertBranch.lo Judy1MallocIF.lo \
Judy1MemActive.lo Judy1MemUsed.lo
libJudy1_la_OBJECTS = $(am_libJudy1_la_OBJECTS)
libcount_la_LIBADD =
am_libcount_la_OBJECTS = libcount_la-Judy1ByCount.lo
libcount_la_OBJECTS = $(am_libcount_la_OBJECTS)
libinline_la_LIBADD =
am_libinline_la_OBJECTS = libinline_la-j__udy1Test.lo
libinline_la_OBJECTS = $(am_libinline_la_OBJECTS)
libnext_la_LIBADD =
am_libnext_la_OBJECTS = libnext_la-Judy1Next.lo \
libnext_la-Judy1NextEmpty.lo
libnext_la_OBJECTS = $(am_libnext_la_OBJECTS)
libprev_la_LIBADD =
am_libprev_la_OBJECTS = libprev_la-Judy1Prev.lo \
libprev_la-Judy1PrevEmpty.lo
libprev_la_OBJECTS = $(am_libprev_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libJudy1_la_SOURCES) $(libcount_la_SOURCES) \
$(libinline_la_SOURCES) $(libnext_la_SOURCES) \
$(libprev_la_SOURCES)
DIST_SOURCES = $(libJudy1_la_SOURCES) $(libcount_la_SOURCES) \
$(libinline_la_SOURCES) $(libnext_la_SOURCES) \
$(libprev_la_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
FLAVOR = @FLAVOR@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
VERSION_INFO = @VERSION_INFO@
WARN_CFLAGS = @WARN_CFLAGS@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
ac_ct_LD = @ac_ct_LD@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
INCLUDES = -I. -I.. -I../JudyCommon/
AM_CFLAGS = -DJUDY1 @WARN_CFLAGS@
noinst_LTLIBRARIES = libJudy1.la libnext.la libprev.la libcount.la libinline.la
libJudy1_la_SOURCES = Judy1Test.c Judy1Tables.c Judy1Set.c Judy1SetArray.c Judy1Unset.c Judy1Cascade.c Judy1Count.c Judy1CreateBranch.c Judy1Decascade.c Judy1First.c Judy1FreeArray.c Judy1InsertBranch.c Judy1MallocIF.c Judy1MemActive.c Judy1MemUsed.c
libnext_la_SOURCES = Judy1Next.c Judy1NextEmpty.c
libnext_la_CFLAGS = $(AM_CFLAGS) -DJUDYNEXT
libprev_la_SOURCES = Judy1Prev.c Judy1PrevEmpty.c
libprev_la_CFLAGS = $(AM_CFLAGS) -DJUDYPREV
libcount_la_SOURCES = Judy1ByCount.c
libcount_la_CFLAGS = $(AM_CFLAGS) -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB
libinline_la_SOURCES = j__udy1Test.c
libinline_la_CFLAGS = $(AM_CFLAGS) -DJUDYGETINLINE
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Judy1/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Judy1/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libJudy1.la: $(libJudy1_la_OBJECTS) $(libJudy1_la_DEPENDENCIES)
$(LINK) $(libJudy1_la_LDFLAGS) $(libJudy1_la_OBJECTS) $(libJudy1_la_LIBADD) $(LIBS)
libcount.la: $(libcount_la_OBJECTS) $(libcount_la_DEPENDENCIES)
$(LINK) $(libcount_la_LDFLAGS) $(libcount_la_OBJECTS) $(libcount_la_LIBADD) $(LIBS)
libinline.la: $(libinline_la_OBJECTS) $(libinline_la_DEPENDENCIES)
$(LINK) $(libinline_la_LDFLAGS) $(libinline_la_OBJECTS) $(libinline_la_LIBADD) $(LIBS)
libnext.la: $(libnext_la_OBJECTS) $(libnext_la_DEPENDENCIES)
$(LINK) $(libnext_la_LDFLAGS) $(libnext_la_OBJECTS) $(libnext_la_LIBADD) $(LIBS)
libprev.la: $(libprev_la_OBJECTS) $(libprev_la_DEPENDENCIES)
$(LINK) $(libprev_la_LDFLAGS) $(libprev_la_OBJECTS) $(libprev_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Cascade.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Count.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1CreateBranch.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Decascade.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1First.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1FreeArray.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1InsertBranch.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1MallocIF.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1MemActive.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1MemUsed.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Set.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1SetArray.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Tables.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Test.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Unset.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcount_la-Judy1ByCount.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libinline_la-j__udy1Test.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnext_la-Judy1Next.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnext_la-Judy1NextEmpty.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libprev_la-Judy1Prev.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libprev_la-Judy1PrevEmpty.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
libcount_la-Judy1ByCount.lo: Judy1ByCount.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcount_la_CFLAGS) $(CFLAGS) -MT libcount_la-Judy1ByCount.lo -MD -MP -MF "$(DEPDIR)/libcount_la-Judy1ByCount.Tpo" -c -o libcount_la-Judy1ByCount.lo `test -f 'Judy1ByCount.c' || echo '$(srcdir)/'`Judy1ByCount.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libcount_la-Judy1ByCount.Tpo" "$(DEPDIR)/libcount_la-Judy1ByCount.Plo"; else rm -f "$(DEPDIR)/libcount_la-Judy1ByCount.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='Judy1ByCount.c' object='libcount_la-Judy1ByCount.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcount_la_CFLAGS) $(CFLAGS) -c -o libcount_la-Judy1ByCount.lo `test -f 'Judy1ByCount.c' || echo '$(srcdir)/'`Judy1ByCount.c
libinline_la-j__udy1Test.lo: j__udy1Test.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libinline_la_CFLAGS) $(CFLAGS) -MT libinline_la-j__udy1Test.lo -MD -MP -MF "$(DEPDIR)/libinline_la-j__udy1Test.Tpo" -c -o libinline_la-j__udy1Test.lo `test -f 'j__udy1Test.c' || echo '$(srcdir)/'`j__udy1Test.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libinline_la-j__udy1Test.Tpo" "$(DEPDIR)/libinline_la-j__udy1Test.Plo"; else rm -f "$(DEPDIR)/libinline_la-j__udy1Test.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='j__udy1Test.c' object='libinline_la-j__udy1Test.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libinline_la_CFLAGS) $(CFLAGS) -c -o libinline_la-j__udy1Test.lo `test -f 'j__udy1Test.c' || echo '$(srcdir)/'`j__udy1Test.c
libnext_la-Judy1Next.lo: Judy1Next.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnext_la_CFLAGS) $(CFLAGS) -MT libnext_la-Judy1Next.lo -MD -MP -MF "$(DEPDIR)/libnext_la-Judy1Next.Tpo" -c -o libnext_la-Judy1Next.lo `test -f 'Judy1Next.c' || echo '$(srcdir)/'`Judy1Next.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libnext_la-Judy1Next.Tpo" "$(DEPDIR)/libnext_la-Judy1Next.Plo"; else rm -f "$(DEPDIR)/libnext_la-Judy1Next.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='Judy1Next.c' object='libnext_la-Judy1Next.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnext_la_CFLAGS) $(CFLAGS) -c -o libnext_la-Judy1Next.lo `test -f 'Judy1Next.c' || echo '$(srcdir)/'`Judy1Next.c
libnext_la-Judy1NextEmpty.lo: Judy1NextEmpty.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnext_la_CFLAGS) $(CFLAGS) -MT libnext_la-Judy1NextEmpty.lo -MD -MP -MF "$(DEPDIR)/libnext_la-Judy1NextEmpty.Tpo" -c -o libnext_la-Judy1NextEmpty.lo `test -f 'Judy1NextEmpty.c' || echo '$(srcdir)/'`Judy1NextEmpty.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libnext_la-Judy1NextEmpty.Tpo" "$(DEPDIR)/libnext_la-Judy1NextEmpty.Plo"; else rm -f "$(DEPDIR)/libnext_la-Judy1NextEmpty.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='Judy1NextEmpty.c' object='libnext_la-Judy1NextEmpty.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnext_la_CFLAGS) $(CFLAGS) -c -o libnext_la-Judy1NextEmpty.lo `test -f 'Judy1NextEmpty.c' || echo '$(srcdir)/'`Judy1NextEmpty.c
libprev_la-Judy1Prev.lo: Judy1Prev.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libprev_la_CFLAGS) $(CFLAGS) -MT libprev_la-Judy1Prev.lo -MD -MP -MF "$(DEPDIR)/libprev_la-Judy1Prev.Tpo" -c -o libprev_la-Judy1Prev.lo `test -f 'Judy1Prev.c' || echo '$(srcdir)/'`Judy1Prev.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libprev_la-Judy1Prev.Tpo" "$(DEPDIR)/libprev_la-Judy1Prev.Plo"; else rm -f "$(DEPDIR)/libprev_la-Judy1Prev.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='Judy1Prev.c' object='libprev_la-Judy1Prev.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libprev_la_CFLAGS) $(CFLAGS) -c -o libprev_la-Judy1Prev.lo `test -f 'Judy1Prev.c' || echo '$(srcdir)/'`Judy1Prev.c
libprev_la-Judy1PrevEmpty.lo: Judy1PrevEmpty.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libprev_la_CFLAGS) $(CFLAGS) -MT libprev_la-Judy1PrevEmpty.lo -MD -MP -MF "$(DEPDIR)/libprev_la-Judy1PrevEmpty.Tpo" -c -o libprev_la-Judy1PrevEmpty.lo `test -f 'Judy1PrevEmpty.c' || echo '$(srcdir)/'`Judy1PrevEmpty.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libprev_la-Judy1PrevEmpty.Tpo" "$(DEPDIR)/libprev_la-Judy1PrevEmpty.Plo"; else rm -f "$(DEPDIR)/libprev_la-Judy1PrevEmpty.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='Judy1PrevEmpty.c' object='libprev_la-Judy1PrevEmpty.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libprev_la_CFLAGS) $(CFLAGS) -c -o libprev_la-Judy1PrevEmpty.lo `test -f 'Judy1PrevEmpty.c' || echo '$(srcdir)/'`Judy1PrevEmpty.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \
uninstall-info-am
Judy1Tables.c: Judy1TablesGen.c
$(CC) $(INCLUDES) $(AM_CFLAGS) @CFLAGS@ -o Judy1TablesGen Judy1TablesGen.c; ./Judy1TablesGen
Judy1Test.c: copies
copies:
cp -f ../JudyCommon/JudyByCount.c Judy1ByCount.c
cp -f ../JudyCommon/JudyCascade.c Judy1Cascade.c
cp -f ../JudyCommon/JudyCount.c Judy1Count.c
cp -f ../JudyCommon/JudyCreateBranch.c Judy1CreateBranch.c
cp -f ../JudyCommon/JudyDecascade.c Judy1Decascade.c
cp -f ../JudyCommon/JudyDel.c Judy1Unset.c
cp -f ../JudyCommon/JudyFirst.c Judy1First.c
cp -f ../JudyCommon/JudyFreeArray.c Judy1FreeArray.c
cp -f ../JudyCommon/JudyGet.c Judy1Test.c
cp -f ../JudyCommon/JudyGet.c j__udy1Test.c
cp -f ../JudyCommon/JudyInsArray.c Judy1SetArray.c
cp -f ../JudyCommon/JudyIns.c Judy1Set.c
cp -f ../JudyCommon/JudyInsertBranch.c Judy1InsertBranch.c
cp -f ../JudyCommon/JudyMallocIF.c Judy1MallocIF.c
cp -f ../JudyCommon/JudyMemActive.c Judy1MemActive.c
cp -f ../JudyCommon/JudyMemUsed.c Judy1MemUsed.c
cp -f ../JudyCommon/JudyPrevNext.c Judy1Next.c
cp -f ../JudyCommon/JudyPrevNext.c Judy1Prev.c
cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1NextEmpty.c
cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1PrevEmpty.c
cp -f ../JudyCommon/JudyTables.c Judy1TablesGen.c
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,11 @@
# @(#) $Revision$ $Source$
# This tree contains sources for the Judy1*() functions.
#
# Note: At one time, all of the Judy sources were split between Judy1/ and
# JudyL/ variants, but now most of them are merged in JudyCommon/ and this
# directory is vestigal.
Judy1.h header for following functions
lint.waivers see usage in makefile

File diff suppressed because it is too large Load Diff