Skip to content

Commit

Permalink
Updated hash map definitions to try to use unordered_map if available…
Browse files Browse the repository at this point in the history
… and fall back to hash_map or map. Now done more cleanly using autoconf detection.
  • Loading branch information
ruven committed Dec 4, 2013
1 parent d960a93 commit f3beda8
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 57 deletions.
5 changes: 5 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
04/12/2013:
- Updated hash map definitions to try to use unordered_map if available and fall back to
hash_map or map. Now done more cleanly using autoconf detection.


02/12/2013:
- Changes to IIPImage, TPTImage and KakaduImage class contstructors to use more efficient
member initializer lists, which are also necessary for compilation with clang compiler.
Expand Down
158 changes: 158 additions & 0 deletions acinclude.m4
Original file line number Diff line number Diff line change
Expand Up @@ -664,3 +664,161 @@ fi
])
dnl
# AC_HEADER_TR1_UNORDERED_MAP
AC_DEFUN([AC_HEADER_TR1_UNORDERED_MAP], [
AC_CACHE_CHECK(for tr1/unordered_map,
ac_cv_cxx_tr1_unordered_map,
[AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([#include <tr1/unordered_map>], [using std::tr1::unordered_map;],
ac_cv_cxx_tr1_unordered_map=yes, ac_cv_cxx_tr1_unordered_map=no)
AC_LANG_RESTORE
])
if test "$ac_cv_cxx_tr1_unordered_map" = yes; then
AC_DEFINE(HAVE_TR1_UNORDERED_MAP,,[Define if tr1/unordered_map is present. ])
fi
])
# AC_COMPILE_STDCXX_OX
AC_DEFUN([AC_COMPILE_STDCXX_0X], [
AC_CACHE_CHECK(if g++ supports C++0x features without additional flags,
ac_cv_cxx_compile_cxx0x_native,
[AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = c;],,
ac_cv_cxx_compile_cxx0x_native=yes, ac_cv_cxx_compile_cxx0x_native=no)
AC_LANG_RESTORE
])
AC_CACHE_CHECK(if g++ supports C++0x features with -std=c++0x,
ac_cv_cxx_compile_cxx0x_cxx,
[AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -std=c++0x"
AC_TRY_COMPILE([
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = c;],,
ac_cv_cxx_compile_cxx0x_cxx=yes, ac_cv_cxx_compile_cxx0x_cxx=no)
CXXFLAGS="$ac_save_CXXFLAGS"
AC_LANG_RESTORE
])
AC_CACHE_CHECK(if g++ supports C++0x features with -std=gnu++0x,
ac_cv_cxx_compile_cxx0x_gxx,
[AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -std=gnu++0x"
AC_TRY_COMPILE([
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = c;],,
ac_cv_cxx_compile_cxx0x_gxx=yes, ac_cv_cxx_compile_cxx0x_gxx=no)
CXXFLAGS="$ac_save_CXXFLAGS"
AC_LANG_RESTORE
])
if test "$ac_cv_cxx_compile_cxx0x_native" = yes ||
test "$ac_cv_cxx_compile_cxx0x_cxx" = yes ||
test "$ac_cv_cxx_compile_cxx0x_gxx" = yes; then
AC_DEFINE(HAVE_STDCXX_0X,,[Define if g++ supports C++0x features. ])
fi
])
AU_ALIAS([AC_CXX_HEADER_UNORDERED_MAP], [AX_CXX_HEADER_UNORDERED_MAP])
AC_DEFUN([AX_CXX_HEADER_UNORDERED_MAP], [
AC_CACHE_CHECK(for unordered_map,
ax_cv_cxx_unordered_map,
[AC_REQUIRE([AC_COMPILE_STDCXX_0X])
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -std=gnu++0x"
AC_TRY_COMPILE([#include <unordered_map>], [using std::unordered_map;],
ax_cv_cxx_unordered_map=yes, ax_cv_cxx_unordered_map=no)
CXXFLAGS="$ac_save_CXXFLAGS"
AC_LANG_RESTORE
])
if test "$ax_cv_cxx_unordered_map" = yes; then
AC_DEFINE(HAVE_UNORDERED_MAP,,[Define if unordered_map is present. ])
fi
])
AU_ALIAS([AC_CXX_NAMESPACES], [AX_CXX_NAMESPACES])
AC_DEFUN([AX_CXX_NAMESPACES],
[AC_CACHE_CHECK(whether the compiler implements namespaces,
ax_cv_cxx_namespaces,
[AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([namespace Outer { namespace Inner { int i = 0; }}
using namespace Outer::Inner; int foo(void) { return i;} ])],
ax_cv_cxx_namespaces=yes, ax_cv_cxx_namespaces=no)
AC_LANG_POP
])
if test "$ax_cv_cxx_namespaces" = yes; then
AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces])
fi
])
AU_ALIAS([AC_CXX_HAVE_EXT_HASH_MAP], [AX_CXX_HAVE_EXT_HASH_MAP])
AC_DEFUN([AX_CXX_HAVE_EXT_HASH_MAP],
[AC_CACHE_CHECK(whether the compiler has ext/hash_map,
ax_cv_cxx_have_ext_hash_map,
[AC_REQUIRE([AX_CXX_NAMESPACES])
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([#include <ext/hash_map>
#ifdef HAVE_NAMESPACES
using namespace __gnu_cxx;
#endif],[hash_map<int, int> t; return 0;],
ax_cv_cxx_have_ext_hash_map=yes, ax_cv_cxx_have_ext_hash_map=no)
AC_LANG_RESTORE
])
if test "$ax_cv_cxx_have_ext_hash_map" = yes; then
AC_DEFINE(HAVE_EXT_HASH_MAP,,[define if the compiler has ext/hash_map])
fi
])
8 changes: 7 additions & 1 deletion configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,17 @@ AC_FUNC_MALLOC
AC_CHECK_LIB(m, log2, AC_DEFINE(HAVE_LOG2))
AC_CHECK_FUNCS([setenv])

AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_CHECK_HEADERS(ext/pool_allocator.h)
AC_LANG_RESTORE

AC_HEADER_TR1_UNORDERED_MAP
AX_CXX_HAVE_EXT_HASH_MAP

# For our windows build
AC_CHECK_HEADERS(windows.h)


# we want largefile support, if possible
AC_SYS_LARGEFILE

Expand Down
71 changes: 40 additions & 31 deletions src/Cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,46 +26,58 @@
#ifndef _CACHE_H
#define _CACHE_H

// Remove our deprecated warnings for now. We should upgrade our hash_maps to
// unordered_maps, however
#undef __DEPRECATED

// Use the hashmap extensions if we are using >= gcc 3.1
#ifdef __GNUC__
// Fix missing snprintf in Windows
#if _MSC_VER
#define snprintf _snprintf
#endif



// Test for available map types. Try to use an efficient hashed map type if possible
#if defined(HAVE_TR1_UNORDERED_MAP)
#include <tr1/unordered_map>
#define HASHMAP std::tr1::unordered_map
// Need to define the hash function
namespace std {
namespace tr1 {
template<> struct hash< const std::string > {
size_t operator()( const std::string& x ) const {
return hash< const char* >()( x.c_str() );
}
};
}
}

#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || (__GNUC__ >= 4)
#define USE_HASHMAP 1
// Use the gcc hash_map extension if we have it
#elif defined(HAVE_EXT_HASH_MAP)
#include <ext/hash_map>
namespace __gnu_cxx
{
#define HASHMAP __gnu_cxx::hash_map
// Need to define the hash function
namespace __gnu_cxx {
template<> struct hash< const std::string > {
size_t operator()( const std::string& x ) const {
return hash< const char* >()( x.c_str() );
}
};
}
#endif

// And the high performance memory pool allocator if >= gcc 3.4
#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)
#define POOL_ALLOCATOR 1
#include <ext/pool_allocator.h>
#endif

#endif
// If no hash type available, just use map
#else
#include <map>
#define HASHMAP std::map

#endif // End of #if defined

#ifndef USE_HASHMAP
#include <map>
#endif


// Fix missing snprintf in Windows
#if _MSC_VER
#define snprintf _snprintf
// Try to use the gcc high performance memory pool allocator (available in gcc >= 3.4)
#ifdef HAVE_EXT_POOL_ALLOCATOR
#include <ext/pool_allocator.h>
#endif



#include <iostream>
#include <list>
#include <string>
Expand All @@ -90,7 +102,7 @@ class Cache {
unsigned long currentSize;

/// Main cache storage typedef
#ifdef POOL_ALLOCATOR
#ifdef HAVE_EXT_POOL_ALLOCATOR
typedef std::list < std::pair<const std::string,RawTile>,
__gnu_cxx::__pool_alloc< std::pair<const std::string,RawTile> > > TileList;
#else
Expand All @@ -101,20 +113,17 @@ class Cache {
typedef std::list < std::pair<const std::string,RawTile> >::iterator List_Iter;

/// Index typedef
#ifdef USE_HASHMAP
#ifdef POOL_ALLOCATOR
typedef __gnu_cxx::hash_map < const std::string, List_Iter,
#ifdef HAVE_EXT_POOL_ALLOCATOR
typedef HASHMAP < const std::string, List_Iter,
__gnu_cxx::hash< const std::string >,
std::equal_to< const std::string >,
__gnu_cxx::__pool_alloc< std::pair<const std::string, List_Iter> >
> TileMap;
#else
typedef __gnu_cxx::hash_map < const std::string,List_Iter > TileMap;
#endif
#else
typedef std::map < const std::string,List_Iter > TileMap;
typedef HASHMAP < const std::string,List_Iter > TileMap;
#endif


/// Main cache storage object
TileList tileList;

Expand Down
30 changes: 5 additions & 25 deletions src/Task.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,43 +40,23 @@
#endif


// Define our http header cache max age
// Define our http header cache max age (24 hours)
#define MAX_AGE 86400


// Use the hashmap extensions if we are using >= gcc 3.1
#ifdef __GNUC__

#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || (__GNUC__ >= 4)
#define USE_HASHMAP 1
#endif

// And the high performance memory pool allocator if >= gcc 3.4
#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)
#define USE_POOL_ALLOCATOR 1
#endif

#endif



#ifdef USE_HASHMAP
#include <ext/hash_map>

#ifdef USE_POOL_ALLOCATOR
#ifdef HAVE_EXT_POOL_ALLOCATOR
#include <ext/pool_allocator.h>
typedef __gnu_cxx::hash_map < const std::string, IIPImage,
typedef HASHMAP < const std::string, IIPImage,
__gnu_cxx::hash< const std::string >,
std::equal_to< const std::string >,
__gnu_cxx::__pool_alloc< std::pair<const std::string,IIPImage> >
> imageCacheMapType;
#else
typedef __gnu_cxx::hash_map <const std::string,IIPImage> imageCacheMapType;
typedef HASHMAP <const std::string,IIPImage> imageCacheMapType;
#endif

#else
typedef std::map<const std::string,IIPImage> imageCacheMapType;
#endif




Expand Down

0 comments on commit f3beda8

Please sign in to comment.