X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibmdb%2Fmidl.c;h=a2cb86165961ca4dc92b7336f1d5cc90c6a0260a;hb=d50d57ed63a4fd29d90da3b7de9cc105fff63a3e;hp=7a7b59c7c0e053cb752defb001c2a3e253fd1ea2;hpb=5f682934751d54263df19f3b181f1555158daf25;p=openldap diff --git a/libraries/libmdb/midl.c b/libraries/libmdb/midl.c index 7a7b59c7c0..a2cb861659 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 @@ -17,6 +17,7 @@ #include #include +#include #include #include #include "midl.h" @@ -38,32 +39,31 @@ 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 ) @@ -72,11 +72,11 @@ int mdb_midl_insert( IDL ids, ID id ) 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; } @@ -117,23 +117,75 @@ int mdb_midl_insert( IDL ids, ID id ) } #endif -int mdb_midl_append( IDL ids, ID id ) +IDL mdb_midl_alloc() +{ + IDL ids = malloc((MDB_IDL_UM_MAX+1) * sizeof(ID)); + *ids++ = MDB_IDL_UM_MAX; + return ids; +} + +void mdb_midl_free(IDL ids) +{ + free(ids-1); +} + +int mdb_midl_shrink( IDL *idp ) +{ + IDL ids = *idp; + if (ids[-1] > MDB_IDL_UM_MAX) { + ids = realloc(ids, (MDB_IDL_UM_MAX+1) * sizeof(ID)); + *ids++ = MDB_IDL_UM_MAX; + *idp = ids; + return 1; + } + return 0; +} + +int mdb_midl_append( IDL *idp, ID id ) { + IDL ids = *idp; /* Too big? */ - if (ids[0] >= MDB_IDL_UM_MAX) - return -1; + if (ids[0] >= ids[-1]) { + IDL idn = ids-1; + /* grow it */ + idn = realloc(idn, (*idn + MDB_IDL_UM_MAX + 1) * sizeof(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( IDL *idp, IDL app ) +{ + IDL ids = *idp; + /* Too big? */ + if (ids[0] + app[0] >= ids[-1]) { + IDL idn = ids-1; + /* grow it */ + idn = realloc(idn, (*idn + app[-1]) * sizeof(ID)); + if (!idn) + return -1; + *idn++ += app[-1]; + ids = idn; + *idp = ids; + } + memcpy(&ids[ids[0]+1], &app[1], app[0] * sizeof(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; } void -mdb_midl_sort( ID *ids ) +mdb_midl_sort( IDL ids ) { /* Max possible depth of int-indexed tree * 2 items/level */ int istack[sizeof(int)*CHAR_BIT * 2]; @@ -201,32 +253,31 @@ 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 )