parent
661d4f80e3
commit
27ab75ef36
@ -0,0 +1,95 @@ |
||||
/* Lifted from OpenLDAP back-bdb/idl.c */ |
||||
|
||||
#include <strings.h> |
||||
#include <sys/types.h> |
||||
#include <assert.h> |
||||
#include "idl.h" |
||||
|
||||
typedef ulong pgno_t; |
||||
|
||||
/* Sort the IDLs from highest to lowest */ |
||||
#define IDL_CMP(x,y) ( x > y ? -1 : ( x < y ? 1 : 0 ) ) |
||||
|
||||
unsigned mdb_idl_search( ID *ids, ID id ) |
||||
{ |
||||
/*
|
||||
* binary search of id in ids |
||||
* if found, returns position of id |
||||
* if not found, returns first position greater than id |
||||
*/ |
||||
unsigned base = 0; |
||||
unsigned cursor = 0; |
||||
int val = 0; |
||||
unsigned n = ids[0]; |
||||
|
||||
while( 0 < n ) { |
||||
int pivot = n >> 1; |
||||
cursor = base + pivot; |
||||
val = IDL_CMP( id, ids[cursor + 1] ); |
||||
|
||||
if( val < 0 ) { |
||||
n = pivot; |
||||
|
||||
} else if ( val > 0 ) { |
||||
base = cursor + 1; |
||||
n -= pivot + 1; |
||||
|
||||
} else { |
||||
return cursor + 1; |
||||
} |
||||
} |
||||
|
||||
if( val > 0 ) { |
||||
return cursor + 2; |
||||
} else { |
||||
return cursor + 1; |
||||
} |
||||
} |
||||
|
||||
int mdb_idl_insert( ID *ids, ID id ) |
||||
{ |
||||
unsigned x; |
||||
|
||||
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)) |
||||
return -1; |
||||
if (id < MDB_IDL_FIRST(ids)) |
||||
ids[1] = id; |
||||
else if (id > MDB_IDL_LAST(ids)) |
||||
ids[2] = id; |
||||
return 0; |
||||
} |
||||
|
||||
x = mdb_idl_search( ids, id ); |
||||
assert( x > 0 ); |
||||
|
||||
if( x < 1 ) { |
||||
/* internal error */ |
||||
return -2; |
||||
} |
||||
|
||||
if ( x <= ids[0] && ids[x] == id ) { |
||||
/* duplicate */ |
||||
return -1; |
||||
} |
||||
|
||||
if ( ++ids[0] >= MDB_IDL_DB_MAX ) { |
||||
if( id < ids[1] ) { |
||||
ids[1] = id; |
||||
ids[2] = ids[ids[0]-1]; |
||||
} else if ( ids[ids[0]-1] < id ) { |
||||
ids[2] = id; |
||||
} else { |
||||
ids[2] = ids[ids[0]-1]; |
||||
} |
||||
ids[0] = NOID; |
||||
|
||||
} else { |
||||
/* insert id */ |
||||
AC_MEMCPY( &ids[x+1], &ids[x], (ids[0]-x) * sizeof(ID) ); |
||||
ids[x] = id; |
||||
} |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,78 @@ |
||||
/* idl.h - ldap bdb back-end ID list header file */ |
||||
/* $OpenLDAP$ */ |
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
* |
||||
* Copyright 2000-2011 The OpenLDAP Foundation. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted only as authorized by the OpenLDAP |
||||
* Public License. |
||||
* |
||||
* A copy of this license is available in the file LICENSE in the |
||||
* top-level directory of the distribution or, alternatively, at |
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/ |
||||
|
||||
#ifndef _MDB_IDL_H_ |
||||
#define _MDB_IDL_H_ |
||||
|
||||
#define AC_MEMCPY(dst,src,size) bcopy(src,dst,size) |
||||
|
||||
#define ID unsigned long |
||||
#define NOID ((ID)~0) |
||||
|
||||
/* IDL sizes - likely should be even bigger
|
||||
* limiting factors: sizeof(ID), thread stack size |
||||
*/ |
||||
#define MDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */ |
||||
#define MDB_IDL_DB_SIZE (1<<MDB_IDL_LOGN) |
||||
#define MDB_IDL_UM_SIZE (1<<(MDB_IDL_LOGN+1)) |
||||
#define MDB_IDL_UM_SIZEOF (MDB_IDL_UM_SIZE * sizeof(ID)) |
||||
|
||||
#define MDB_IDL_DB_MAX (MDB_IDL_DB_SIZE-1) |
||||
|
||||
#define MDB_IDL_UM_MAX (MDB_IDL_UM_SIZE-1) |
||||
|
||||
#define MDB_IDL_IS_RANGE(ids) ((ids)[0] == NOID) |
||||
#define MDB_IDL_RANGE_SIZE (3) |
||||
#define MDB_IDL_RANGE_SIZEOF (MDB_IDL_RANGE_SIZE * sizeof(ID)) |
||||
#define MDB_IDL_SIZEOF(ids) ((MDB_IDL_IS_RANGE(ids) \ |
||||
? MDB_IDL_RANGE_SIZE : ((ids)[0]+1)) * sizeof(ID)) |
||||
|
||||
#define MDB_IDL_RANGE_FIRST(ids) ((ids)[1]) |
||||
#define MDB_IDL_RANGE_LAST(ids) ((ids)[2]) |
||||
|
||||
#define MDB_IDL_RANGE( ids, f, l ) \ |
||||
do { \
|
||||
(ids)[0] = NOID; \
|
||||
(ids)[1] = (f); \
|
||||
(ids)[2] = (l); \
|
||||
} while(0) |
||||
|
||||
#define MDB_IDL_ZERO(ids) \ |
||||
do { \
|
||||
(ids)[0] = 0; \
|
||||
(ids)[1] = 0; \
|
||||
(ids)[2] = 0; \
|
||||
} while(0) |
||||
|
||||
#define MDB_IDL_IS_ZERO(ids) ( (ids)[0] == 0 ) |
||||
#define MDB_IDL_IS_ALL( range, ids ) ( (ids)[0] == NOID \ |
||||
&& (ids)[1] <= (range)[1] && (range)[2] <= (ids)[2] ) |
||||
|
||||
#define MDB_IDL_CPY( dst, src ) (AC_MEMCPY( dst, src, MDB_IDL_SIZEOF( src ) )) |
||||
|
||||
#define MDB_IDL_ID( bdb, ids, id ) MDB_IDL_RANGE( ids, id, ((bdb)->bi_lastid) ) |
||||
#define MDB_IDL_ALL( bdb, ids ) MDB_IDL_RANGE( ids, 1, ((bdb)->bi_lastid) ) |
||||
|
||||
#define MDB_IDL_FIRST( ids ) ( ids[1] ) |
||||
#define MDB_IDL_LAST( ids ) ( MDB_IDL_IS_RANGE(ids) \ |
||||
? ids[2] : ids[ids[0]] ) |
||||
|
||||
#define MDB_IDL_N( ids ) ( MDB_IDL_IS_RANGE(ids) \ |
||||
? (ids[2]-ids[1])+1 : ids[0] ) |
||||
|
||||
int mdb_idl_insert( ID *ids, ID id ); |
||||
|
||||
#endif |
Loading…
Reference in new issue