From b4f53143b0e05fd3061cdf2e65e17a6a2904090b Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Fri, 24 Jul 2015 00:50:58 -0700 Subject: Migrate source files into src/ directory This change moves source files into a src/ directory, and puts object files into an obj/ directory. The Makefile and xcode project are updated accordingly. Fixes #1866 --- src/intern.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/intern.cpp (limited to 'src/intern.cpp') diff --git a/src/intern.cpp b/src/intern.cpp new file mode 100644 index 00000000..56dec21a --- /dev/null +++ b/src/intern.cpp @@ -0,0 +1,92 @@ +/** \file intern.c + + Library for pooling common strings + +*/ +#include "config.h" + + +#include +#include +#include +#include +#include +#include + +#include "fallback.h" +#include "util.h" + +#include "wutil.h" +#include "common.h" +#include "intern.h" + +/** Comparison function for intern'd strings */ +class string_table_compare_t +{ +public: + bool operator()(const wchar_t *a, const wchar_t *b) const + { + return wcscmp(a, b) < 0; + } +}; + +/* A sorted vector ends up being a little more memory efficient than a std::set for the intern'd string table */ +#define USE_SET 0 +#if USE_SET +/** The table of intern'd strings */ +typedef std::set string_table_t; +#else +/** The table of intern'd strings */ +typedef std::vector string_table_t; +#endif + +static string_table_t string_table; + +/** The lock to provide thread safety for intern'd strings */ +static pthread_mutex_t intern_lock = PTHREAD_MUTEX_INITIALIZER; + +static const wchar_t *intern_with_dup(const wchar_t *in, bool dup) +{ + if (!in) + return NULL; + +// debug( 0, L"intern %ls", in ); + scoped_lock lock(intern_lock); + const wchar_t *result; + +#if USE_SET + string_table_t::const_iterator iter = string_table.find(in); + if (iter != string_table.end()) + { + result = *iter; + } + else + { + result = dup ? wcsdup(in) : in; + string_table.insert(result); + } +#else + string_table_t::iterator iter = std::lower_bound(string_table.begin(), string_table.end(), in, string_table_compare_t()); + if (iter != string_table.end() && wcscmp(*iter, in) == 0) + { + result = *iter; + } + else + { + result = dup ? wcsdup(in) : in; + string_table.insert(iter, result); + } +#endif + return result; +} + +const wchar_t *intern(const wchar_t *in) +{ + return intern_with_dup(in, true); +} + + +const wchar_t *intern_static(const wchar_t *in) +{ + return intern_with_dup(in, false); +} -- cgit v1.2.3