/* * Copyright (c) 2014, Linaro Limited * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include /* * Define the initial capacity of the database. It should be a low number * multiple of 2 since some databases a likely to only use a few handles. * Since the algorithm is to doubles up when growing it shouldn't cause a * noticable overhead on large databases. */ #define HANDLE_DB_INITIAL_MAX_PTRS 4 void handle_db_destroy(struct handle_db *db) { if (db) { free(db->ptrs); db->ptrs = NULL; db->max_ptrs = 0; } } int handle_get(struct handle_db *db, void *ptr) { size_t n; void *p; size_t new_max_ptrs; if (!db || !ptr) return -1; /* Try to find an empty location */ for (n = 0; n < db->max_ptrs; n++) { if (!db->ptrs[n]) { db->ptrs[n] = ptr; return n; } } /* No location available, grow the ptrs array */ if (db->max_ptrs) new_max_ptrs = db->max_ptrs * 2; else new_max_ptrs = HANDLE_DB_INITIAL_MAX_PTRS; p = realloc(db->ptrs, new_max_ptrs * sizeof(void *)); if (!p) return -1; db->ptrs = p; memset(db->ptrs + db->max_ptrs, 0, (new_max_ptrs - db->max_ptrs) * sizeof(void *)); db->max_ptrs = new_max_ptrs; /* Since n stopped at db->max_ptrs there is an empty location there */ db->ptrs[n] = ptr; return n; } void *handle_put(struct handle_db *db, int handle) { void *p; if (!db || handle < 0 || (size_t)handle >= db->max_ptrs) return NULL; p = db->ptrs[handle]; db->ptrs[handle] = NULL; return p; } void *handle_lookup(struct handle_db *db, int handle) { if (!db || handle < 0 || (size_t)handle >= db->max_ptrs) return NULL; return db->ptrs[handle]; }