From: Joel Rosdahl Date: Fri, 23 Aug 2019 17:46:40 +0000 (+0200) Subject: Replace third party hashtable with std::unordered_map X-Git-Tag: v4.0~819 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d76845a50fec1d5a0cefb5883b55dda7ad9ff10;p=thirdparty%2Fccache.git Replace third party hashtable with std::unordered_map --- diff --git a/LICENSE.adoc b/LICENSE.adoc index b3555d89b..451ca993d 100644 --- a/LICENSE.adoc +++ b/LICENSE.adoc @@ -124,44 +124,6 @@ https://www.postgresql.org[PostgreSQL] and has the following license text: ------------------------------------------------------------------------------- -src/third_party/hashtable*.[hc] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This code comes from http://www.cl.cam.ac.uk/~cwc22/hashtable/ with the -following license: - -------------------------------------------------------------------------------- - Copyright (c) 2002, 2004, Christopher Clark - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * 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. - - * Neither the name of the original author; nor the names of any - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - - 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 OWNER 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. -------------------------------------------------------------------------------- - - m4/ax_cxx_compile_stdcxx.m4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Makefile.in b/Makefile.in index 9c0a86c96..d0e7075ab 100644 --- a/Makefile.in +++ b/Makefile.in @@ -61,8 +61,6 @@ generated_sources = \ third_party_sources = \ src/third_party/format.cpp \ src/third_party/getopt_long.c \ - src/third_party/hashtable.c \ - src/third_party/hashtable_itr.c \ src/third_party/xxhash.c extra_sources = @extra_sources@ base_sources = $(non_third_party_sources) $(generated_sources) $(third_party_sources) $(extra_sources) diff --git a/dev.mk.in b/dev.mk.in index b0faaaa3c..1b8b0883c 100644 --- a/dev.mk.in +++ b/dev.mk.in @@ -58,9 +58,6 @@ non_third_party_headers = \ third_party_headers = \ src/third_party/catch.hpp \ src/third_party/getopt_long.h \ - src/third_party/hashtable.h \ - src/third_party/hashtable_itr.h \ - src/third_party/hashtable_private.h \ src/third_party/minitrace.h \ src/third_party/xxhash.h headers = $(non_third_party_headers) $(third_party_headers) diff --git a/src/ccache.cpp b/src/ccache.cpp index 618be6e6c..1eaf6ec96 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -38,9 +38,6 @@ #include "result.hpp" #include "unify.hpp" -#include "third_party/hashtable.h" -#include "third_party/hashtable_itr.h" - // Global variables used by other compilation units. extern char* primary_config_path; extern char* secondary_config_path; @@ -172,7 +169,7 @@ time_t time_of_compilation; // Files included by the preprocessor and their hashes. Key: file path. Value: // struct digest. -static struct hashtable* included_files = NULL; +static std::unordered_map g_included_files; // Uses absolute path for some include files. static bool has_absolute_include_headers = false; @@ -574,7 +571,7 @@ get_current_working_dir(void) } // This function hashes an include file and stores the path and hash in the -// global included_files variable. If the include file is a PCH, cpp_hash is +// global g_included_files variable. If the include file is a PCH, cpp_hash is // also updated. Takes over ownership of path. static void remember_include_file(char* path, @@ -601,7 +598,7 @@ remember_include_file(char* path, goto out; } - if (hashtable_search(included_files, path)) { + if (g_included_files.find(path) != g_included_files.end()) { // Already known include file. goto out; } @@ -724,15 +721,15 @@ remember_include_file(char* path, } } - auto d = static_cast(x_malloc(sizeof(digest))); - hash_result_as_bytes(fhash, d); - hashtable_insert(included_files, path, d); - path = NULL; // Ownership transferred to included_files. + digest d; + hash_result_as_bytes(fhash, &d); + g_included_files.emplace(path, d); + path = NULL; if (depend_mode_hash) { hash_delimiter(depend_mode_hash, "include"); char digest[DIGEST_STRING_BUFFER_SIZE]; - digest_as_string(d, digest); + digest_as_string(&d, digest); hash_string(depend_mode_hash, digest); } } @@ -753,11 +750,9 @@ out: static void print_included_files(FILE* fp) { - struct hashtable_itr* iter = hashtable_iterator(included_files); - do { - char* path = static_cast(hashtable_iterator_key(iter)); - fprintf(fp, "%s\n", path); - } while (hashtable_iterator_advance(iter)); + for (const auto& item : g_included_files) { + fprintf(fp, "%s\n", item.first.c_str()); + } } // Make a relative path from current working directory to path if path is under @@ -831,23 +826,13 @@ make_relative_path(char* path) } } -static void -init_included_files_table(void) -{ - // (This function may be called multiple times if several -arch options are - // used.) - if (!included_files) { - included_files = create_hashtable(1000, hash_from_string, strings_equal); - } -} - // This function reads and hashes a file. While doing this, it also does these // things: // // - Makes include file paths for which the base directory is a prefix relative // when computing the hash sum. // - Stores the paths and hashes of included files in the global variable -// included_files. +// g_included_files. static bool process_preprocessed_file(struct hash* hash, const char* path, bool pump) { @@ -872,8 +857,6 @@ process_preprocessed_file(struct hash* hash, const char* path, bool pump) free(p); } - init_included_files_table(); - char* cwd = gnu_getcwd(); // Bytes between p and q are pending to be hashed. @@ -1142,8 +1125,6 @@ result_name_from_depfile(const char* depfile, struct hash* hash) return NULL; } - init_included_files_table(); - char buf[10000]; while (fgets(buf, sizeof(buf), f) && !ferror(f)) { char* saveptr; @@ -1197,7 +1178,7 @@ send_cached_stderr(const char* path_stderr) static void update_manifest_file(void) { - if (!g_config.direct_mode() || !included_files || g_config.read_only() + if (!g_config.direct_mode() || g_config.read_only() || g_config.read_only_direct()) { return; } @@ -1210,7 +1191,7 @@ update_manifest_file(void) MTR_BEGIN("manifest", "manifest_put"); cc_log("Adding result name to %s", manifest_path); - if (manifest_put(manifest_path, cached_result_name, included_files)) { + if (manifest_put(manifest_path, cached_result_name, g_included_files)) { if (x_stat(manifest_path, &st) == 0) { stats_update_size( manifest_stats_file, file_size(&st) - old_size, old_size == 0 ? 1 : 0); @@ -3642,10 +3623,7 @@ cc_reset(void) free(ignore_headers); ignore_headers = NULL; ignore_headers_len = 0; - if (included_files) { - hashtable_destroy(included_files, 1); - included_files = NULL; - } + g_included_files.clear(); has_absolute_include_headers = false; generating_debuginfo = false; generating_debuginfo_level_3 = false; @@ -3847,7 +3825,7 @@ ccache(int argc, char* argv[]) if (!g_config.depend_mode()) { // Find the hash using the preprocessed output. Also updates - // included_files. + // g_included_files. struct hash* cpp_hash = hash_copy(common_hash); init_hash_debug( cpp_hash, output_obj, 'p', "PREPROCESSOR MODE", debug_text_file); diff --git a/src/hashutil.cpp b/src/hashutil.cpp index e9c56c70f..d3a997407 100644 --- a/src/hashutil.cpp +++ b/src/hashutil.cpp @@ -23,24 +23,12 @@ #include "third_party/xxhash.h" -unsigned -hash_from_string(void* str) -{ - return XXH64(str, strlen((const char*)str), 0); -} - unsigned hash_from_int(int i) { return XXH64(&i, sizeof(int), 0); } -int -strings_equal(void* str1, void* str2) -{ - return str_eq((const char*)str1, (const char*)str2); -} - // Search for the strings "__DATE__" and "__TIME__" in str. // // Returns a bitmask with HASH_SOURCE_CODE_FOUND_DATE and diff --git a/src/hashutil.hpp b/src/hashutil.hpp index 9bd34aa67..87a49b81d 100644 --- a/src/hashutil.hpp +++ b/src/hashutil.hpp @@ -25,9 +25,7 @@ #include -unsigned hash_from_string(void* str); unsigned hash_from_int(int i); -int strings_equal(void* str1, void* str2); #define HASH_SOURCE_CODE_OK 0 #define HASH_SOURCE_CODE_ERROR 1 diff --git a/src/manifest.cpp b/src/manifest.cpp index dc2cc5019..f54da6df5 100644 --- a/src/manifest.cpp +++ b/src/manifest.cpp @@ -24,7 +24,6 @@ #include "hashutil.hpp" #include "int_bytes_conversion.hpp" -#include "third_party/hashtable_itr.h" #include "third_party/xxhash.h" // Manifest data format @@ -106,10 +105,7 @@ const char MANIFEST_MAGIC[4] = {'c', 'C', 'm', 'F'}; static const uint32_t MAX_MANIFEST_ENTRIES = 100; static const uint32_t MAX_MANIFEST_FILE_INFO_ENTRIES = 10000; -#define ccache_static_assert(e) \ - do { \ - enum { ccache_static_assert__ = 1 / (e) }; \ - } while (false) +namespace { struct file { @@ -117,7 +113,7 @@ struct file char* path; // NUL-terminated }; -struct file_info +struct FileInfo { // Index to n_files. uint32_t index; @@ -131,6 +127,30 @@ struct file_info int64_t ctime; }; +bool +operator==(const FileInfo& lhs, const FileInfo& rhs) +{ + return lhs.index == rhs.index && digests_equal(&lhs.digest, &rhs.digest) + && lhs.fsize == rhs.fsize && lhs.mtime == rhs.mtime + && lhs.ctime == rhs.ctime; +} + +} // namespace + +namespace std { + +template<> struct hash +{ + size_t + operator()(const FileInfo& file_info) const + { + static_assert(sizeof(FileInfo) == 48, "unexpected size"); // No padding. + return XXH64(&file_info, sizeof(file_info), 0); + } +}; + +} // namespace std + struct result { // Number of entries in file_info_indexes. @@ -151,7 +171,7 @@ struct manifest // Information about referenced include files. uint32_t n_file_infos; - struct file_info* file_infos; + struct FileInfo* file_infos; // Result names plus references to include file infos. uint32_t n_results; @@ -165,23 +185,6 @@ struct file_stats int64_t ctime; }; -static unsigned int -hash_from_file_info(void* key) -{ - ccache_static_assert(sizeof(struct file_info) == 48); // No padding. - return XXH64(key, sizeof(struct file_info), 0); -} - -static int -file_infos_equal(void* key1, void* key2) -{ - struct file_info* fi1 = (struct file_info*)key1; - struct file_info* fi2 = (struct file_info*)key2; - return fi1->index == fi2->index && digests_equal(&fi1->digest, &fi2->digest) - && fi1->fsize == fi2->fsize && fi1->mtime == fi2->mtime - && fi1->ctime == fi2->ctime; -} - static void free_manifest(struct manifest* mf) { @@ -291,7 +294,7 @@ read_manifest(const char* path, char** errmsg) READ_UINT32(mf->n_file_infos); mf->file_infos = - static_cast(x_calloc(mf->n_file_infos, sizeof(file_info))); + static_cast(x_calloc(mf->n_file_infos, sizeof(FileInfo))); for (uint32_t i = 0; i < mf->n_file_infos; i++) { READ_UINT32(mf->file_infos[i].index); READ_BYTES(mf->file_infos[i].digest.bytes, DIGEST_SIZE); @@ -454,26 +457,27 @@ static bool verify_result(const Config& config, struct manifest* mf, struct result* result, - struct hashtable* stated_files, - struct hashtable* hashed_files) + std::unordered_map* stated_files, + std::unordered_map* hashed_files) { for (uint32_t i = 0; i < result->n_file_info_indexes; i++) { - struct file_info* fi = &mf->file_infos[result->file_info_indexes[i]]; + struct FileInfo* fi = &mf->file_infos[result->file_info_indexes[i]]; char* path = mf->files[fi->index].path; - auto st = static_cast(hashtable_search(stated_files, path)); - if (!st) { + auto stated_files_iter = stated_files->find(path); + if (stated_files_iter == stated_files->end()) { struct stat file_stat; if (x_stat(path, &file_stat) != 0) { return false; } - st = static_cast(x_malloc(sizeof(file_stats))); - st->size = file_stat.st_size; - st->mtime = file_stat.st_mtime; - st->ctime = file_stat.st_ctime; - hashtable_insert(stated_files, x_strdup(path), st); + file_stats st; + st.size = file_stat.st_size; + st.mtime = file_stat.st_mtime; + st.ctime = file_stat.st_ctime; + stated_files_iter = stated_files->emplace(path, st).first; } + const file_stats& fs = stated_files_iter->second; - if (fi->fsize != st->size) { + if (fi->fsize != fs.size) { return false; } @@ -481,21 +485,21 @@ verify_result(const Config& config, // and will error out if that header is later used without rebuilding. if ((guessed_compiler == GUESSED_CLANG || guessed_compiler == GUESSED_UNKNOWN) - && output_is_precompiled_header && fi->mtime != st->mtime) { + && output_is_precompiled_header && fi->mtime != fs.mtime) { cc_log("Precompiled header includes %s, which has a new mtime", path); return false; } if (config.sloppiness() & SLOPPY_FILE_STAT_MATCHES) { if (!(config.sloppiness() & SLOPPY_FILE_STAT_MATCHES_CTIME)) { - if (fi->mtime == st->mtime && fi->ctime == st->ctime) { + if (fi->mtime == fs.mtime && fi->ctime == fs.ctime) { cc_log("mtime/ctime hit for %s", path); continue; } else { cc_log("mtime/ctime miss for %s", path); } } else { - if (fi->mtime == st->mtime) { + if (fi->mtime == fs.mtime) { cc_log("mtime hit for %s", path); continue; } else { @@ -504,8 +508,8 @@ verify_result(const Config& config, } } - auto actual = static_cast(hashtable_search(hashed_files, path)); - if (!actual) { + auto hashed_files_iter = hashed_files->find(path); + if (hashed_files_iter == hashed_files->end()) { struct hash* hash = hash_init(); int ret = hash_source_code_file(config, hash, path); if (ret & HASH_SOURCE_CODE_ERROR) { @@ -518,12 +522,13 @@ verify_result(const Config& config, return false; } - actual = static_cast(malloc(sizeof(digest))); - hash_result_as_bytes(hash, actual); - hashtable_insert(hashed_files, x_strdup(path), actual); + digest actual; + hash_result_as_bytes(hash, &actual); hash_free(hash); + hashed_files_iter = hashed_files->emplace(path, actual).first; } - if (!digests_equal(&fi->digest, actual)) { + + if (!digests_equal(&fi->digest, &hashed_files_iter->second)) { return false; } } @@ -531,61 +536,57 @@ verify_result(const Config& config, return true; } -static struct hashtable* -create_file_index_map(struct file* files, uint32_t len) +static void +create_file_index_map( + struct file* files, + uint32_t len, + std::unordered_map* mf_files) { - struct hashtable* h = create_hashtable(1000, hash_from_string, strings_equal); for (uint32_t i = 0; i < len; i++) { - auto index = static_cast(x_malloc(sizeof(uint32_t))); - *index = i; - hashtable_insert(h, x_strdup(files[i].path), index); + mf_files->emplace(files[i].path, i); } - return h; } -static struct hashtable* -create_file_info_index_map(struct file_info* infos, uint32_t len) +static void +create_file_info_index_map( + struct FileInfo* infos, + uint32_t len, + std::unordered_map* mf_file_infos) { - struct hashtable* h = - create_hashtable(1000, hash_from_file_info, file_infos_equal); for (uint32_t i = 0; i < len; i++) { - auto fi = static_cast(x_malloc(sizeof(file_info))); - *fi = infos[i]; - uint32_t* index = static_cast(x_malloc(sizeof(uint32_t))); - *index = i; - hashtable_insert(h, fi, index); + mf_file_infos->emplace(infos[i], i); } - return h; } static uint32_t -get_include_file_index(struct manifest* mf, - char* path, - struct hashtable* mf_files) +get_include_file_index( + struct manifest* mf, + const std::string& path, + const std::unordered_map& mf_files) { - uint32_t* index = static_cast(hashtable_search(mf_files, path)); - if (index) { - return *index; + auto it = mf_files.find(path); + if (it != mf_files.end()) { + return it->second; } uint32_t n = mf->n_files; mf->files = static_cast(x_realloc(mf->files, (n + 1) * sizeof(file))); mf->n_files++; - mf->files[n].path_len = strlen(path); - mf->files[n].path = x_strdup(path); + mf->files[n].path_len = path.size(); + mf->files[n].path = x_strdup(path.c_str()); return n; } static uint32_t get_file_info_index(struct manifest* mf, - char* path, - struct digest* digest, - struct hashtable* mf_files, - struct hashtable* mf_file_infos) + const std::string& path, + const digest& digest, + const std::unordered_map& mf_files, + const std::unordered_map& mf_file_infos) { - struct file_info fi; + struct FileInfo fi; fi.index = get_include_file_index(mf, path, mf_files); - fi.digest = *digest; + fi.digest = digest; // file_stat.st_{m,c}time has a resolution of 1 second, so we can cache the // file's mtime and ctime only if they're at least one second older than @@ -595,7 +596,7 @@ get_file_info_index(struct manifest* mf, // MAX(mtime, ctime). struct stat file_stat; - if (stat(path, &file_stat) != -1) { + if (stat(path.c_str(), &file_stat) != -1) { if (time_of_compilation > std::max(file_stat.st_mtime, file_stat.st_ctime)) { fi.mtime = file_stat.st_mtime; @@ -611,52 +612,50 @@ get_file_info_index(struct manifest* mf, fi.fsize = 0; } - auto fi_index = static_cast(hashtable_search(mf_file_infos, &fi)); - if (fi_index) { - return *fi_index; + auto it = mf_file_infos.find(fi); + if (it != mf_file_infos.end()) { + return it->second; } uint32_t n = mf->n_file_infos; - mf->file_infos = static_cast( - x_realloc(mf->file_infos, (n + 1) * sizeof(file_info))); + mf->file_infos = static_cast( + x_realloc(mf->file_infos, (n + 1) * sizeof(FileInfo))); mf->n_file_infos++; mf->file_infos[n] = fi; return n; } static void -add_file_info_indexes(uint32_t* indexes, - uint32_t size, - struct manifest* mf, - struct hashtable* included_files) +add_file_info_indexes( + uint32_t* indexes, + uint32_t size, + struct manifest* mf, + const std::unordered_map& included_files) { if (size == 0) { return; } - // path --> index - struct hashtable* mf_files = create_file_index_map(mf->files, mf->n_files); - // struct file_info --> index - struct hashtable* mf_file_infos = - create_file_info_index_map(mf->file_infos, mf->n_file_infos); - struct hashtable_itr* iter = hashtable_iterator(included_files); + std::unordered_map mf_files; + create_file_index_map(mf->files, mf->n_files, &mf_files); + + std::unordered_map mf_file_infos; + create_file_info_index_map(mf->file_infos, mf->n_file_infos, &mf_file_infos); + uint32_t i = 0; - do { - auto path = static_cast(hashtable_iterator_key(iter)); - auto digest = static_cast(hashtable_iterator_value(iter)); + for (const auto& item : included_files) { + const auto& path = item.first; + const auto& digest = item.second; indexes[i] = get_file_info_index(mf, path, digest, mf_files, mf_file_infos); i++; - } while (hashtable_iterator_advance(iter)); + } assert(i == size); - - hashtable_destroy(mf_file_infos, 1); - hashtable_destroy(mf_files, 1); } static void add_result_entry(struct manifest* mf, struct digest* result_digest, - struct hashtable* included_files) + const std::unordered_map& included_files) { uint32_t n_results = mf->n_results; mf->results = static_cast( @@ -664,7 +663,7 @@ add_result_entry(struct manifest* mf, mf->n_results++; struct result* result = &mf->results[n_results]; - uint32_t n_fii = hashtable_count(included_files); + uint32_t n_fii = included_files.size(); result->n_file_info_indexes = n_fii; result->file_info_indexes = static_cast(x_malloc(n_fii * sizeof(uint32_t))); @@ -684,18 +683,14 @@ manifest_get(const Config& config, const char* manifest_path) return NULL; } - // path --> struct digest - struct hashtable* hashed_files = - create_hashtable(1000, hash_from_string, strings_equal); - // path --> struct file_stats - struct hashtable* stated_files = - create_hashtable(1000, hash_from_string, strings_equal); + std::unordered_map stated_files; + std::unordered_map hashed_files; // Check newest result first since it's a bit more likely to match. struct digest* name = NULL; for (uint32_t i = mf->n_results; i > 0; i--) { if (verify_result( - config, mf, &mf->results[i - 1], stated_files, hashed_files)) { + config, mf, &mf->results[i - 1], &stated_files, &hashed_files)) { name = static_cast(x_malloc(sizeof(digest))); *name = mf->results[i - 1].name; goto out; @@ -703,12 +698,6 @@ manifest_get(const Config& config, const char* manifest_path) } out: - if (hashed_files) { - hashtable_destroy(hashed_files, 1); - } - if (stated_files) { - hashtable_destroy(stated_files, 1); - } free_manifest(mf); if (name) { // Update modification timestamp to save files from LRU cleanup. @@ -722,7 +711,7 @@ out: bool manifest_put(const char* manifest_path, struct digest* result_name, - struct hashtable* included_files) + const std::unordered_map& included_files) { // We don't bother to acquire a lock when writing the manifest to disk. A // race between two processes will only result in one lost entry, which is @@ -752,10 +741,10 @@ manifest_put(const char* manifest_path, free_manifest(mf); mf = create_empty_manifest(); } else if (mf->n_file_infos > MAX_MANIFEST_FILE_INFO_ENTRIES) { - // Rarely, file_info entries can grow large in pathological cases where + // Rarely, FileInfo entries can grow large in pathological cases where // many included files change, but the main file does not. This also puts - // an upper bound on the number of file_info entries. - cc_log("More than %u file_info entries in manifest file; discarding", + // an upper bound on the number of FileInfo entries. + cc_log("More than %u FileInfo entries in manifest file; discarding", MAX_MANIFEST_FILE_INFO_ENTRIES); free_manifest(mf); mf = create_empty_manifest(); diff --git a/src/manifest.hpp b/src/manifest.hpp index 21a558704..71f8e194a 100644 --- a/src/manifest.hpp +++ b/src/manifest.hpp @@ -23,13 +23,12 @@ #include "Config.hpp" #include "hashutil.hpp" -#include "third_party/hashtable.h" - extern const char MANIFEST_MAGIC[4]; #define MANIFEST_VERSION 2 struct digest* manifest_get(const Config& config, const char* manifest_path); -bool manifest_put(const char* manifest_path, - struct digest* result_digest, - struct hashtable* included_files); +bool +manifest_put(const char* manifest_path, + struct digest* result_digest, + const std::unordered_map& included_files); bool manifest_dump(const char* manifest_path, FILE* stream); diff --git a/src/third_party/hashtable.c b/src/third_party/hashtable.c deleted file mode 100644 index 308e72cab..000000000 --- a/src/third_party/hashtable.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - Copyright (c) 2002, 2004, Christopher Clark - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * 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. - - * Neither the name of the original author; nor the names of any - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - - 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 OWNER 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 "hashtable.h" -#define HASHTABLE_INDEXFOR -#include "hashtable_private.h" -#include -#include -#include -#include - -extern const unsigned int prime_table_length; -extern const float max_load_factor; - -/* -Credit for primes table: Aaron Krowne - http://br.endernet.org/~akrowne/ - http://planetmath.org/encyclopedia/GoodHashTablePrimes.html -*/ -static const unsigned int primes[] = { -53, 97, 193, 389, -769, 1543, 3079, 6151, -12289, 24593, 49157, 98317, -196613, 393241, 786433, 1572869, -3145739, 6291469, 12582917, 25165843, -50331653, 100663319, 201326611, 402653189, -805306457, 1610612741 -}; -const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]); -const float max_load_factor = 0.65f; - -/*****************************************************************************/ -struct hashtable * -create_hashtable(unsigned int minsize, - unsigned int (*hashf) (void*), - int (*eqf) (void*,void*)) -{ - struct hashtable *h; - unsigned int pindex, size = primes[0]; - /* Check requested hashtable isn't too large */ - if (minsize > (1u << 30)) return NULL; - /* Enforce size as prime */ - for (pindex=0; pindex < prime_table_length; pindex++) { - if (primes[pindex] > minsize) { size = primes[pindex]; break; } - } - h = (struct hashtable *)malloc(sizeof(struct hashtable)); - if (NULL == h) return NULL; /*oom*/ - h->table = (struct entry **)malloc(sizeof(struct entry*) * size); - if (NULL == h->table) { free(h); return NULL; } /*oom*/ - memset(h->table, 0, size * sizeof(struct entry *)); - h->tablelength = size; - h->primeindex = pindex; - h->entrycount = 0; - h->hashfn = hashf; - h->eqfn = eqf; - double loadlimit_float = ceil((double)size * (double)max_load_factor); - h->loadlimit = (unsigned int)loadlimit_float; - return h; -} - -/*****************************************************************************/ -unsigned int -hash(struct hashtable *h, void *k) -{ - /* Aim to protect against poor hash functions by adding logic here - * - logic taken from java 1.4 hashtable source */ - unsigned int i = h->hashfn(k); - i += ~(i << 9); - i ^= ((i >> 14) | (i << 18)); /* >>> */ - i += (i << 4); - i ^= ((i >> 10) | (i << 22)); /* >>> */ - return i; -} - -/*****************************************************************************/ -static int -hashtable_expand(struct hashtable *h) -{ - /* Double the size of the table to accommodate more entries */ - struct entry **newtable; - struct entry *e; - unsigned int newsize, i, index; - /* Check we're not hitting max capacity */ - if (h->primeindex == (prime_table_length - 1)) return 0; - newsize = primes[++(h->primeindex)]; - - newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize); - if (NULL != newtable) - { - memset(newtable, 0, newsize * sizeof(struct entry *)); - /* This algorithm is not 'stable'. ie. it reverses the list - * when it transfers entries between the tables */ - for (i = 0; i < h->tablelength; i++) { - while (NULL != (e = h->table[i])) { - h->table[i] = e->next; - index = indexFor(newsize,e->h); - e->next = newtable[index]; - newtable[index] = e; - } - } - free(h->table); - h->table = newtable; - } - /* Plan B: realloc instead */ - else - { - struct entry **pE; - newtable = (struct entry **) - realloc(h->table, newsize * sizeof(struct entry *)); - if (NULL == newtable) { (h->primeindex)--; return 0; } - h->table = newtable; - memset(newtable[h->tablelength], 0, newsize - h->tablelength); - for (i = 0; i < h->tablelength; i++) { - for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) { - index = indexFor(newsize,e->h); - if (index == i) - { - pE = &(e->next); - } - else - { - *pE = e->next; - e->next = newtable[index]; - newtable[index] = e; - } - } - } - } - h->tablelength = newsize; - double loadlimit_float = ceil((double)newsize* (double)max_load_factor); - h->loadlimit = (unsigned int) loadlimit_float; - return -1; -} - -/*****************************************************************************/ -unsigned int -hashtable_count(struct hashtable *h) -{ - return h->entrycount; -} - -/*****************************************************************************/ -int -hashtable_insert(struct hashtable *h, void *k, void *v) -{ - /* This method allows duplicate keys - but they shouldn't be used */ - unsigned int index; - struct entry *e; - if (++(h->entrycount) > h->loadlimit) - { - /* Ignore the return value. If expand fails, we should - * still try cramming just this value into the existing table - * -- we may not have memory for a larger table, but one more - * element may be ok. Next time we insert, we'll try expanding again.*/ - hashtable_expand(h); - } - e = (struct entry *)malloc(sizeof(struct entry)); - if (NULL == e) { --(h->entrycount); return 0; } /*oom*/ - e->h = hash(h,k); - index = indexFor(h->tablelength,e->h); - e->k = k; - e->v = v; - e->next = h->table[index]; - h->table[index] = e; - return -1; -} - -/*****************************************************************************/ -void * /* returns value associated with key */ -hashtable_search(struct hashtable *h, void *k) -{ - struct entry *e; - unsigned int hashvalue, index; - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hashvalue); - e = h->table[index]; - while (NULL != e) - { - /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v; - e = e->next; - } - return NULL; -} - -/*****************************************************************************/ -void * /* returns value associated with key */ -hashtable_remove(struct hashtable *h, void *k) -{ - /* TODO: consider compacting the table when the load factor drops enough, - * or provide a 'compact' method. */ - - struct entry *e; - struct entry **pE; - void *v; - unsigned int hashvalue, index; - - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hash(h,k)); - pE = &(h->table[index]); - e = *pE; - while (NULL != e) - { - /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) - { - *pE = e->next; - h->entrycount--; - v = e->v; - freekey(e->k); - free(e); - return v; - } - pE = &(e->next); - e = e->next; - } - return NULL; -} - -/*****************************************************************************/ -/* destroy */ -void -hashtable_destroy(struct hashtable *h, int free_values) -{ - unsigned int i; - struct entry *e, *f; - struct entry **table = h->table; - if (free_values) - { - for (i = 0; i < h->tablelength; i++) - { - e = table[i]; - while (NULL != e) - { f = e; e = e->next; freekey(f->k); free(f->v); free(f); } - } - } - else - { - for (i = 0; i < h->tablelength; i++) - { - e = table[i]; - while (NULL != e) - { f = e; e = e->next; freekey(f->k); free(f); } - } - } - free(h->table); - free(h); -} - -/* - * Copyright (c) 2002, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * 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. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * 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 OWNER - * 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. -*/ diff --git a/src/third_party/hashtable.h b/src/third_party/hashtable.h deleted file mode 100644 index de3d25721..000000000 --- a/src/third_party/hashtable.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - Copyright (c) 2002, 2004, Christopher Clark - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * 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. - - * Neither the name of the original author; nor the names of any - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - - 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 OWNER 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. -*/ - -#ifndef HASHTABLE_CWC22_H -#define HASHTABLE_CWC22_H - -#include "config.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -struct hashtable; - -/* Example of use: - * - * struct hashtable *h; - * struct some_key *k; - * struct some_value *v; - * - * static unsigned int hash_from_key_fn( void *k ); - * static int keys_equal_fn ( void *key1, void *key2 ); - * - * h = create_hashtable(16, hash_from_key_fn, keys_equal_fn); - * k = (struct some_key *) malloc(sizeof(struct some_key)); - * v = (struct some_value *) malloc(sizeof(struct some_value)); - * - * (initialise k and v to suitable values) - * - * if (! hashtable_insert(h,k,v) ) - * { exit(-1); } - * - * if (NULL == (found = hashtable_search(h,k) )) - * { printf("not found!"); } - * - * if (NULL == (found = hashtable_remove(h,k) )) - * { printf("Not found\n"); } - * - */ - -/* Macros may be used to define type-safe(r) hashtable access functions, with - * methods specialized to take known key and value types as parameters. - * - * Example: - * - * Insert this at the start of your file: - * - * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value); - * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value); - * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value); - * - * This defines the functions 'insert_some', 'search_some' and 'remove_some'. - * These operate just like hashtable_insert etc., with the same parameters, - * but their function signatures have 'struct some_key *' rather than - * 'void *', and hence can generate compile time errors if your program is - * supplying incorrect data as a key (and similarly for value). - * - * Note that the hash and key equality functions passed to create_hashtable - * still take 'void *' parameters instead of 'some key *'. This shouldn't be - * a difficult issue as they're only defined and passed once, and the other - * functions will ensure that only valid keys are supplied to them. - * - * The cost for this checking is increased code size and runtime overhead - * - if performance is important, it may be worth switching back to the - * unsafe methods once your program has been debugged with the safe methods. - * This just requires switching to some simple alternative defines - eg: - * #define insert_some hashtable_insert - * - */ - -/***************************************************************************** - * create_hashtable - - * @name create_hashtable - * @param minsize minimum initial size of hashtable - * @param hashfunction function for hashing keys - * @param key_eq_fn function for determining key equality - * @return newly created hashtable or NULL on failure - */ - -struct hashtable * -create_hashtable(unsigned int minsize, - unsigned int (*hashfunction) (void*), - int (*key_eq_fn) (void*,void*)); - -/***************************************************************************** - * hashtable_insert - - * @name hashtable_insert - * @param h the hashtable to insert into - * @param k the key - hashtable claims ownership and will free on removal - * @param v the value - does not claim ownership - * @return non-zero for successful insertion - * - * This function will cause the table to expand if the insertion would take - * the ratio of entries to table size over the maximum load factor. - * - * This function does not check for repeated insertions with a duplicate key. - * The value returned when using a duplicate key is undefined -- when - * the hashtable changes size, the order of retrieval of duplicate key - * entries is reversed. - * If in doubt, remove before insert. - */ - -int -hashtable_insert(struct hashtable *h, void *k, void *v); - -#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \ -int fnname (struct hashtable *h, keytype *k, valuetype *v) \ -{ \ - return hashtable_insert(h,k,v); \ -} - -/***************************************************************************** - * hashtable_search - - * @name hashtable_search - * @param h the hashtable to search - * @param k the key to search for - does not claim ownership - * @return the value associated with the key, or NULL if none found - */ - -void * -hashtable_search(struct hashtable *h, void *k); - -#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \ -valuetype * fnname (struct hashtable *h, keytype *k) \ -{ \ - return (valuetype *) (hashtable_search(h,k)); \ -} - -/***************************************************************************** - * hashtable_remove - - * @name hashtable_remove - * @param h the hashtable to remove the item from - * @param k the key to search for - does not claim ownership - * @return the value associated with the key, or NULL if none found - */ - -void * /* returns value */ -hashtable_remove(struct hashtable *h, void *k); - -#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \ -valuetype * fnname (struct hashtable *h, keytype *k) \ -{ \ - return (valuetype *) (hashtable_remove(h,k)); \ -} - - -/***************************************************************************** - * hashtable_count - - * @name hashtable_count - * @param h the hashtable - * @return the number of items stored in the hashtable - */ -unsigned int -hashtable_count(struct hashtable *h); - - -/***************************************************************************** - * hashtable_destroy - - * @name hashtable_destroy - * @param h the hashtable - * @param free_values whether to call 'free' on the remaining values - */ - -void -hashtable_destroy(struct hashtable *h, int free_values); - -#if defined (__cplusplus) -} -#endif - -#endif /* HASHTABLE_CWC22_H */ - -/* - * Copyright (c) 2002, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * 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. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * 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 OWNER - * 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. -*/ diff --git a/src/third_party/hashtable_itr.c b/src/third_party/hashtable_itr.c deleted file mode 100644 index 1ee43da0c..000000000 --- a/src/third_party/hashtable_itr.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Copyright (C) 2002, 2004 Christopher Clark */ - -#include "hashtable.h" -#define HASHTABLE_INDEXFOR -#include "hashtable_private.h" -#include "hashtable_itr.h" -#include /* defines NULL */ - -/*****************************************************************************/ -/* hashtable_iterator - iterator constructor */ - -struct hashtable_itr * -hashtable_iterator(struct hashtable *h) -{ - unsigned int i, tablelength; - struct hashtable_itr *itr = (struct hashtable_itr *) - malloc(sizeof(struct hashtable_itr)); - if (NULL == itr) return NULL; - itr->h = h; - itr->e = NULL; - itr->parent = NULL; - tablelength = h->tablelength; - itr->index = tablelength; - if (0 == h->entrycount) return itr; - - for (i = 0; i < tablelength; i++) - { - if (NULL != h->table[i]) - { - itr->e = h->table[i]; - itr->index = i; - break; - } - } - return itr; -} - -/*****************************************************************************/ -/* key - return the key of the (key,value) pair at the current position */ -/* value - return the value of the (key,value) pair at the current position */ - -void * -hashtable_iterator_key(struct hashtable_itr *i) -{ return i->e->k; } - -void * -hashtable_iterator_value(struct hashtable_itr *i) -{ return i->e->v; } - -/*****************************************************************************/ -/* advance - advance the iterator to the next element - * returns zero if advanced to end of table */ - -int -hashtable_iterator_advance(struct hashtable_itr *itr) -{ - unsigned int j,tablelength; - struct entry **table; - struct entry *next; - if (NULL == itr->e) return 0; /* stupidity check */ - - next = itr->e->next; - if (NULL != next) - { - itr->parent = itr->e; - itr->e = next; - return -1; - } - tablelength = itr->h->tablelength; - itr->parent = NULL; - if (tablelength <= (j = ++(itr->index))) - { - itr->e = NULL; - return 0; - } - table = itr->h->table; - while (NULL == (next = table[j])) - { - if (++j >= tablelength) - { - itr->index = tablelength; - itr->e = NULL; - return 0; - } - } - itr->index = j; - itr->e = next; - return -1; -} - -/*****************************************************************************/ -/* remove - remove the entry at the current iterator position - * and advance the iterator, if there is a successive - * element. - * If you want the value, read it before you remove: - * beware memory leaks if you don't. - * Returns zero if end of iteration. */ - -int -hashtable_iterator_remove(struct hashtable_itr *itr) -{ - struct entry *remember_e, *remember_parent; - int ret; - - /* Do the removal */ - if (NULL == (itr->parent)) - { - /* element is head of a chain */ - itr->h->table[itr->index] = itr->e->next; - } else { - /* element is mid-chain */ - itr->parent->next = itr->e->next; - } - /* itr->e is now outside the hashtable */ - remember_e = itr->e; - itr->h->entrycount--; - freekey(remember_e->k); - - /* Advance the iterator, correcting the parent */ - remember_parent = itr->parent; - ret = hashtable_iterator_advance(itr); - if (itr->parent == remember_e) { itr->parent = remember_parent; } - free(remember_e); - return ret; -} - -/*****************************************************************************/ -int /* returns zero if not found */ -hashtable_iterator_search(struct hashtable_itr *itr, - struct hashtable *h, void *k) -{ - struct entry *e, *parent; - unsigned int hashvalue, index; - - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hashvalue); - - e = h->table[index]; - parent = NULL; - while (NULL != e) - { - /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) - { - itr->index = index; - itr->e = e; - itr->parent = parent; - itr->h = h; - return -1; - } - parent = e; - e = e->next; - } - return 0; -} - - -/* - * Copyright (c) 2002, 2004, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * 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. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * 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 OWNER - * 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. -*/ diff --git a/src/third_party/hashtable_itr.h b/src/third_party/hashtable_itr.h deleted file mode 100644 index 823e55618..000000000 --- a/src/third_party/hashtable_itr.h +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright (C) 2002, 2004 Christopher Clark */ - -#ifndef HASHTABLE_ITR_CWC22_H -#define HASHTABLE_ITR_CWC22_H -#include "hashtable.h" -#include "hashtable_private.h" /* needed to enable inlining */ - -#if defined (__cplusplus) -extern "C" { -#endif - -/*****************************************************************************/ -/* This struct is only concrete here to allow the inlining of two of the - * accessor functions. */ -struct hashtable_itr -{ - struct hashtable *h; - struct entry *e; - struct entry *parent; - unsigned int index; -}; - - -/*****************************************************************************/ -/* hashtable_iterator - */ - -struct hashtable_itr * -hashtable_iterator(struct hashtable *h); - -/*****************************************************************************/ -/* hashtable_iterator_key - * - return the value of the (key,value) pair at the current position */ - -#ifdef HAVE_EXTERN_INLINE -extern inline void * -hashtable_iterator_key(struct hashtable_itr *i) -{ - return i->e->k; -} -#else -void * -hashtable_iterator_key(struct hashtable_itr *i); -#endif - -/*****************************************************************************/ -/* value - return the value of the (key,value) pair at the current position */ - -#ifdef HAVE_EXTERN_INLINE -extern inline void * -hashtable_iterator_value(struct hashtable_itr *i) -{ - return i->e->v; -} -#else -void * -hashtable_iterator_value(struct hashtable_itr *i); -#endif - -/*****************************************************************************/ -/* advance - advance the iterator to the next element - * returns zero if advanced to end of table */ - -int -hashtable_iterator_advance(struct hashtable_itr *itr); - -/*****************************************************************************/ -/* remove - remove current element and advance the iterator to the next element - * NB: if you need the value to free it, read it before - * removing. ie: beware memory leaks! - * returns zero if advanced to end of table */ - -int -hashtable_iterator_remove(struct hashtable_itr *itr); - -/*****************************************************************************/ -/* search - overwrite the supplied iterator, to point to the entry - * matching the supplied key. - h points to the hashtable to be searched. - * returns zero if not found. */ -int -hashtable_iterator_search(struct hashtable_itr *itr, - struct hashtable *h, void *k); - -#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \ -int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \ -{ \ - return (hashtable_iterator_search(i,h,k)); \ -} - -#if defined (__cplusplus) -} -#endif - -#endif /* HASHTABLE_ITR_CWC22_H */ - -/* - * Copyright (c) 2002, 2004, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * 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. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * 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 OWNER - * 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. -*/ diff --git a/src/third_party/hashtable_private.h b/src/third_party/hashtable_private.h deleted file mode 100644 index b0a8c6581..000000000 --- a/src/third_party/hashtable_private.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (C) 2002, 2004 Christopher Clark */ - -#ifndef HASHTABLE_PRIVATE_CWC22_H -#define HASHTABLE_PRIVATE_CWC22_H - -#include "hashtable.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -/*****************************************************************************/ -struct entry -{ - void *k, *v; - unsigned int h; - struct entry *next; -}; - -struct hashtable { - unsigned int tablelength; - struct entry **table; - unsigned int entrycount; - unsigned int loadlimit; - unsigned int primeindex; - unsigned int (*hashfn) (void *k); - int (*eqfn) (void *k1, void *k2); -}; - -/*****************************************************************************/ -unsigned int -hash(struct hashtable *h, void *k); - -/*****************************************************************************/ -#ifdef HASHTABLE_INDEXFOR -/* indexFor */ -static inline unsigned int -indexFor(unsigned int tablelength, unsigned int hashvalue) { - return (hashvalue % tablelength); -} - -/* Only works if tablelength == 2^N */ -/*static inline unsigned int -indexFor(unsigned int tablelength, unsigned int hashvalue) -{ - return (hashvalue & (tablelength - 1u)); -} -*/ -#endif - -/*****************************************************************************/ -#define freekey(X) free(X) -/*define freekey(X) ; */ - - -/*****************************************************************************/ - -#if defined (__cplusplus) -} -#endif - -#endif /* HASHTABLE_PRIVATE_CWC22_H */ - -/* - * Copyright (c) 2002, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * 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. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * 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 OWNER - * 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. -*/