]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Replace third party hashtable with std::unordered_map
authorJoel Rosdahl <joel@rosdahl.net>
Fri, 23 Aug 2019 17:46:40 +0000 (19:46 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Thu, 5 Sep 2019 20:04:43 +0000 (22:04 +0200)
13 files changed:
LICENSE.adoc
Makefile.in
dev.mk.in
src/ccache.cpp
src/hashutil.cpp
src/hashutil.hpp
src/manifest.cpp
src/manifest.hpp
src/third_party/hashtable.c [deleted file]
src/third_party/hashtable.h [deleted file]
src/third_party/hashtable_itr.c [deleted file]
src/third_party/hashtable_itr.h [deleted file]
src/third_party/hashtable_private.h [deleted file]

index b3555d89b0f716d94caa02709e49c3e31db59b91..451ca993d190e67145fa52734963a009baf1ab23 100644 (file)
@@ -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
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
index 9c0a86c9622aef68348183f978b72fc5110d1669..d0e7075ab5378dc9a0848288e9b6d0323f0e378d 100644 (file)
@@ -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)
index b0faaaa3c35fbcecef8756f9b1d28459be8630ec..1b8b0883ca95ecaa8ffaa39812ede412b998736a 100644 (file)
--- 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)
index 618be6e6cae1922ff987734aaf3575f9ae93bcc9..1eaf6ec96f5940e8c24e3813c90b990f5058fb94 100644 (file)
@@ -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<std::string, digest> 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<digest*>(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<char*>(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);
index e9c56c70fce40e26b433e77049854060bcdc53be..d3a9974071c3d9a794f0b8a6f6f1ea746b11c886 100644 (file)
 
 #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
index 9bd34aa6761a5e17e33309fd65e3935eed9ab827..87a49b81d10197362c64836f3e976eba1b8a5cee 100644 (file)
@@ -25,9 +25,7 @@
 
 #include <inttypes.h>
 
-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
index dc2cc501925e01b21b4bfea65b000772dfc60c8b..f54da6df5ea1fb4363afea41731a463aebc2aec8 100644 (file)
@@ -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<FileInfo>
+{
+  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<file_info*>(x_calloc(mf->n_file_infos, sizeof(file_info)));
+    static_cast<FileInfo*>(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<std::string, file_stats>* stated_files,
+              std::unordered_map<std::string, digest>* 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<file_stats*>(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<file_stats*>(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<digest*>(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<digest*>(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<std::string, uint32_t /*index*/>* 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<uint32_t*>(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<FileInfo, uint32_t /*index*/>* 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<file_info*>(x_malloc(sizeof(file_info)));
-    *fi = infos[i];
-    uint32_t* index = static_cast<uint32_t*>(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<std::string, uint32_t>& mf_files)
 {
-  uint32_t* index = static_cast<uint32_t*>(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<file*>(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<std::string, uint32_t>& mf_files,
+                    const std::unordered_map<FileInfo, uint32_t>& 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<uint32_t*>(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<file_info*>(
-    x_realloc(mf->file_infos, (n + 1) * sizeof(file_info)));
+  mf->file_infos = static_cast<FileInfo*>(
+    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<std::string, digest>& 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<std::string, uint32_t /*index*/> mf_files;
+  create_file_index_map(mf->files, mf->n_files, &mf_files);
+
+  std::unordered_map<FileInfo, uint32_t /*index*/> 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<char*>(hashtable_iterator_key(iter));
-    auto digest = static_cast<struct digest*>(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<std::string, digest>& included_files)
 {
   uint32_t n_results = mf->n_results;
   mf->results = static_cast<result*>(
@@ -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<uint32_t*>(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<std::string, file_stats> stated_files;
+  std::unordered_map<std::string, digest> 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<digest*>(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<std::string, digest>& 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();
index 21a5587040b30d30a4627b047f99443b387e051e..71f8e194a77d97469a5745be9aa30655a07a5b06 100644 (file)
 #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<std::string, digest>& 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 (file)
index 308e72c..0000000
+++ /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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-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 (file)
index de3d257..0000000
+++ /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 (file)
index 1ee43da..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Copyright (C) 2002, 2004 Christopher Clark  <firstname.lastname@cl.cam.ac.uk> */
-
-#include "hashtable.h"
-#define HASHTABLE_INDEXFOR
-#include "hashtable_private.h"
-#include "hashtable_itr.h"
-#include <stdlib.h> /* 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 (file)
index 823e556..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
-
-#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 (file)
index b0a8c65..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
-
-#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.
-*/