X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibmdb%2Fmidl.c;h=a3844d6875f19750eb537fa17cd8090411542385;hb=fbf9c233045881e85ca2eaafd930af404bf39f86;hp=7932d3caeea3dfe779f757d6707243e1a9eb0cbd;hpb=963c421a971cc4e95947f3ff20a70a6cc8c9cb5d;p=openldap diff --git a/libraries/libmdb/midl.c b/libraries/libmdb/midl.c index 7932d3caee..a3844d6875 100644 --- a/libraries/libmdb/midl.c +++ b/libraries/libmdb/midl.c @@ -3,7 +3,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2000-2011 The OpenLDAP Foundation. + * Copyright 2000-2012 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -15,7 +15,9 @@ * . */ +#include #include +#include #include #include #include "midl.h" @@ -29,7 +31,7 @@ #define CMP(x,y) ( (x) < (y) ? -1 : (x) > (y) ) #if 0 /* superseded by append/sort */ -static unsigned mdb_midl_search( IDL ids, ID id ) +static unsigned mdb_midl_search( MDB_IDL ids, MDB_ID id ) { /* * binary search of id in ids @@ -37,45 +39,44 @@ static unsigned mdb_midl_search( IDL ids, ID id ) * if not found, returns first position greater than id */ unsigned base = 0; - unsigned cursor = 0; + unsigned cursor = 1; int val = 0; unsigned n = ids[0]; while( 0 < n ) { - int pivot = n >> 1; - cursor = base + pivot; - val = CMP( ids[cursor + 1], id ); + unsigned pivot = n >> 1; + cursor = base + pivot + 1; + val = CMP( ids[cursor], id ); if( val < 0 ) { n = pivot; } else if ( val > 0 ) { - base = cursor + 1; + base = cursor; n -= pivot + 1; } else { - return cursor + 1; + return cursor; } } if( val > 0 ) { - return cursor + 2; - } else { - return cursor + 1; + ++cursor; } + return cursor; } -int mdb_midl_insert( IDL ids, ID id ) +int mdb_midl_insert( MDB_IDL ids, MDB_ID id ) { unsigned x, i; if (MDB_IDL_IS_RANGE( ids )) { /* if already in range, treat as a dup */ - if (id >= MDB_IDL_FIRST(ids) && id <= MDB_IDL_LAST(ids)) + if (id >= MDB_IDL_RANGE_FIRST(ids) && id <= MDB_IDL_RANGE_LAST(ids)) return -1; - if (id < MDB_IDL_FIRST(ids)) + if (id < MDB_IDL_RANGE_FIRST(ids)) ids[1] = id; - else if (id > MDB_IDL_LAST(ids)) + else if (id > MDB_IDL_RANGE_LAST(ids)) ids[2] = id; return 0; } @@ -103,7 +104,7 @@ int mdb_midl_insert( IDL ids, ID id ) } else { ids[2] = ids[ids[0]-1]; } - ids[0] = NOID; + ids[0] = MDB_NOID; } else { /* insert id */ @@ -116,27 +117,80 @@ int mdb_midl_insert( IDL ids, ID id ) } #endif -int mdb_midl_append( IDL ids, ID id ) +MDB_IDL mdb_midl_alloc() +{ + MDB_IDL ids = malloc((MDB_IDL_UM_MAX+1) * sizeof(MDB_ID)); + *ids++ = MDB_IDL_UM_MAX; + return ids; +} + +void mdb_midl_free(MDB_IDL ids) +{ + free(ids-1); +} + +int mdb_midl_shrink( MDB_IDL *idp ) +{ + MDB_IDL ids = *idp; + if (ids[-1] > MDB_IDL_UM_MAX) { + ids = realloc(ids, (MDB_IDL_UM_MAX+1) * sizeof(MDB_ID)); + *ids++ = MDB_IDL_UM_MAX; + *idp = ids; + return 1; + } + return 0; +} + +int mdb_midl_append( MDB_IDL *idp, MDB_ID id ) { + MDB_IDL ids = *idp; /* Too big? */ - if (ids[0] >= MDB_IDL_UM_MAX) - return -1; + if (ids[0] >= ids[-1]) { + MDB_IDL idn = ids-1; + /* grow it */ + idn = realloc(idn, (*idn + MDB_IDL_UM_MAX + 1) * sizeof(MDB_ID)); + if (!idn) + return -1; + *idn++ += MDB_IDL_UM_MAX; + ids = idn; + *idp = ids; + } ids[0]++; ids[ids[0]] = id; return 0; } +int mdb_midl_append_list( MDB_IDL *idp, MDB_IDL app ) +{ + MDB_IDL ids = *idp; + /* Too big? */ + if (ids[0] + app[0] >= ids[-1]) { + MDB_IDL idn = ids-1; + /* grow it */ + idn = realloc(idn, (*idn + app[-1]) * sizeof(MDB_ID)); + if (!idn) + return -1; + *idn++ += app[-1]; + ids = idn; + *idp = ids; + } + memcpy(&ids[ids[0]+1], &app[1], app[0] * sizeof(MDB_ID)); + ids[0] += app[0]; + return 0; +} + /* Quicksort + Insertion sort for small arrays */ #define SMALL 8 -#define SWAP(a,b) itmp=(a);(a)=(b);(b)=itmp +#define SWAP(a,b) { itmp=(a); (a)=(b); (b)=itmp; } void -mdb_midl_sort( ID *ids ) +mdb_midl_sort( MDB_IDL ids ) { - int istack[16*sizeof(int)]; + /* Max possible depth of int-indexed tree * 2 items/level */ + int istack[sizeof(int)*CHAR_BIT * 2]; int i,j,k,l,ir,jstack; - ID a, itmp; + MDB_ID a, itmp; ir = ids[0]; l = 1; @@ -191,7 +245,7 @@ mdb_midl_sort( ID *ids ) } } -unsigned mdb_mid2l_search( ID2L ids, ID id ) +unsigned mdb_mid2l_search( MDB_ID2L ids, MDB_ID id ) { /* * binary search of id in ids @@ -199,35 +253,34 @@ unsigned mdb_mid2l_search( ID2L ids, ID id ) * if not found, returns first position greater than id */ unsigned base = 0; - unsigned cursor = 0; + unsigned cursor = 1; int val = 0; unsigned n = ids[0].mid; while( 0 < n ) { - int pivot = n >> 1; - cursor = base + pivot; - val = CMP( id, ids[cursor + 1].mid ); + unsigned pivot = n >> 1; + cursor = base + pivot + 1; + val = CMP( id, ids[cursor].mid ); if( val < 0 ) { n = pivot; } else if ( val > 0 ) { - base = cursor + 1; + base = cursor; n -= pivot + 1; } else { - return cursor + 1; + return cursor; } } if( val > 0 ) { - return cursor + 2; - } else { - return cursor + 1; + ++cursor; } + return cursor; } -int mdb_mid2l_insert( ID2L ids, ID2 *id ) +int mdb_mid2l_insert( MDB_ID2L ids, MDB_ID2 *id ) { unsigned x, i;