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