1*549b59edSchristos /* $NetBSD: midl.h,v 1.3 2021/08/14 16:14:57 christos Exp $ */ 2d11b170bStron 3d11b170bStron /** @file midl.h 4376af7d7Schristos * @brief LMDB ID List header file. 5d11b170bStron * 6d11b170bStron * This file was originally part of back-bdb but has been 7d11b170bStron * modified for use in libmdb. Most of the macros defined 8d11b170bStron * in this file are unused, just left over from the original. 9d11b170bStron * 10d11b170bStron * This file is only used internally in libmdb and its definitions 11d11b170bStron * are not exposed publicly. 12d11b170bStron */ 13d11b170bStron /* $OpenLDAP$ */ 14d11b170bStron /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 15d11b170bStron * 16*549b59edSchristos * Copyright 2000-2021 The OpenLDAP Foundation. 17*549b59edSchristos * Portions Copyright 2001-2021 Howard Chu, Symas Corp. 18d11b170bStron * All rights reserved. 19d11b170bStron * 20d11b170bStron * Redistribution and use in source and binary forms, with or without 21d11b170bStron * modification, are permitted only as authorized by the OpenLDAP 22d11b170bStron * Public License. 23d11b170bStron * 24d11b170bStron * A copy of this license is available in the file LICENSE in the 25d11b170bStron * top-level directory of the distribution or, alternatively, at 26d11b170bStron * <http://www.OpenLDAP.org/license.html>. 27d11b170bStron */ 28d11b170bStron 29d11b170bStron #ifndef _MDB_MIDL_H_ 30d11b170bStron #define _MDB_MIDL_H_ 31d11b170bStron 32d11b170bStron #include <stddef.h> 33d11b170bStron 34d11b170bStron #ifdef __cplusplus 35d11b170bStron extern "C" { 36d11b170bStron #endif 37d11b170bStron 38376af7d7Schristos /** @defgroup internal LMDB Internals 39d11b170bStron * @{ 40d11b170bStron */ 41d11b170bStron 42d11b170bStron /** @defgroup idls ID List Management 43d11b170bStron * @{ 44d11b170bStron */ 45d11b170bStron /** A generic unsigned ID number. These were entryIDs in back-bdb. 46d11b170bStron * Preferably it should have the same size as a pointer. 47d11b170bStron */ 48d11b170bStron typedef size_t MDB_ID; 49d11b170bStron 50d11b170bStron /** An IDL is an ID List, a sorted array of IDs. The first 51d11b170bStron * element of the array is a counter for how many actual 52d11b170bStron * IDs are in the list. In the original back-bdb code, IDLs are 53d11b170bStron * sorted in ascending order. For libmdb IDLs are sorted in 54d11b170bStron * descending order. 55d11b170bStron */ 56d11b170bStron typedef MDB_ID *MDB_IDL; 57d11b170bStron 58d11b170bStron /* IDL sizes - likely should be even bigger 59d11b170bStron * limiting factors: sizeof(ID), thread stack size 60d11b170bStron */ 61d11b170bStron #define MDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */ 62d11b170bStron #define MDB_IDL_DB_SIZE (1<<MDB_IDL_LOGN) 63d11b170bStron #define MDB_IDL_UM_SIZE (1<<(MDB_IDL_LOGN+1)) 64d11b170bStron 65d11b170bStron #define MDB_IDL_DB_MAX (MDB_IDL_DB_SIZE-1) 66d11b170bStron #define MDB_IDL_UM_MAX (MDB_IDL_UM_SIZE-1) 67d11b170bStron 68d11b170bStron #define MDB_IDL_SIZEOF(ids) (((ids)[0]+1) * sizeof(MDB_ID)) 69d11b170bStron #define MDB_IDL_IS_ZERO(ids) ( (ids)[0] == 0 ) 70d11b170bStron #define MDB_IDL_CPY( dst, src ) (memcpy( dst, src, MDB_IDL_SIZEOF( src ) )) 71d11b170bStron #define MDB_IDL_FIRST( ids ) ( (ids)[1] ) 72d11b170bStron #define MDB_IDL_LAST( ids ) ( (ids)[(ids)[0]] ) 73d11b170bStron 74376af7d7Schristos /** Current max length of an #mdb_midl_alloc()ed IDL */ 75376af7d7Schristos #define MDB_IDL_ALLOCLEN( ids ) ( (ids)[-1] ) 76376af7d7Schristos 77d11b170bStron /** Append ID to IDL. The IDL must be big enough. */ 78d11b170bStron #define mdb_midl_xappend(idl, id) do { \ 79d11b170bStron MDB_ID *xidl = (idl), xlen = ++(xidl[0]); \ 80d11b170bStron xidl[xlen] = (id); \ 81d11b170bStron } while (0) 82d11b170bStron 83d11b170bStron /** Search for an ID in an IDL. 84d11b170bStron * @param[in] ids The IDL to search. 85d11b170bStron * @param[in] id The ID to search for. 86d11b170bStron * @return The index of the first ID greater than or equal to \b id. 87d11b170bStron */ 88d11b170bStron unsigned mdb_midl_search( MDB_IDL ids, MDB_ID id ); 89d11b170bStron 90d11b170bStron /** Allocate an IDL. 91d11b170bStron * Allocates memory for an IDL of the given size. 92d11b170bStron * @return IDL on success, NULL on failure. 93d11b170bStron */ 94d11b170bStron MDB_IDL mdb_midl_alloc(int num); 95d11b170bStron 96d11b170bStron /** Free an IDL. 97d11b170bStron * @param[in] ids The IDL to free. 98d11b170bStron */ 99d11b170bStron void mdb_midl_free(MDB_IDL ids); 100d11b170bStron 101d11b170bStron /** Shrink an IDL. 102d11b170bStron * Return the IDL to the default size if it has grown larger. 103d11b170bStron * @param[in,out] idp Address of the IDL to shrink. 104d11b170bStron */ 105376af7d7Schristos void mdb_midl_shrink(MDB_IDL *idp); 106d11b170bStron 107d11b170bStron /** Make room for num additional elements in an IDL. 108d11b170bStron * @param[in,out] idp Address of the IDL. 109d11b170bStron * @param[in] num Number of elements to make room for. 110d11b170bStron * @return 0 on success, ENOMEM on failure. 111d11b170bStron */ 112d11b170bStron int mdb_midl_need(MDB_IDL *idp, unsigned num); 113d11b170bStron 114d11b170bStron /** Append an ID onto an IDL. 115d11b170bStron * @param[in,out] idp Address of the IDL to append to. 116d11b170bStron * @param[in] id The ID to append. 117d11b170bStron * @return 0 on success, ENOMEM if the IDL is too large. 118d11b170bStron */ 119d11b170bStron int mdb_midl_append( MDB_IDL *idp, MDB_ID id ); 120d11b170bStron 121d11b170bStron /** Append an IDL onto an IDL. 122d11b170bStron * @param[in,out] idp Address of the IDL to append to. 123d11b170bStron * @param[in] app The IDL to append. 124d11b170bStron * @return 0 on success, ENOMEM if the IDL is too large. 125d11b170bStron */ 126d11b170bStron int mdb_midl_append_list( MDB_IDL *idp, MDB_IDL app ); 127d11b170bStron 128d11b170bStron /** Append an ID range onto an IDL. 129d11b170bStron * @param[in,out] idp Address of the IDL to append to. 130d11b170bStron * @param[in] id The lowest ID to append. 131d11b170bStron * @param[in] n Number of IDs to append. 132d11b170bStron * @return 0 on success, ENOMEM if the IDL is too large. 133d11b170bStron */ 134d11b170bStron int mdb_midl_append_range( MDB_IDL *idp, MDB_ID id, unsigned n ); 135d11b170bStron 136376af7d7Schristos /** Merge an IDL onto an IDL. The destination IDL must be big enough. 137376af7d7Schristos * @param[in] idl The IDL to merge into. 138376af7d7Schristos * @param[in] merge The IDL to merge. 139376af7d7Schristos */ 140376af7d7Schristos void mdb_midl_xmerge( MDB_IDL idl, MDB_IDL merge ); 141376af7d7Schristos 142d11b170bStron /** Sort an IDL. 143d11b170bStron * @param[in,out] ids The IDL to sort. 144d11b170bStron */ 145d11b170bStron void mdb_midl_sort( MDB_IDL ids ); 146d11b170bStron 147d11b170bStron /** An ID2 is an ID/pointer pair. 148d11b170bStron */ 149d11b170bStron typedef struct MDB_ID2 { 150d11b170bStron MDB_ID mid; /**< The ID */ 151d11b170bStron void *mptr; /**< The pointer */ 152d11b170bStron } MDB_ID2; 153d11b170bStron 154d11b170bStron /** An ID2L is an ID2 List, a sorted array of ID2s. 155d11b170bStron * The first element's \b mid member is a count of how many actual 156d11b170bStron * elements are in the array. The \b mptr member of the first element is unused. 157d11b170bStron * The array is sorted in ascending order by \b mid. 158d11b170bStron */ 159d11b170bStron typedef MDB_ID2 *MDB_ID2L; 160d11b170bStron 161d11b170bStron /** Search for an ID in an ID2L. 162d11b170bStron * @param[in] ids The ID2L to search. 163d11b170bStron * @param[in] id The ID to search for. 164d11b170bStron * @return The index of the first ID2 whose \b mid member is greater than or equal to \b id. 165d11b170bStron */ 166d11b170bStron unsigned mdb_mid2l_search( MDB_ID2L ids, MDB_ID id ); 167d11b170bStron 168d11b170bStron 169d11b170bStron /** Insert an ID2 into a ID2L. 170d11b170bStron * @param[in,out] ids The ID2L to insert into. 171d11b170bStron * @param[in] id The ID2 to insert. 172d11b170bStron * @return 0 on success, -1 if the ID was already present in the ID2L. 173d11b170bStron */ 174d11b170bStron int mdb_mid2l_insert( MDB_ID2L ids, MDB_ID2 *id ); 175d11b170bStron 176d11b170bStron /** Append an ID2 into a ID2L. 177d11b170bStron * @param[in,out] ids The ID2L to append into. 178d11b170bStron * @param[in] id The ID2 to append. 179d11b170bStron * @return 0 on success, -2 if the ID2L is too big. 180d11b170bStron */ 181d11b170bStron int mdb_mid2l_append( MDB_ID2L ids, MDB_ID2 *id ); 182d11b170bStron 183d11b170bStron /** @} */ 184d11b170bStron /** @} */ 185d11b170bStron #ifdef __cplusplus 186d11b170bStron } 187d11b170bStron #endif 188d11b170bStron #endif /* _MDB_MIDL_H_ */ 189