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