1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-12-28 05:29:33 +02:00

Remove Google sparsehash library.

GMenu2X now uses tr1::unordered_map instead, which results in a much smaller binary.
The Google library might have its uses when high performance is required, but for us a smaller binary is more important since that reduces startup time.
This commit is contained in:
Maarten ter Huurne 2010-07-28 03:37:40 +02:00
parent 4ddc189847
commit 599628fa38
78 changed files with 1 additions and 32003 deletions

View File

@ -27,7 +27,7 @@ noinst_HEADERS = asfont.h button.h cpu.h dirdialog.h FastDelegate.h \
AM_CFLAGS= @CFLAGS@ @SDL_CFLAGS@
AM_CXXFLAGS = @CXXFLAGS@ @SDL_CFLAGS@ -Isparsehash-1.6/src -DTARGET_GP2X \
AM_CXXFLAGS = @CXXFLAGS@ @SDL_CFLAGS@ -DTARGET_GP2X \
-Wall -Wextra -Wundef -Wunused-macros
gmenu2x_LDADD = @LIBS@ @SDL_LIBS@ -lSDL_image -lSDL_gfx -lSDL -ljpeg -lpng12 -lz -ldl -lpthread

View File

@ -1,2 +0,0 @@
opensource@google.com

View File

@ -1,28 +0,0 @@
Copyright (c) 2005, Google Inc.
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 Google Inc. nor the names of its
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.

View File

@ -1,182 +0,0 @@
Fri Jan 8 14:47:55 2010 Google Inc. <opensource@google.com>
* sparsehash: version 1.6 release
* New accessor methods for deleted_key, empty_key (sjackman)
* Use explicit hash functions in sparsehash tests (csilvers)
* BUGFIX: Cast resize to fix SUNWspro bug (csilvers)
* Check for sz overflow in min_size (csilvers)
* Speed up clear() for dense and sparse hashtables (jeff)
* Avoid shrinking in all cases when min-load is 0 (shaunj, csilvers)
* Improve densehashtable code for the deleted key (gpike)
* BUGFIX: Fix operator= when the 2 empty-keys differ (andreidam)
* BUGFIX: Fix ht copying when empty-key isn't set (andreidam)
* PORTING: Use TmpFile() instead of /tmp on MinGW (csilvers)
* PORTING: Use filenames that work with Stratus VOS.
Tue May 12 14:16:38 2009 Google Inc. <opensource@google.com>
* sparsehash: version 1.5.2 release
* Fix compile error: not initializing set_key in all constructors
Fri May 8 15:23:44 2009 Google Inc. <opensource@google.com>
* sparsehash: version 1.5.1 release
* Fix broken equal_range() for all the hash-classes (csilvers)
Wed May 6 11:28:49 2009 Google Inc. <opensource@google.com>
* sparsehash: version 1.5 release
* Support the tr1 unordered_map (and unordered_set) API (csilvers)
* Store only key for delkey; reduces need for 0-arg c-tor (csilvers)
* Prefer unordered_map to hash_map for the timing test (csilvers)
* PORTING: update the resource use for 64-bit machines (csilvers)
* PORTING: fix MIN/MAX collisions by un-#including windows.h (csilvers)
* Updated autoconf version to 2.61 and libtool version to 1.5.26
Wed Jan 28 17:11:31 2009 Google Inc. <opensource@google.com>
* sparsehash: version 1.4 release
* Allow hashtables to be <32 buckets (csilvers)
* Fix initial-sizing bug: was sizing tables too small (csilvers)
* Add asserts that clients don't abuse deleted/empty key (csilvers)
* Improve determination of 32/64 bit for C code (csilvers)
* Small fix for doc files in rpm (csilvers)
Thu Nov 6 15:06:09 2008 Google Inc. <opensource@google.com>
* sparsehash: version 1.3 release
* Add an interface to change the parameters for resizing (myl)
* Document another potentially good hash function (csilvers)
Thu Sep 18 13:53:20 2008 Google Inc. <opensource@google.com>
* sparsehash: version 1.2 release
* Augment documentation to better describe namespace issues (csilvers)
* BUG FIX: replace hash<> with SPARSEHASH_HASH, for windows (csilvers)
* Add timing test to unittest to test repeated add+delete (csilvers)
* Do better picking a new size when resizing (csilvers)
* Use ::google instead of google as a namespace (csilvers)
* Improve threading test at config time (csilvers)
Mon Feb 11 16:30:11 2008 Google Inc. <opensource@google.com>
* sparsehash: version 1.1 release
* Fix brown-paper-bag bug in some constructors (rafferty)
* Fix problem with variables shadowing member vars, add -Wshadow
Thu Nov 29 11:44:38 2007 Google Inc. <opensource@google.com>
* sparsehash: version 1.0.2 release
* Fix a final reference to hash<> to use SPARSEHASH_HASH<> instead.
Wed Nov 14 08:47:48 2007 Google Inc. <opensource@google.com>
* sparsehash: version 1.0.1 release :-(
* Remove an unnecessary (harmful) "#define hash" in windows' config.h
Tue Nov 13 15:15:46 2007 Google Inc. <opensource@google.com>
* sparsehash: version 1.0 release! We are now out of beta.
* Clean up Makefile awk script to be more readable (csilvers)
* Namespace fixes: use fewer #defines, move typedefs into namespace
Fri Oct 12 12:35:24 2007 Google Inc. <opensource@google.com>
* sparsehash: version 0.9.1 release
* Fix Makefile awk script to work on more architectures (csilvers)
* Add test to test code in more 'real life' situations (csilvers)
Tue Oct 9 14:15:21 2007 Google Inc. <opensource@google.com>
* sparsehash: version 0.9 release
* More type-hygiene improvements, especially for 64-bit (csilvers)
* Some configure improvements to improve portability, utility (austern)
* Small bugfix for operator== for dense_hash_map (jeff)
Tue Jul 3 12:55:04 2007 Google Inc. <opensource@google.com>
* sparsehash: version 0.8 release
* Minor type-hygiene improvements: size_t for int, etc. (csilvers)
* Porting improvements: tests pass on OS X, FreeBSD, Solaris (csilvers)
* Full windows port! VS solution provided for all unittests (csilvers)
Mon Jun 11 11:33:41 2007 Google Inc. <opensource@google.com>
* sparsehash: version 0.7 release
* Syntax fixes to better support gcc 4.3 and VC++ 7 (mec, csilvers)
* Improved windows/VC++ support (see README.windows) (csilvers)
* Config improvements: better tcmalloc support and config.h (csilvers)
* More robust with missing hash_map + nix 'trampoline' .h's (csilvers)
* Support for STLport's hash_map/hash_fun locations (csilvers)
* Add .m4 files to distribution; now all source is there (csilvers)
* Tiny modification of shrink-threshhold to allow never-shrinking (amc)
* Protect timing tests against aggressive optimizers (csilvers)
* Extend time_hash_map to test bigger objects (csilvers)
* Extend type-trait support to work with const objects (csilvers)
* USER VISIBLE: speed up all code by replacing memmove with memcpy
(csilvers)
Tue Mar 20 17:29:34 2007 Google Inc. <opensource@google.com>
* sparsehash: version 0.6 release
* Some improvement to type-traits (jyasskin)
* Better timing results when google-perftools is installed (sanjay)
* Updates and fixes to html documentation and README (csilvers)
* A bit more careful about #includes (csilvers)
* Fix for typo that broken compilation on some systems (csilvers)
* USER VISIBLE: New clear_no_resize() method added to dense_hash_map
(uszkoreit)
Sat Oct 21 13:47:47 2006 Google Inc. <opensource@google.com>
* sparsehash: version 0.5 release
* Support uint16_t (SunOS) in addition to u_int16_t (BSD) (csilvers)
* Get rid of UNDERSTANDS_ITERATOR_TAGS; everyone understands (csilvers)
* Test that empty-key and deleted-key differ (rbayardo)
* Fix example docs: strcmp needs to test for NULL (csilvers)
Sun Apr 23 22:42:35 2006 Google Inc. <opensource@google.com>
* sparsehash: version 0.4 release
* Remove POD requirement for keys and values! (austern)
* Add tr1-compatible type-traits system to speed up POD ops. (austern)
* Fixed const-iterator bug where postfix ++ didn't compile. (csilvers)
* Fixed iterator comparison bugs where <= was incorrect. (csilvers)
* Clean up config.h to keep its #defines from conflicting. (csilvers)
* Big documentation sweep and cleanup. (csilvers)
* Update documentation to talk more about good hash fns. (csilvers)
* Fixes to compile on MSVC (working around some MSVC bugs). (rennie)
* Avoid resizing hashtable on operator[] lookups (austern)
Thu Nov 3 20:12:31 2005 Google Inc. <opensource@google.com>
* sparsehash: version 0.3 release
* Quiet compiler warnings on some compilers. (csilvers)
* Some documentation fixes: example code for dense_hash_map. (csilvers)
* Fix a bug where swap() wasn't swapping delete_key(). (csilvers)
* set_deleted_key() and set_empty_key() now take a key only,
allowing hash-map values to be forward-declared. (csilvers)
* support for std::insert_iterator (and std::inserter). (csilvers)
Mon May 2 07:04:46 2005 Google Inc. <opensource@google.com>
* sparsehash: version 0.2 release
* Preliminary support for msvc++ compilation. (csilvers)
* Documentation fixes -- some example code was incomplete! (csilvers)
* Minimize size of config.h to avoid other-package conflicts (csilvers)
* Contribute a C-based version of sparsehash that served as the
inspiration for this code. One day, I hope to clean it up and
support it, but for now it's just in experimental/, for playing
around with. (csilvers)
* Change default namespace from std to google. (csilvers)
Fri Jan 14 16:53:32 2005 Google Inc. <opensource@google.com>
* sparsehash: initial release:
The sparsehash package contains several hash-map implementations,
similar in API to SGI's hash_map class, but with different
performance characteristics. sparse_hash_map uses very little
space overhead: 1-2 bits per entry. dense_hash_map is typically
faster than the default SGI STL implementation. This package
also includes hash-set analogues of these classes.

View File

@ -1,236 +0,0 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script). Here is a another example:
/bin/bash ./configure CONFIG_SHELL=/bin/bash
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
configuration-related scripts to be executed by `/bin/bash'.
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View File

@ -1,157 +0,0 @@
## Process this file with automake to produce Makefile.in
# Make sure that when we re-make ./configure, we get the macros we need
ACLOCAL_AMFLAGS = -I m4
# This is so we can #include <google/foo>
AM_CPPFLAGS = -I$(top_srcdir)/src
# These are good warnings to turn on by default
if GCC
AM_CXXFLAGS = -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -Wshadow
endif
googleincludedir = $(includedir)/google
## The .h files you want to install (that is, .h files that people
## who install this package can include in their own applications.)
googleinclude_HEADERS = \
src/google/dense_hash_map \
src/google/dense_hash_set \
src/google/sparse_hash_map \
src/google/sparse_hash_set \
src/google/sparsetable \
src/google/type_traits.h
docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
## This is for HTML and other documentation you want to install.
## Add your documentation files (in doc/) in addition to these boilerplate
## Also add a TODO file if you have one
dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README README.windows \
TODO \
doc/dense_hash_map.html \
doc/dense_hash_set.html \
doc/sparse_hash_map.html \
doc/sparse_hash_set.html \
doc/sparsetable.html \
doc/implementation.html \
doc/performance.html \
doc/index.html \
doc/designstyle.css
## The libraries (.so's) you want to install
lib_LTLIBRARIES =
## The location of the windows project file for each binary we make
WINDOWS_PROJECTS = google-sparsehash.sln
## unittests you want to run when people type 'make check'.
## TESTS is for binary unittests, check_SCRIPTS for script-based unittests.
## TESTS_ENVIRONMENT sets environment variables for when you run unittest,
## but it only seems to take effect for *binary* unittests (argh!)
TESTS = type_traits_unittest sparsetable_unittest hashtable_unittest \
simple_test
# TODO(csilvers): get simple_test working on windows
WINDOWS_PROJECTS += vsprojects/type_traits_unittest/type_traits_unittest.vcproj \
vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj \
vsprojects/hashtable_unittest/hashtable_unittest.vcproj
check_SCRIPTS =
TESTS_ENVIRONMENT =
## This should always include $(TESTS), but may also include other
## binaries that you compile but don't want automatically installed.
noinst_PROGRAMS = $(TESTS) time_hash_map
WINDOWS_PROJECTS += vsprojects/time_hash_map/time_hash_map.vcproj
## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
# All our .h files need to read the config information in config.h. The
# autoheader config.h has too much info, including PACKAGENAME, that
# might conflict with other config.h's an application might #include.
# Thus, we create a "minimal" config.h, called sparseconfig.h, that
# includes only the #defines we really need, and that are unlikely to
# change from system to system. NOTE: The awk command is equivalent to
# fgrep -B2 -f- $(top_builddir)/src/config.h \
# fgrep -vx -e -- > _sparsehash_config
# For correctness, it depends on the fact config.h.include does not have
# any lines starting with #.
src/google/sparsehash/sparseconfig.h: $(top_builddir)/src/config.h \
$(top_srcdir)/src/config.h.include
[ -d $(@D) ] || mkdir -p $(@D)
echo "/*" > $(@D)/_sparsehash_config
echo " * NOTE: This file is for internal use only." >> $(@D)/_sparsehash_config
echo " * Do not use these #defines in your own program!" >> $(@D)/_sparsehash_config
echo " */" >> $(@D)/_sparsehash_config
$(AWK) '{prevline=currline; currline=$$0;} \
/^#/ {in_second_file = 1;} \
!in_second_file {if (currline !~ /^ *$$/) {inc[currline]=0}}; \
in_second_file { for (i in inc) { \
if (index(currline, i) != 0) { \
print "\n"prevline"\n"currline; \
delete inc[i]; \
} \
} }' \
$(top_srcdir)/src/config.h.include $(top_builddir)/src/config.h \
>> $(@D)/_sparsehash_config
mv -f $(@D)/_sparsehash_config $@
# This is how we tell automake about auto-generated .h files
BUILT_SOURCES = src/google/sparsehash/sparseconfig.h
CLEANFILES = src/google/sparsehash/sparseconfig.h
sparsehashincludedir = $(googleincludedir)/sparsehash
sparsehashinclude_HEADERS = \
src/google/sparsehash/densehashtable.h \
src/google/sparsehash/sparsehashtable.h
nodist_sparsehashinclude_HEADERS = src/google/sparsehash/sparseconfig.h
type_traits_unittest_SOURCES = \
src/type_traits_unittest.cc \
$(sparsehashinclude_HEADERS) \
src/google/type_traits.h
nodist_type_traits_unittest_SOURCES = $(nodist_sparsehashinclude_HEADERS)
sparsetable_unittest_SOURCES = \
src/sparsetable_unittest.cc \
$(sparsehashinclude_HEADERS) \
src/google/sparsetable
nodist_sparsetable_unittest_SOURCES = $(nodist_sparsehashinclude_HEADERS)
hashtable_unittest_SOURCES = \
src/hashtable_unittest.cc \
$(googleinclude_HEADERS) \
$(sparsehashinclude_HEADERS) \
src/words
nodist_hashtable_unittest_SOURCES = $(nodist_sparsehashinclude_HEADERS)
simple_test_SOURCES = \
src/simple_test.cc \
$(sparsehashinclude_HEADERS)
nodist_simple_test_SOURCES = $(nodist_sparsehashinclude_HEADERS)
time_hash_map_SOURCES = \
src/time_hash_map.cc \
$(sparsehashinclude_HEADERS) \
$(googleinclude_HEADERS)
nodist_time_hash_map_SOURCES = $(nodist_sparsehashinclude_HEADERS)
# If tcmalloc is installed, use it with time_hash_map; it gives us
# heap-usage statistics for the hash_map routines, which is very nice
time_hash_map_CXXFLAGS = @tcmalloc_flags@ $(AM_CXXFLAGS)
time_hash_map_LDFLAGS = @tcmalloc_flags@
time_hash_map_LDADD = @tcmalloc_libs@
## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
@cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
deb: dist-gzip packages/deb.sh packages/deb/*
@cd packages && ./deb.sh ${PACKAGE} ${VERSION}
# Windows wants write permission to .vcproj files and maybe even sln files.
dist-hook:
test -e "$(distdir)/vsprojects" \
&& chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/
EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
src/config.h.include src/windows $(WINDOWS_PROJECTS) experimental

View File

@ -1,149 +0,0 @@
This directory contains several hash-map implementations, similar in
API to SGI's hash_map class, but with different performance
characteristics. sparse_hash_map uses very little space overhead, 1-2
bits per entry. dense_hash_map is very fast, particulary on lookup.
(sparse_hash_set and dense_hash_set are the set versions of these
routines.) On the other hand, these classes have requirements that
may not make them appropriate for all applications.
All these implementation use a hashtable with internal quadratic
probing. This method is space-efficient -- there is no pointer
overhead -- and time-efficient for good hash functions.
COMPILING
---------
To compile test applications with these classes, run ./configure
followed by make. To install these header files on your system, run
'make install'. (On Windows, the instructions are different; see
README.windows.) See INSTALL for more details.
This code should work on any modern C++ system. It has been tested on
Linux (Ubuntu, Fedora, RedHat, Debian), Solaris 10 x86, FreeBSD 6.0,
OS X 10.3 and 10.4, and Windows under both VC++7 and VC++8.
USING
-----
See the html files in the doc directory for small example programs
that use these classes. It's enough to just include the header file:
#include <google/sparse_hash_map> // or sparse_hash_set, dense_hash_map, ...
google::sparse_hash_set<int, int> number_mapper;
and use the class the way you would other hash-map implementations.
(Though see "API" below for caveats.)
By default (you can change it via a flag to ./configure), these hash
implementations are defined in the google namespace.
API
---
The API for sparse_hash_map, dense_hash_map, sparse_hash_set, and
dense_hash_set, are a superset of the API of SGI's hash_map class.
See doc/sparse_hash_map.html, et al., for more information about the
API.
The usage of these classes differ from SGI's hash_map, and other
hashtable implementations, in the following major ways:
1) dense_hash_map requires you to set aside one key value as the
'empty bucket' value, set via the set_empty_key() method. This
*MUST* be called before you can use the dense_hash_map. It is
illegal to insert any elements into a dense_hash_map whose key is
equal to the empty-key.
2) For both dense_hash_map and sparse_hash_map, if you wish to delete
elements from the hashtable, you must set aside a key value as the
'deleted bucket' value, set via the set_deleted_key() method. If
your hash-map is insert-only, there is no need to call this
method. If you call set_deleted_key(), it is illegal to insert any
elements into a dense_hash_map or sparse_hash_map whose key is
equal to the deleted-key.
3) These hash-map implementation support I/O. See below.
There are also some smaller differences:
1) The constructor takes an optional argument that specifies the
number of elements you expect to insert into the hashtable. This
differs from SGI's hash_map implementation, which takes an optional
number of buckets.
2) erase() does not immediately reclaim memory. As a consequence,
erase() does not invalidate any iterators, making loops like this
correct:
for (it = ht.begin(); it != ht.end(); ++it)
if (...) ht.erase(it);
As another consequence, a series of erase() calls can leave your
hashtable using more memory than it needs to. The hashtable will
automatically compact() at the next call to insert(), but to
manually compact a hashtable, you can call
ht.resize(0)
3) While sparse_hash_map et al. accept an Allocator template argument,
they ignore it. They use malloc() and free() for all memory
allocations.
4) sparse_hash_map et al. do not use exceptions.
I/O
---
In addition to the normal hash-map operations, sparse_hash_map can
read and write hashtables to disk. (dense_hash_map also has the API,
but it has not yet been implemented, and writes will always fail.)
In the simplest case, writing a hashtable is as easy as calling two
methods on the hashtable:
ht.write_metadata(fp);
ht.write_nopointer_data(fp);
Reading in this data is equally simple:
google::sparse_hash_map<...> ht;
ht.read_metadata(fp);
ht.read_nopointer_data(fp);
The above is sufficient if the key and value do not contain any
pointers: they are basic C types or agglomorations of basic C types.
If the key and/or value do contain pointers, you can still store the
hashtable by replacing write_nopointer_data() with a custom writing
routine. See sparse_hash_map.html et al. for more information.
SPARSETABLE
-----------
In addition to the hash-map and hash-set classes, this package also
provides sparsetable.h, an array implementation that uses space
proportional to the number of elements in the array, rather than the
maximum element index. It uses very little space overhead: 1 bit per
entry. See doc/sparsetable.html for the API.
RESOURCE USAGE
--------------
* sparse_hash_map has memory overhead of about 2 bits per hash-map
entry.
* dense_hash_map has a factor of 2-3 memory overhead: if your
hashtable data takes X bytes, dense_hash_map will use 3X-4X memory
total.
Hashtables tend to double in size when resizing, creating an
additional 50% space overhead. dense_hash_map does in fact have a
significant "high water mark" memory use requirement.
sparse_hash_map, however, is written to need very little space
overhead when resizing: only a few bits per hashtable entry.
PERFORMANCE
-----------
You can compile and run the included file time_hash_map.cc to examine
the performance of sparse_hash_map, dense_hash_map, and your native
hash_map implementation on your system. One test against the
SGI hash_map implementation gave the following timing information for
a simple find() call:
SGI hash_map: 22 ns
dense_hash_map: 13 ns
sparse_hash_map: 117 ns
SGI map: 113 ns
See doc/performance.html for more detailed charts on resource usage
and performance data.
---
16 March 2005
(Last updated: 20 March 2007)

View File

@ -1,28 +0,0 @@
1) TODO: I/O implementation in densehashtable.h
2) TODO: document SPARSEHASH_STAT_UPDATE macro, and also macros that
tweak performance. Perhaps add support to these to the API?
3) TODO: support exceptions?
4) BUG: sparsetable's operator[] doesn't work well with printf: you
need to explicitly cast the result to value_type to print it. (It
works fine with streams.)
5) TODO: consider rewriting dense_hash_map to use a 'groups' scheme,
like sparsetable, but without the sparse-allocation within a
group. This makes resizing have better memory-use properties. The
downside is that probes across groups might take longer since
groups are not contiguous in memory. Making groups the same size
as a cache-line, and ensuring they're loaded on cache-line
boundaries, might help. Needs careful testing to make sure it
doesn't hurt performance.
6) TODO: Get the C-only version of sparsehash in experimental/ ready
for prime-time.
7) TODO: use cmake (www.cmake.org) to make it easy to isntall this on
a windows system.
---
28 February 2007

View File

@ -1,868 +0,0 @@
# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION so it can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.9.6])])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
# therefore $ac_aux_dir as well) can be either absolute or relative,
# depending on how configure is run. This is pretty annoying, since
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
# source directory, any form will work fine, but in subdirectories a
# relative path needs to be adjusted first.
#
# $ac_aux_dir/missing
# fails when called from a subdirectory if $ac_aux_dir is relative
# $top_srcdir/$ac_aux_dir/missing
# fails if $ac_aux_dir is absolute,
# fails when called from a subdirectory in a VPATH build with
# a relative $ac_aux_dir
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
# harmless because $srcdir is `.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
# and then we would define $MISSING as
# MISSING="\${SHELL} $am_aux_dir/missing"
# This will work as long as MISSING is not called from configure, because
# unfortunately $(top_srcdir) has no meaning in configure.
# However there are other variables, like CC, which are often used in
# configure, and could therefore not use this "fixed" $ac_aux_dir.
#
# Another solution, used here, is to always expand $ac_aux_dir to an
# absolute PATH. The drawback is that using absolute paths prevent a
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
[dnl Rely on autoconf to set up CDPATH properly.
AC_PREREQ([2.50])dnl
# expand $ac_aux_dir to an absolute path
am_aux_dir=`cd $ac_aux_dir && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 7
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
[AC_PREREQ(2.52)dnl
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])
AC_SUBST([$1_FALSE])
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
AC_MSG_ERROR([[conditional "$1" was never defined.
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 8
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX", "GCJ", or "OBJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
[$1], CXX, [depcc="$CXX" am_compiler_list=],
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
[depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
# We will build objects and dependencies in a subdirectory because
# it helps to detect inapplicable dependency modes. For instance
# both Tru64's cc and ICC support -MD to output dependencies as a
# side effect of compilation, but ICC will put the dependencies in
# the current directory while Tru64 will put them in the object
# directory.
mkdir sub
am_cv_$1_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
fi
for depmode in $am_compiler_list; do
# Setup a source with many dependencies, because some compilers
# like to wrap large dependency lists on column 80 (with \), and
# we should not choose a depcomp mode which is confused by this.
#
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
# Solaris 8's {/usr,}/bin/sh.
touch sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
case $depmode in
nosideeffect)
# after this tag, mechanisms are not by side-effect, so they'll
# only be used when explicitly requested
if test "x$enable_dependency_tracking" = xyes; then
continue
else
break
fi
;;
none) break ;;
esac
# We check with `-c' and `-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this.
if depmode=$depmode \
source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
$SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
>/dev/null 2>conftest.err &&
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
# icc doesn't choke on unknown options, it will just issue warnings
# or remarks (even with -Werror). So we grep stderr for any message
# that says an option was ignored or not supported.
# When given -MP, icc 7.0 and 7.1 complain thusly:
# icc: Command line warning: ignoring option '-M'; no argument required
# The diagnosis changed in icc 8.0:
# icc: Command line remark: option '-MP' not supported
if (grep 'ignoring option' conftest.err ||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
am_cv_$1_dependencies_compiler_type=$depmode
break
fi
fi
done
cd ..
rm -rf conftest.dir
else
am_cv_$1_dependencies_compiler_type=none
fi
])
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
AM_CONDITIONAL([am__fastdep$1], [
test "x$enable_dependency_tracking" != xno \
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
])
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
])
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE(dependency-tracking,
[ --disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
#serial 3
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[for mf in $CONFIG_FILES; do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
# We used to match only the files named `Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# So let's grep whole file.
if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
# from the Makefile without running `make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
test -z "am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# When using ansi2knr, U may be empty or an underscore; expand it
U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
# AM_OUTPUT_DEPENDENCY_COMMANDS
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each `.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 8
# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 12
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
# The call with PACKAGE and VERSION arguments is the old style
# call (pre autoconf-2.50), which is being phased out. PACKAGE
# and VERSION should now be passed to AC_INIT and removed from
# the call to AM_INIT_AUTOMAKE.
# We support both call styles for the transition. After
# the next Automake release, Autoconf can make the AC_INIT
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_PREREQ([2.58])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
# test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" &&
test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
# test whether we have cygpath
if test -z "$CYGPATH_W"; then
if (cygpath --version) >/dev/null 2>/dev/null; then
CYGPATH_W='cygpath -w'
else
CYGPATH_W=echo
fi
fi
AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
AM_MISSING_PROG(AUTOCONF, autoconf)
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
AM_MISSING_PROG(AUTOHEADER, autoheader)
AM_MISSING_PROG(MAKEINFO, makeinfo)
AM_PROG_INSTALL_SH
AM_PROG_INSTALL_STRIP
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
[_AM_PROG_TAR([v7])])])
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
[_AM_DEPENDENCIES(CC)],
[define([AC_PROG_CC],
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
[_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_CXX],
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
])
])
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[# Compute $1's index in $config_headers.
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
$1 | $1:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
install_sh=${install_sh-"$am_aux_dir/install-sh"}
AC_SUBST(install_sh)])
# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 2
# Check whether the underlying file-system supports filenames
# with a leading dot. For instance MS-DOS doesn't.
AC_DEFUN([AM_SET_LEADING_DOT],
[rm -rf .tst 2>/dev/null
mkdir .tst 2>/dev/null
if test -d .tst; then
am__leading_dot=.
else
am__leading_dot=_
fi
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 3
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
am__doit:
@echo done
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# We grep out `Entering directory' and `Leaving directory'
# messages which can occur if `w' ends up in MAKEFLAGS.
# In particular we don't look at `^make:' because GNU make might
# be invoked under some other name (usually "gmake"), in which
# case it prints its new name instead of `make'.
if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
am__include=include
am__quote=
_am_result=GNU
fi
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
am__include=.include
am__quote="\""
_am_result=BSD
fi
fi
AC_SUBST([am__include])
AC_SUBST([am__quote])
AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 4
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it supports --run.
# If it does, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
# Use eval to expand $SHELL
if eval "$MISSING --run true"; then
am_missing_run="$MISSING --run "
else
am_missing_run=
AC_MSG_WARN([`missing' script is too old or missing])
fi
])
# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_MKDIR_P
# ---------------
# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
#
# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
# created by `make install' are always world readable, even if the
# installer happens to have an overly restrictive umask (e.g. 077).
# This was a mistake. There are at least two reasons why we must not
# use `-m 0755':
# - it causes special bits like SGID to be ignored,
# - it may be too restrictive (some setups expect 775 directories).
#
# Do not use -m 0755 and let people choose whatever they expect by
# setting umask.
#
# We cannot accept any implementation of `mkdir' that recognizes `-p'.
# Some implementations (such as Solaris 8's) are not thread-safe: if a
# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
# concurrently, both version can detect that a/ is missing, but only
# one can create it and the other will error out. Consequently we
# restrict ourselves to GNU make (using the --version option ensures
# this.)
AC_DEFUN([AM_PROG_MKDIR_P],
[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
# We used to keeping the `.' as first argument, in order to
# allow $(mkdir_p) to be used without argument. As in
# $(mkdir_p) $(somedir)
# where $(somedir) is conditionally defined. However this is wrong
# for two reasons:
# 1. if the package is installed by a user who cannot write `.'
# make install will fail,
# 2. the above comment should most certainly read
# $(mkdir_p) $(DESTDIR)$(somedir)
# so it does not work when $(somedir) is undefined and
# $(DESTDIR) is not.
# To support the latter case, we have to write
# test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
# so the `.' trick is pointless.
mkdir_p='mkdir -p --'
else
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because `.' already
# exists.
for d in ./-p ./--version;
do
test -d $d && rmdir $d
done
# $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
if test -f "$ac_aux_dir/mkinstalldirs"; then
mkdir_p='$(mkinstalldirs)'
else
mkdir_p='$(install_sh) -d'
fi
fi
AC_SUBST([mkdir_p])])
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 3
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
# ------------------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
# ----------------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 4
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftest.file
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
if test "$[*]" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftest.file`
fi
rm -f conftest.file
if test "$[*]" != "X $srcdir/configure conftest.file" \
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "$[2]" = conftest.file
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT(yes)])
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_INSTALL_STRIP
# ---------------------
# One issue with vendor `install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in `make install-strip', and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
# Installed binaries are usually stripped using `strip' when the user
# run `make install-strip'. However `strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
# will honor the `STRIP' environment variable to overrule this program.
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 2
# _AM_PROG_TAR(FORMAT)
# --------------------
# Check how to create a tarball in format FORMAT.
# FORMAT should be one of `v7', `ustar', or `pax'.
#
# Substitute a variable $(am__tar) that is a command
# writing to stdout a FORMAT-tarball containing the directory
# $tardir.
# tardir=directory && $(am__tar) > result.tar
#
# Substitute a variable $(am__untar) that extract such
# a tarball read from stdin.
# $(am__untar) < result.tar
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility.
AM_MISSING_PROG([AMTAR], [tar])
m4_if([$1], [v7],
[am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
[m4_case([$1], [ustar],, [pax],,
[m4_fatal([Unknown tar format])])
AC_MSG_CHECKING([how to create a $1 tar archive])
# Loop over all known methods to create a tar archive until one works.
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
# Do not fold the above two line into one, because Tru64 sh and
# Solaris sh will not grok spaces in the rhs of `-'.
for _am_tool in $_am_tools
do
case $_am_tool in
gnutar)
for _am_tar in tar gnutar gtar;
do
AM_RUN_LOG([$_am_tar --version]) && break
done
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
am__untar="$_am_tar -xf -"
;;
plaintar)
# Must skip GNU tar: if it does not support --format= it doesn't create
# ustar tarball either.
(tar --version) >/dev/null 2>&1 && continue
am__tar='tar chf - "$$tardir"'
am__tar_='tar chf - "$tardir"'
am__untar='tar xf -'
;;
pax)
am__tar='pax -L -x $1 -w "$$tardir"'
am__tar_='pax -L -x $1 -w "$tardir"'
am__untar='pax -r'
;;
cpio)
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
am__untar='cpio -i -H $1 -d'
;;
none)
am__tar=false
am__tar_=false
am__untar=false
;;
esac
# If the value was cached, stop now. We just wanted to have am__tar
# and am__untar set.
test -n "${am_cv_prog_tar_$1}" && break
# tar/untar a dummy directory, and stop if the command works
rm -rf conftest.dir
mkdir conftest.dir
echo GrepMe > conftest.dir/file
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
rm -rf conftest.dir
if test -s conftest.tar; then
AM_RUN_LOG([$am__untar <conftest.tar])
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
fi
done
rm -rf conftest.dir
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
m4_include([m4/acx_pthread.m4])
m4_include([m4/google_namespace.m4])
m4_include([m4/namespaces.m4])
m4_include([m4/stl_hash.m4])
m4_include([m4/stl_hash_fun.m4])
m4_include([m4/stl_namespace.m4])

View File

@ -1,74 +0,0 @@
## Process this file with autoconf to produce configure.
## In general, the safest way to proceed is to run ./autogen.sh
# make sure we're interpreted by some minimal autoconf
AC_PREREQ(2.57)
AC_INIT(sparsehash, 1.6, opensource@google.com)
# The argument here is just something that should be in the current directory
# (for sanity checking)
AC_CONFIG_SRCDIR(README)
AM_INIT_AUTOMAKE([dist-zip])
AM_CONFIG_HEADER(src/config.h)
# Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
AM_CONDITIONAL(GCC, test "$GCC" = yes) # let the Makefile know if we're gcc
# Check whether some low-level functions/files are available
AC_HEADER_STDC
AC_CHECK_FUNCS(memcpy memmove)
AC_CHECK_TYPES([uint16_t]) # defined in C99 systems
AC_CHECK_TYPES([u_int16_t]) # defined in BSD-derived systems, and gnu
AC_CHECK_TYPES([__uint16]) # defined in some windows systems (vc7)
AC_CHECK_TYPES([long long]) # probably defined everywhere, but...
# These are 'only' needed for unittests
AC_CHECK_HEADERS(sys/resource.h unistd.h sys/time.h sys/utsname.h)
# If you have google-perftools installed, we can do a bit more testing.
# We not only want to set HAVE_MALLOC_EXTENSION_H, we also want to set
# a variable to let the Makefile to know to link in tcmalloc.
AC_LANG([C++])
AC_CHECK_HEADERS(google/malloc_extension.h,
tcmalloc_libs=-ltcmalloc,
tcmalloc_libs=)
# On some systems, when linking in tcmalloc you also need to link in
# pthread. That's a bug somewhere, but we'll work around it for now.
tcmalloc_flags=""
if test -n "$tcmalloc_libs"; then
ACX_PTHREAD
tcmalloc_flags="\$(PTHREAD_CFLAGS)"
tcmalloc_libs="$tcmalloc_libs \$(PTHREAD_LIBS)"
fi
AC_SUBST(tcmalloc_flags)
AC_SUBST(tcmalloc_libs)
# Figure out where hash_map lives and also hash_fun.h (or stl_hash_fun.h).
# This also tells us what namespace hash code lives in.
AC_CXX_STL_HASH
AC_CXX_STL_HASH_FUN
# Find out what namespace 'normal' STL code lives in, and also what namespace
# the user wants our classes to be defined in
AC_CXX_STL_NAMESPACE
AC_DEFINE_GOOGLE_NAMESPACE(google)
# In unix-based systems, hash is always defined as hash<> (in namespace.
# HASH_NAMESPACE.) So we can use a simple AC_DEFINE here. On
# windows, and possibly on future unix STL implementations, this
# macro will evaluate to something different.)
AC_DEFINE(SPARSEHASH_HASH_NO_NAMESPACE, hash,
[The system-provided hash function, in namespace HASH_NAMESPACE.])
# Do *not* define this in terms of SPARSEHASH_HASH_NO_NAMESPACE, because
# SPARSEHASH_HASH is exported to sparseconfig.h, but S_H_NO_NAMESPACE isn't.
AC_DEFINE(SPARSEHASH_HASH, HASH_NAMESPACE::hash,
[The system-provided hash function including the namespace.])
# Write generated configuration file
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,115 +0,0 @@
body {
background-color: #ffffff;
color: black;
margin-right: 1in;
margin-left: 1in;
}
h1, h2, h3, h4, h5, h6 {
color: #3366ff;
font-family: sans-serif;
}
@media print {
/* Darker version for printing */
h1, h2, h3, h4, h5, h6 {
color: #000080;
font-family: helvetica, sans-serif;
}
}
h1 {
text-align: center;
font-size: 18pt;
}
h2 {
margin-left: -0.5in;
}
h3 {
margin-left: -0.25in;
}
h4 {
margin-left: -0.125in;
}
hr {
margin-left: -1in;
}
/* Definition lists: definition term bold */
dt {
font-weight: bold;
}
address {
text-align: right;
}
/* Use the <code> tag for bits of code and <var> for variables and objects. */
code,pre,samp,var {
color: #006000;
}
/* Use the <file> tag for file and directory paths and names. */
file {
color: #905050;
font-family: monospace;
}
/* Use the <kbd> tag for stuff the user should type. */
kbd {
color: #600000;
}
div.note p {
float: right;
width: 3in;
margin-right: 0%;
padding: 1px;
border: 2px solid #6060a0;
background-color: #fffff0;
}
UL.nobullets {
list-style-type: none;
list-style-image: none;
margin-left: -1em;
}
/*
body:after {
content: "Google Confidential";
}
*/
/* pretty printing styles. See prettify.js */
.str { color: #080; }
.kwd { color: #008; }
.com { color: #800; }
.typ { color: #606; }
.lit { color: #066; }
.pun { color: #660; }
.pln { color: #000; }
.tag { color: #008; }
.atn { color: #606; }
.atv { color: #080; }
pre.prettyprint { padding: 2px; border: 1px solid #888; }
.embsrc { background: #eee; }
@media print {
.str { color: #060; }
.kwd { color: #006; font-weight: bold; }
.com { color: #600; font-style: italic; }
.typ { color: #404; font-weight: bold; }
.lit { color: #044; }
.pun { color: #440; }
.pln { color: #000; }
.tag { color: #006; font-weight: bold; }
.atn { color: #404; }
.atv { color: #060; }
}
/* Table Column Headers */
.hdr {
color: #006;
font-weight: bold;
background-color: #dddddd; }
.hdr2 {
color: #006;
background-color: #eeeeee; }

View File

@ -1,371 +0,0 @@
<HTML>
<HEAD>
<title>Implementation notes: sparse_hash, dense_hash, sparsetable</title>
</HEAD>
<BODY>
<h1>Implementation of sparse_hash_map, dense_hash_map, and
sparsetable</h1>
This document contains a few notes on how the data structures in this
package are implemented. This discussion refers at several points to
the classic text in this area: Knuth, <i>The Art of Computer
Programming</i>, Vol 3, Hashing.
<hr>
<h2><tt>sparsetable</tt></h2>
<p>For specificity, consider the declaration </p>
<pre>
sparsetable&lt;Foo&gt; t(100); // a sparse array with 100 elements
</pre>
<p>A sparsetable is a random container that implements a sparse array,
that is, an array that uses very little memory to store unassigned
indices (in this case, between 1-2 bits per unassigned index). For
instance, if you allocate an array of size 5 and assign a[2] = [big
struct], then a[2] will take up a lot of memory but a[0], a[1], a[3],
and a[4] will not. Array elements that have a value are called
"assigned". Array elements that have no value yet, or have had their
value cleared using erase() or clear(), are called "unassigned".
For assigned elements, lookups return the assigned value; for
unassigned elements, they return the default value, which for t is
Foo().</p>
<p>sparsetable is implemented as an array of "groups". Each group is
responsible for M array indices. The first group knows about
t[0]..t[M-1], the second about t[M]..t[2M-1], and so forth. (M is 48
by default.) At construct time, t creates an array of (99/M + 1)
groups. From this point on, all operations -- insert, delete, lookup
-- are passed to the appropriate group. In particular, any operation
on t[i] is actually performed on (t.group[i / M])[i % M].</p>
<p>Each group contains of a vector, which holds assigned values, and a
bitmap of size M, which indicates which indices are assigned. A
lookup works as follows: the group is asked to look up index i, where
i &lt; M. The group looks at bitmap[i]. If it's 0, the lookup fails.
If it's 1, then the group has to find the appropriate value in the
vector.</p>
<h3><tt>find()</tt></h3>
<p>Finding the appropriate vector element is the most expensive part of
the lookup. The code counts all bitmap entries &lt;= i that are set to
1. (There's at least 1 of them, since bitmap[i] is 1.) Suppose there
are 4 such entries. Then the right value to return is the 4th element
of the vector: vector[3]. This takes time O(M), which is a constant
since M is a constant.</p>
<h3><tt>insert()</tt></h3>
<p>Insert starts with a lookup. If the lookup succeeds, the code merely
replaces vector[3] with the new value. If the lookup fails, then the
code must insert a new entry into the middle of the vector. Again, to
insert at position i, the code must count all the bitmap entries &lt;= i
that are set to i. This indicates the position to insert into the
vector. All vector entries above that position must be moved to make
room for the new entry. This takes time, but still constant time
since the vector has size at most M.</p>
<p>(Inserts could be made faster by using a list instead of a vector to
hold group values, but this would use much more memory, since each
list element requires a full pointer of overhead.)</p>
<p>The only metadata that needs to be updated, after the actual value is
inserted, is to set bitmap[i] to 1. No other counts must be
maintained.</p>
<h3><tt>delete()</tt></h3>
<p>Deletes are similar to inserts. They start with a lookup. If it
fails, the delete is a noop. Otherwise, the appropriate entry is
removed from the vector, all the vector elements above it are moved
down one, and bitmap[i] is set to 0.</p>
<h3>iterators</h3>
<p>Sparsetable iterators pose a special burden. They must iterate over
unassigned array values, but the act of iterating should not cause an
assignment to happen -- otherwise, iterating over a sparsetable would
cause it to take up much more room. For const iterators, the matter
is simple: the iterator is merely programmed to return the default
value -- Foo() -- when dereferenced while pointing to an unassigned
entry.</p>
<p>For non-const iterators, such simple techniques fail. Instead,
dereferencing a sparsetable_iterator returns an opaque object that
acts like a Foo in almost all situations, but isn't actually a Foo.
(It does this by defining operator=(), operator value_type(), and,
most sneakily, operator&().) This works in almost all cases. If it
doesn't, an explicit cast to value_type will solve the problem:</p>
<pre>
printf("%d", static_cast&lt;Foo&gt;(*t.find(0)));
</pre>
<p>To avoid such problems, consider using get() and set() instead of an
iterator:</p>
<pre>
for (int i = 0; i &lt; t.size(); ++i)
if (t.get(i) == ...) t.set(i, ...);
</pre>
<p>Sparsetable also has a special class of iterator, besides normal and
const: nonempty_iterator. This only iterates over array values that
are assigned. This is particularly fast given the sparsetable
implementation, since it can ignore the bitmaps entirely and just
iterate over the various group vectors.</p>
<h3>Resource use</h3>
<p>The space overhead for an sparsetable of size N is N + 48N/M bits.
For the default value of M, this is exactly 2 bits per array entry.
(That's for 32-bit pointers; for machines with 64-bit pointers, it's N
+ 80N/M bits, or 2.67 bits per entry.)
A larger M would use less overhead -- approaching 1 bit per array
entry -- but take longer for inserts, deletes, and lookups. A smaller
M would use more overhead but make operations somewhat faster.</p>
<p>You can also look at some specific <A
HREF="performance.html">performance numbers</A>.</p>
<hr>
<h2><tt>sparse_hash_set</tt></h2>
<p>For specificity, consider the declaration </p>
<pre>
sparse_hash_set&lt;Foo&gt; t;
</pre>
<p>sparse_hash_set is a hashtable. For more information on hashtables,
see Knuth. Hashtables are basically arrays with complicated logic on
top of them. sparse_hash_set uses a sparsetable to implement the
underlying array.</p>
<p>In particular, sparse_hash_set stores its data in a sparsetable using
quadratic internal probing (see Knuth). Many hashtable
implementations use external probing, so each table element is
actually a pointer chain, holding many hashtable values.
sparse_hash_set, on the other hand, always stores at most one value in
each table location. If the hashtable wants to store a second value
at a given table location, it can't; it's forced to look somewhere
else.</p>
<h3><tt>insert()</tt></h3>
<p>As a specific example, suppose t is a new sparse_hash_set. It then
holds a sparsetable of size 32. The code for t.insert(foo) works as
follows:</p>
<p>
1) Call hash&lt;Foo&gt;(foo) to convert foo into an integer i. (hash&lt;Foo&gt; is
the default hash function; you can specify a different one in the
template arguments.)
</p><p>
2a) Look at t.sparsetable[i % 32]. If it's unassigned, assign it to
foo. foo is now in the hashtable.
</p><p>
2b) If t.sparsetable[i % 32] is assigned, and its value is foo, then
do nothing: foo was already in t and the insert is a noop.
</p><p>
2c) If t.sparsetable[i % 32] is assigned, but to a value other than
foo, look at t.sparsetable[(i+1) % 32]. If that also fails, try
t.sparsetable[(i+3) % 32], then t.sparsetable[(i+6) % 32]. In
general, keep trying the next triangular number.
</p><p>
3) If the table is now "too full" -- say, 25 of the 32 table entries
are now assigned -- grow the table by creating a new sparsetable
that's twice as big, and rehashing every single element from the
old table into the new one. This keeps the table from ever filling
up.
</p><p>
4) If the table is now "too empty" -- say, only 3 of the 32 table
entries are now assigned -- shrink the table by creating a new
sparsetable that's half as big, and rehashing every element as in
the growing case. This keeps the table overhead proportional to
the number of elements in the table.
</p>
<p>Instead of using triangular numbers as offsets, one could just use
regular integers: try i, then i+1, then i+2, then i+3. This has bad
'clumping' behavior, as explored in Knuth. Quadratic probing, using
the triangular numbers, avoids the clumping while keeping cache
coherency in the common case. As long as the table size is a power of
2, the quadratic-probing method described above will explore every
table element if necessary, to find a good place to insert.</p>
<p>(As a side note, using a table size that's a power of two has several
advantages, including the speed of calculating (i % table_size). On
the other hand, power-of-two tables are not very forgiving of a poor
hash function. Make sure your hash function is a good one! There are
plenty of dos and don'ts on the web (and in Knuth), for writing hash
functions.)</p>
<p>The "too full" value, also called the "maximum occupancy", determines
a time-space tradeoff: in general, the higher it is, the less space is
wasted but the more probes must be performed for each insert.
sparse_hash_set uses a high maximum occupancy, since space is more
important than speed for this data structure.</p>
<p>The "too empty" value is not necessary for performance but helps with
space use. It's rare for hashtable implementations to check this
value at insert() time -- after all, how will inserting cause a
hashtable to get too small? However, the sparse_hash_set
implementation never resizes on erase(); it's nice to have an erase()
that does not invalidate iterators. Thus, the first insert() after a
long string of erase()s could well trigger a hashtable shrink.</p>
<h3><tt>find()</tt></h3>
<p>find() works similarly to insert. The only difference is in step
(2a): if the value is unassigned, then the lookup fails immediately.</p>
<h3><tt>delete()</tt></h3>
<p>delete() is tricky in an internal-probing scheme. The obvious
implementation of just "unassigning" the relevant table entry doesn't
work. Consider the following scenario:</p>
<pre>
t.insert(foo1); // foo1 hashes to 4, is put in table[4]
t.insert(foo2); // foo2 hashes to 4, is put in table[5]
t.erase(foo1); // table[4] is now 'unassigned'
t.lookup(foo2); // fails since table[hash(foo2)] is unassigned
</pre>
<p>To avoid these failure situations, delete(foo1) is actually
implemented by replacing foo1 by a special 'delete' value in the
hashtable. This 'delete' value causes the table entry to be
considered unassigned for the purposes of insertion -- if foo3 hashes
to 4 as well, it can go into table[4] no problem -- but assigned for
the purposes of lookup.</p>
<p>What is this special 'delete' value? The delete value has to be an
element of type Foo, since the table can't hold anything else. It
obviously must be an element the client would never want to insert on
its own, or else the code couldn't distinguish deleted entries from
'real' entries with the same value. There's no way to determine a
good value automatically. The client has to specify it explicitly.
This is what the set_deleted_key() method does.</p>
<p>Note that set_deleted_key() is only necessary if the client actually
wants to call t.erase(). For insert-only hash-sets, set_deleted_key()
is unnecessary.</p>
<p>When copying the hashtable, either to grow it or shrink it, the
special 'delete' values are <b>not</b> copied into the new table. The
copy-time rehash makes them unnecessary.</p>
<h3>Resource use</h3>
<p>The data is stored in a sparsetable, so space use is the same as
for sparsetable. However, by default the sparse_hash_set
implementation tries to keep about half the table buckets empty, to
keep lookup-chains short. Since sparsehashmap has about 2 bits
overhead per bucket (or 2.5 bits on 64-bit systems), sparse_hash_map
has about 4-5 bits overhead per hashtable item.</p>
<p>Time use is also determined in large part by the sparsetable
implementation. However, there is also an extra probing cost in
hashtables, which depends in large part on the "too full" value. It
should be rare to need more than 4-5 probes per lookup, and usually
significantly less will suffice.</p>
<p>A note on growing and shrinking the hashtable: all hashtable
implementations use the most memory when growing a hashtable, since
they must have room for both the old table and the new table at the
same time. sparse_hash_set is careful to delete entries from the old
hashtable as soon as they're copied into the new one, to minimize this
space overhead. (It does this efficiently by using its knowledge of
the sparsetable class and copying one sparsetable group at a time.)</p>
<p>You can also look at some specific <A
HREF="performance.html">performance numbers</A>.</p>
<hr>
<h2><tt>sparse_hash_map</tt></h2>
<p>sparse_hash_map is implemented identically to sparse_hash_set. The
only difference is instead of storing just Foo in each table entry,
the data structure stores pair&lt;Foo, Value&gt;.</p>
<hr>
<h2><tt>dense_hash_set</tt></h2>
<p>The hashtable aspects of dense_hash_set are identical to
sparse_hash_set: it uses quadratic internal probing, and resizes
hashtables in exactly the same way. The difference is in the
underlying array: instead of using a sparsetable, dense_hash_set uses
a C array. This means much more space is used, especially if Foo is
big. However, it makes all operations faster, since sparsetable has
memory management overhead that C arrays do not.</p>
<p>The use of C arrays instead of sparsetables points to one immediate
complication dense_hash_set has that sparse_hash_set does not: the
need to distinguish assigned from unassigned entries. In a
sparsetable, this is accomplished by a bitmap. dense_hash_set, on the
other hand, uses a dedicated value to specify unassigned entries.
Thus, dense_hash_set has two special values: one to indicate deleted
table entries, and one to indicated unassigned table entries. At
construct time, all table entries are initialized to 'unassigned'.</p>
<p>dense_hash_set provides the method set_empty_key() to indicate the
value that should be used for unassigned entries. Like
set_deleted_key(), set_empty_key() requires a value that will not be
used by the client for any legitimate purpose. Unlike
set_deleted_key(), set_empty_key() is always required, no matter what
hashtable operations the client wishes to perform.</p>
<h3>Resource use</h3>
<p>This implementation is fast because even though dense_hash_set may not
be space efficient, most lookups are localized: a single lookup may
need to access table[i], and maybe table[i+1] and table[i+3], but
nothing other than that. For all but the biggest data structures,
these will frequently be in a single cache line.</p>
<p>This implementation takes, for every unused bucket, space as big as
the key-type. Usually between half and two-thirds of the buckets are
empty.</p>
<p>The doubling method used by dense_hash_set tends to work poorly
with most memory allocators. This is because memory allocators tend
to have memory 'buckets' which are a power of two. Since each
doubling of a dense_hash_set doubles the memory use, a single
hashtable doubling will require a new memory 'bucket' from the memory
allocator, leaving the old bucket stranded as fragmented memory.
Hence, it's not recommended this data structure be used with many
inserts in memory-constrained situations.</p>
<p>You can also look at some specific <A
HREF="performance.html">performance numbers</A>.</p>
<hr>
<h2><tt>dense_hash_map</tt></h2>
<p>dense_hash_map is identical to dense_hash_set except for what values
are stored in each table entry.</p>
<hr>
<author>
Craig Silverstein<br>
Thu Jan 6 20:15:42 PST 2005
</author>
</body>
</html>

View File

@ -1,69 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Google Sparsehash Package</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="http://www.google.com/favicon.ico" type="image/x-icon"
rel="shortcut icon">
<link href="designstyle.css" type="text/css" rel="stylesheet">
<style>
<!--
ol.bluelist li {
color: #3366ff;
font-family: sans-serif;
}
ol.bluelist li p {
color: #000;
font-family: "Times Roman", times, serif;
}
ul.blacklist li {
color: #000;
font-family: "Times Roman", times, serif;
}
//-->
</style>
</head>
<body>
<h1> <a name="Google_Sparsehash_Package"></a>Google Sparsehash Package </h1>
<br>
<p>The Google sparsehash package consists of two hashtable
implementations: <i>sparse</i>, which is designed to be very space
efficient, and <i>dense</i>, which is designed to be very time
efficient. For each one, the package provides both a hash-map and a
hash-set, to mirror the classes in the common STL implementation.</p>
<p>Documentation on how to use these classes:</p>
<ul>
<li> <A HREF="sparse_hash_map.html">sparse_hash_map</A>
<li> <A HREF="sparse_hash_set.html">sparse_hash_set</A>
<li> <A HREF="dense_hash_map.html">dense_hash_map</A>
<li> <A HREF="dense_hash_set.html">dense_hash_set</A>
</ul>
<p>In addition to the hash-map (and hash-set) classes, there's also a
lower-level class that implements a "sparse" array. This class can be
useful in its own right; consider using it when you'd normally use a
<code>sparse_hash_map</code>, but your keys are all small-ish
integers.</p>
<ul>
<li> <A HREF="sparsetable.html">sparsetable</A>
</ul>
<p>There is also a doc explaining the <A
HREF="implementation.html">implementation details</A> of these
classes, for those who are curious. And finally, you can see some
<A HREF="performance.html">performance comparisons</A>, both between
the various classes here, but also between these implementations and
other standard hashtable implementations.</p>
<hr>
<address>
Craig Silverstein<br>
Last modified: Thu Jan 25 17:58:02 PST 2007
</address>
</body>
</html>

View File

@ -1,96 +0,0 @@
<HTML>
<HEAD>
<title>Performance notes: sparse_hash, dense_hash, sparsetable</title>
</HEAD>
<BODY>
<H2>Performance Numbers</H2>
<p>Here are some performance numbers from an example desktop machine,
taken from a version of time_hash_map that was instrumented to also
report memory allocation information (this modification is not
included by default because it required a big hack to do, including
modifying the STL code to not try to do its own freelist management).</p>
<p>Note there are lots of caveats on these numbers: they may differ from
machine to machine and compiler to compiler, and they only test a very
particular usage pattern that may not match how you use hashtables --
for instance, they test hashtables with very small keys. However,
they're still useful for a baseline comparison of the various
hashtable implementations.</p>
<p>These figures are from a 2.80GHz Pentium 4 with 2G of memory. The
'standard' hash_map and map implementations are the SGI STL code
included with <tt>gcc2</tt>. Compiled with <tt>gcc2.95.3 -g
-O2</tt></p>
<pre>
======
Average over 10000000 iterations
Wed Dec 8 14:56:38 PST 2004
SPARSE_HASH_MAP:
map_grow 665 ns
map_predict/grow 303 ns
map_replace 177 ns
map_fetch 117 ns
map_remove 192 ns
memory used in map_grow 84.3956 Mbytes
DENSE_HASH_MAP:
map_grow 84 ns
map_predict/grow 22 ns
map_replace 18 ns
map_fetch 13 ns
map_remove 23 ns
memory used in map_grow 256.0000 Mbytes
STANDARD HASH_MAP:
map_grow 162 ns
map_predict/grow 107 ns
map_replace 44 ns
map_fetch 22 ns
map_remove 124 ns
memory used in map_grow 204.1643 Mbytes
STANDARD MAP:
map_grow 297 ns
map_predict/grow 282 ns
map_replace 113 ns
map_fetch 113 ns
map_remove 238 ns
memory used in map_grow 236.8081 Mbytes
</pre>
<H2><A name="hashfn">A Note on Hash Functions</A></H2>
<p>For good performance, the Google hash routines depend on a good
hash function: one that distributes data evenly. Many hashtable
implementations come with sub-optimal hash functions that can degrade
performance. For instance, the hash function given in Knuth's _Art of
Computer Programming_, and the default string hash function in SGI's
STL implementation, both distribute certain data sets unevenly,
leading to poor performance.</p>
<p>As an example, in one test of the default SGI STL string hash
function against the Hsieh hash function (see below), for a particular
set of string keys, the Hsieh function resulted in hashtable lookups
that were 20 times as fast as the STLPort hash function. The string
keys were chosen to be "hard" to hash well, so these results may not
be typical, but they are suggestive.</p>
<p>There has been much research over the years into good hash
functions. Here are some hash functions of note.</p>
<ul>
<li> Bob Jenkins: <A HREF="http://burtleburtle.net/bob/hash/">http://burtleburtle.net/bob/hash/</A>
<li> Paul Hsieh: <A HREF="http://www.azillionmonkeys.com/qed/hash.html">http://www.azillionmonkeys.com/qed/hash.html</A>
<li> Fowler/Noll/Vo (FNV): <A HREF="http://www.isthe.com/chongo/tech/comp/fnv/">http://www.isthe.com/chongo/tech/comp/fnv/</A>
<li> MurmurHash: <A HREF="http://murmurhash.googlepages.com/">http://murmurhash.googlepages.com/</A>
</ul>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
example: example.o libchash.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
.SUFFIXES: .c .o .h
.c.o:
$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<
example.o: example.c libchash.h
libchash.o: libchash.c libchash.h

View File

@ -1,14 +0,0 @@
This is a C version of sparsehash (and also, maybe, densehash) that I
wrote way back when, and served as the inspiration for the C++
version. The API for the C version is much uglier than the C++,
because of the lack of template support. I believe the class works,
but I'm not convinced it's really flexible or easy enough to use.
It would be nice to rework this C class to follow the C++ API as
closely as possible (eg have a set_deleted_key() instead of using a
#define like this code does now). I believe the code compiles and
runs, if anybody is interested in using it now, but it's subject to
major change in the future, as people work on it.
Craig Silverstein
20 March 2005

View File

@ -1,54 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "libchash.h"
static void TestInsert() {
struct HashTable* ht;
HTItem* bck;
ht = AllocateHashTable(1, 0); /* value is 1 byte, 0: don't copy keys */
HashInsert(ht, PTR_KEY(ht, "January"), 31); /* 0: don't overwrite old val */
bck = HashInsert(ht, PTR_KEY(ht, "February"), 28);
bck = HashInsert(ht, PTR_KEY(ht, "March"), 31);
bck = HashFind(ht, PTR_KEY(ht, "February"));
assert(bck);
assert(bck->data == 28);
FreeHashTable(ht);
}
static void TestFindOrInsert() {
struct HashTable* ht;
int i;
int iterations = 1000000;
int range = 30; /* random number between 1 and 30 */
ht = AllocateHashTable(4, 0); /* value is 4 bytes, 0: don't copy keys */
/* We'll test how good rand() is as a random number generator */
for (i = 0; i < iterations; ++i) {
int key = rand() % range;
HTItem* bck = HashFindOrInsert(ht, key, 0); /* initialize to 0 */
bck->data++; /* found one more of them */
}
for (i = 0; i < range; ++i) {
HTItem* bck = HashFind(ht, i);
if (bck) {
printf("%3d: %d\n", bck->key, bck->data);
} else {
printf("%3d: 0\n", i);
}
}
FreeHashTable(ht);
}
int main(int argc, char** argv) {
TestInsert();
TestFindOrInsert();
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,252 +0,0 @@
/* Copyright (c) 1998 - 2005, Google Inc.
* 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 Google Inc. nor the names of its
* 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.
*
* ---
* Author: Craig Silverstein
*
* This library is intended to be used for in-memory hash tables,
* though it provides rudimentary permanent-storage capabilities.
* It attempts to be fast, portable, and small. The best algorithm
* to fulfill these goals is an internal probing hashing algorithm,
* as in Knuth, _Art of Computer Programming_, vol III. Unlike
* chained (open) hashing, it doesn't require a pointer for every
* item, yet it is still constant time lookup in practice.
*
* Also to save space, we let the contents (both data and key) that
* you insert be a union: if the key/data is small, we store it
* directly in the hashtable, otherwise we store a pointer to it.
* To keep you from having to figure out which, use KEY_PTR and
* PTR_KEY to convert between the arguments to these functions and
* a pointer to the real data. For instance:
* char key[] = "ab", *key2;
* HTItem *bck; HashTable *ht;
* HashInsert(ht, PTR_KEY(ht, key), 0);
* bck = HashFind(ht, PTR_KEY(ht, "ab"));
* key2 = KEY_PTR(ht, bck->key);
*
* There are a rich set of operations supported:
* AllocateHashTable() -- Allocates a hashtable structure and
* returns it.
* cchKey: if it's a positive number, then each key is a
* fixed-length record of that length. If it's 0,
* the key is assumed to be a \0-terminated string.
* fSaveKey: normally, you are responsible for allocating
* space for the key. If this is 1, we make a
* copy of the key for you.
* ClearHashTable() -- Removes everything from a hashtable
* FreeHashTable() -- Frees memory used by a hashtable
*
* HashFind() -- takes a key (use PTR_KEY) and returns the
* HTItem containing that key, or NULL if the
* key is not in the hashtable.
* HashFindLast() -- returns the item found by last HashFind()
* HashFindOrInsert() -- inserts the key/data pair if the key
* is not already in the hashtable, or
* returns the appropraite HTItem if it is.
* HashFindOrInsertItem() -- takes key/data as an HTItem.
* HashInsert() -- adds a key/data pair to the hashtable. What
* it does if the key is already in the table
* depends on the value of SAMEKEY_OVERWRITE.
* HashInsertItem() -- takes key/data as an HTItem.
* HashDelete() -- removes a key/data pair from the hashtable,
* if it's there. RETURNS 1 if it was there,
* 0 else.
* If you use sparse tables and never delete, the full data
* space is available. Otherwise we steal -2 (maybe -3),
* so you can't have data fields with those values.
* HashDeleteLast() -- deletes the item returned by the last Find().
*
* HashFirstBucket() -- used to iterate over the buckets in a
* hashtable. DON'T INSERT OR DELETE WHILE
* ITERATING! You can't nest iterations.
* HashNextBucket() -- RETURNS NULL at the end of iterating.
*
* HashSetDeltaGoalSize() -- if you're going to insert 1000 items
* at once, call this fn with arg 1000.
* It grows the table more intelligently.
*
* HashSave() -- saves the hashtable to a file. It saves keys ok,
* but it doesn't know how to interpret the data field,
* so if the data field is a pointer to some complex
* structure, you must send a function that takes a
* file pointer and a pointer to the structure, and
* write whatever you want to write. It should return
* the number of bytes written. If the file is NULL,
* it should just return the number of bytes it would
* write, without writing anything.
* If your data field is just an integer, not a
* pointer, just send NULL for the function.
* HashLoad() -- loads a hashtable. It needs a function that takes
* a file and the size of the structure, and expects
* you to read in the structure and return a pointer
* to it. You must do memory allocation, etc. If
* the data is just a number, send NULL.
* HashLoadKeys() -- unlike HashLoad(), doesn't load the data off disk
* until needed. This saves memory, but if you look
* up the same key a lot, it does a disk access each
* time.
* You can't do Insert() or Delete() on hashtables that were loaded
* from disk.
*/
#include <sys/types.h> /* includes definition of "ulong", we hope */
#define ulong u_long
#define MAGIC_KEY "CHsh" /* when we save the file */
#ifndef LOG_WORD_SIZE /* 5 for 32 bit words, 6 for 64 */
#if defined (__LP64__) || defined (_LP64)
#define LOG_WORD_SIZE 6 /* log_2(sizeof(ulong)) [in bits] */
#else
#define LOG_WORD_SIZE 5 /* log_2(sizeof(ulong)) [in bits] */
#endif
#endif
/* The following gives a speed/time tradeoff: how many buckets are *
* in each bin. 0 gives 32 buckets/bin, which is a good number. */
#ifndef LOG_BM_WORDS
#define LOG_BM_WORDS 0 /* each group has 2^L_B_W * 32 buckets */
#endif
/* The following are all parameters that affect performance. */
#ifndef JUMP
#define JUMP(key, offset) ( ++(offset) ) /* ( 1 ) for linear hashing */
#endif
#ifndef Table
#define Table(x) Sparse##x /* Dense##x for dense tables */
#endif
#ifndef FAST_DELETE
#define FAST_DELETE 0 /* if it's 1, we never shrink the ht */
#endif
#ifndef SAMEKEY_OVERWRITE
#define SAMEKEY_OVERWRITE 1 /* overwrite item with our key on insert? */
#endif
#ifndef OCCUPANCY_PCT
#define OCCUPANCY_PCT 0.5 /* large PCT means smaller and slower */
#endif
#ifndef MIN_HASH_SIZE
#define MIN_HASH_SIZE 512 /* ht size when first created */
#endif
/* When deleting a bucket, we can't just empty it (future hashes *
* may fail); instead we set the data field to DELETED. Thus you *
* should set DELETED to a data value you never use. Better yet, *
* if you don't need to delete, define INSERT_ONLY. */
#ifndef INSERT_ONLY
#define DELETED -2UL
#define IS_BCK_DELETED(bck) ( (bck) && (bck)->data == DELETED )
#define SET_BCK_DELETED(ht, bck) do { (bck)->data = DELETED; \
FREE_KEY(ht, (bck)->key); } while ( 0 )
#else
#define IS_BCK_DELETED(bck) 0
#define SET_BCK_DELETED(ht, bck) \
do { fprintf(stderr, "Deletion not supported for insert-only hashtable\n");\
exit(2); } while ( 0 )
#endif
/* We need the following only for dense buckets (Dense##x above). *
* If you need to, set this to a value you'll never use for data. */
#define EMPTY -3UL /* steal more of the bck->data space */
/* This is what an item is. Either can be cast to a pointer. */
typedef struct {
ulong data; /* 4 bytes for data: either a pointer or an integer */
ulong key; /* 4 bytes for the key: either a pointer or an int */
} HTItem;
struct Table(Bin); /* defined in chash.c, I hope */
struct Table(Iterator);
typedef struct Table(Bin) Table; /* Expands to SparseBin, etc */
typedef struct Table(Iterator) TableIterator;
/* for STORES_PTR to work ok, cchKey MUST BE DEFINED 1st, cItems 2nd! */
typedef struct HashTable {
ulong cchKey; /* the length of the key, or if it's \0 terminated */
ulong cItems; /* number of items currently in the hashtable */
ulong cDeletedItems; /* # of buckets holding DELETE in the hashtable */
ulong cBuckets; /* size of the table */
Table *table; /* The actual contents of the hashtable */
int fSaveKeys; /* 1 if we copy keys locally; 2 if keys in one block */
int cDeltaGoalSize; /* # of coming inserts (or deletes, if <0) we expect */
HTItem *posLastFind; /* position of last Find() command */
TableIterator *iter; /* used in First/NextBucket */
FILE *fpData; /* if non-NULL, what item->data points into */
char * (*dataRead)(FILE *, int); /* how to load data from disk */
HTItem bckData; /* holds data after being loaded from disk */
} HashTable;
/* Small keys are stored and passed directly, but large keys are
* stored and passed as pointers. To make it easier to remember
* what to pass, we provide two functions:
* PTR_KEY: give it a pointer to your data, and it returns
* something appropriate to send to Hash() functions or
* be stored in a data field.
* KEY_PTR: give it something returned by a Hash() routine, and
* it returns a (char *) pointer to the actual data.
*/
#define HashKeySize(ht) ( ((ulong *)(ht))[0] ) /* this is how we inline */
#define HashSize(ht) ( ((ulong *)(ht))[1] ) /* ...a la C++ :-) */
#define STORES_PTR(ht) ( HashKeySize(ht) == 0 || \
HashKeySize(ht) > sizeof(ulong) )
#define KEY_PTR(ht, key) ( STORES_PTR(ht) ? (char *)(key) : (char *)&(key) )
#ifdef DONT_HAVE_TO_WORRY_ABOUT_BUS_ERRORS
#define PTR_KEY(ht, ptr) ( STORES_PTR(ht) ? (ulong)(ptr) : *(ulong *)(ptr) )
#else
#define PTR_KEY(ht, ptr) ( STORES_PTR(ht) ? (ulong)(ptr) : HTcopy((char *)ptr))
#endif
/* Function prototypes */
unsigned long HTcopy(char *pul); /* for PTR_KEY, not for users */
struct HashTable *AllocateHashTable(int cchKey, int fSaveKeys);
void ClearHashTable(struct HashTable *ht);
void FreeHashTable(struct HashTable *ht);
HTItem *HashFind(struct HashTable *ht, ulong key);
HTItem *HashFindLast(struct HashTable *ht);
HTItem *HashFindOrInsert(struct HashTable *ht, ulong key, ulong dataInsert);
HTItem *HashFindOrInsertItem(struct HashTable *ht, HTItem *pItem);
HTItem *HashInsert(struct HashTable *ht, ulong key, ulong data);
HTItem *HashInsertItem(struct HashTable *ht, HTItem *pItem);
int HashDelete(struct HashTable *ht, ulong key);
int HashDeleteLast(struct HashTable *ht);
HTItem *HashFirstBucket(struct HashTable *ht);
HTItem *HashNextBucket(struct HashTable *ht);
int HashSetDeltaGoalSize(struct HashTable *ht, int delta);
void HashSave(FILE *fp, struct HashTable *ht, int (*write)(FILE *, char *));
struct HashTable *HashLoad(FILE *fp, char * (*read)(FILE *, int));
struct HashTable *HashLoadKeys(FILE *fp, char * (*read)(FILE *, int));

View File

@ -1,47 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "type_traits_unittest", "vsprojects\type_traits_unittest\type_traits_unittest.vcproj", "{008CCFED-7D7B-46F8-8E13-03837A2258B3}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sparsetable_unittest", "vsprojects\sparsetable_unittest\sparsetable_unittest.vcproj", "{E420867B-8BFA-4739-99EC-E008AB762FF9}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hashtable_unittest", "vsprojects\hashtable_unittest\hashtable_unittest.vcproj", "{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "time_hash_map", "vsprojects\time_hash_map\time_hash_map.vcproj", "{A74E5DB8-5295-487A-AB1D-23859F536F45}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{008CCFED-7D7B-46F8-8E13-03837A2258B3}.Debug.ActiveCfg = Debug|Win32
{008CCFED-7D7B-46F8-8E13-03837A2258B3}.Debug.Build.0 = Debug|Win32
{008CCFED-7D7B-46F8-8E13-03837A2258B3}.Release.ActiveCfg = Release|Win32
{008CCFED-7D7B-46F8-8E13-03837A2258B3}.Release.Build.0 = Release|Win32
{E420867B-8BFA-4739-99EC-E008AB762FF9}.Debug.ActiveCfg = Debug|Win32
{E420867B-8BFA-4739-99EC-E008AB762FF9}.Debug.Build.0 = Debug|Win32
{E420867B-8BFA-4739-99EC-E008AB762FF9}.Release.ActiveCfg = Release|Win32
{E420867B-8BFA-4739-99EC-E008AB762FF9}.Release.Build.0 = Release|Win32
{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}.Debug.ActiveCfg = Debug|Win32
{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}.Debug.Build.0 = Debug|Win32
{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}.Release.ActiveCfg = Release|Win32
{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}.Release.Build.0 = Release|Win32
{A74E5DB8-5295-487A-AB1D-23859F536F45}.Debug.ActiveCfg = Debug|Win32
{A74E5DB8-5295-487A-AB1D-23859F536F45}.Debug.Build.0 = Debug|Win32
{A74E5DB8-5295-487A-AB1D-23859F536F45}.Release.ActiveCfg = Release|Win32
{A74E5DB8-5295-487A-AB1D-23859F536F45}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@ -1,363 +0,0 @@
# This was retrieved from
# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
# See also (perhaps for new versions?)
# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
#
# We've rewritten the inconsistency check code (from avahi), to work
# more broadly. In particular, it no longer assumes ld accepts -zdefs.
# This caused a restructing of the code, but the functionality has only
# changed a little.
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
dnl
dnl @summary figure out how to build C programs using POSIX threads
dnl
dnl This macro figures out how to build C programs using POSIX threads.
dnl It sets the PTHREAD_LIBS output variable to the threads library and
dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
dnl C compiler flags that are needed. (The user can also force certain
dnl compiler flags/libs to be tested by setting these environment
dnl variables.)
dnl
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
dnl multi-threaded programs (defaults to the value of CC otherwise).
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
dnl
dnl NOTE: You are assumed to not only compile your program with these
dnl flags, but also link it with them as well. e.g. you should link
dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
dnl $LIBS
dnl
dnl If you are only building threads programs, you may wish to use
dnl these variables in your default LIBS, CFLAGS, and CC:
dnl
dnl LIBS="$PTHREAD_LIBS $LIBS"
dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
dnl CC="$PTHREAD_CC"
dnl
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
dnl
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
dnl default action will define HAVE_PTHREAD.
dnl
dnl Please let the authors know if this macro fails on any platform, or
dnl if you have any other suggestions or comments. This macro was based
dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
dnl We are also grateful for the helpful feedback of numerous users.
dnl
dnl @category InstalledPackages
dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
dnl @version 2006-05-29
dnl @license GPLWithACException
dnl
dnl Checks for GCC shared/pthread inconsistency based on work by
dnl Marcin Owsiany <marcin@owsiany.pl>
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_SAVE
AC_LANG_C
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
if test x"$acx_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[acx_pthread_ok=yes])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
if test "x$acx_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
[attr_name=$attr; break])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GCC" != xyes; then
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
else
PTHREAD_CC=$CC
fi
# The next part tries to detect GCC inconsistency with -shared on some
# architectures and systems. The problem is that in certain
# configurations, when -shared is specified, GCC "forgets" to
# internally use various flags which are still necessary.
#
# Prepare the flags
#
save_CFLAGS="$CFLAGS"
save_LIBS="$LIBS"
save_CC="$CC"
# Try with the flags determined by the earlier checks.
#
# -Wl,-z,defs forces link-time symbol resolution, so that the
# linking checks with -shared actually have any value
#
# FIXME: -fPIC is required for -shared on many architectures,
# so we specify it here, but the right way would probably be to
# properly detect whether it is actually required.
CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CC="$PTHREAD_CC"
# In order not to create several levels of indentation, we test
# the value of "$done" until we find the cure or run out of ideas.
done="no"
# First, make sure the CFLAGS we added are actually accepted by our
# compiler. If not (and OS X's ld, for instance, does not accept -z),
# then we can't do this test.
if test x"$done" = xno; then
AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
AC_TRY_LINK(,, , [done=yes])
if test "x$done" = xyes ; then
AC_MSG_RESULT([no])
else
AC_MSG_RESULT([yes])
fi
fi
if test x"$done" = xno; then
AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[done=yes])
if test "x$done" = xyes; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
fi
#
# Linux gcc on some architectures such as mips/mipsel forgets
# about -lpthread
#
if test x"$done" = xno; then
AC_MSG_CHECKING([whether -lpthread fixes that])
LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[done=yes])
if test "x$done" = xyes; then
AC_MSG_RESULT([yes])
PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
else
AC_MSG_RESULT([no])
fi
fi
#
# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
#
if test x"$done" = xno; then
AC_MSG_CHECKING([whether -lc_r fixes that])
LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[done=yes])
if test "x$done" = xyes; then
AC_MSG_RESULT([yes])
PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
else
AC_MSG_RESULT([no])
fi
fi
if test x"$done" = xno; then
# OK, we have run out of ideas
AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
# so it's not safe to assume that we may use pthreads
acx_pthread_ok=no
fi
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
CC="$save_CC"
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
acx_pthread_ok=no
$2
fi
AC_LANG_RESTORE
])dnl ACX_PTHREAD

View File

@ -1,42 +0,0 @@
# Allow users to override the namespace we define our application's classes in
# Arg $1 is the default namespace to use if --enable-namespace isn't present.
# In general, $1 should be 'google', so we put all our exported symbols in a
# unique namespace that is not likely to conflict with anyone else. However,
# when it makes sense -- for instance, when publishing stl-like code -- you
# may want to go with a different default, like 'std'.
# We guarantee the invariant that GOOGLE_NAMESPACE starts with ::,
# unless it's the empty string. Thus, it's always safe to do
# GOOGLE_NAMESPACE::foo and be sure you're getting the foo that's
# actually in the google namespace, and not some other namespace that
# the namespace rules might kick in.
AC_DEFUN([AC_DEFINE_GOOGLE_NAMESPACE],
[google_namespace_default=[$1]
AC_ARG_ENABLE(namespace, [ --enable-namespace=FOO to define these Google
classes in the FOO namespace. --disable-namespace
to define them in the global namespace. Default
is to define them in namespace $1.],
[case "$enableval" in
yes) google_namespace="$google_namespace_default" ;;
no) google_namespace="" ;;
*) google_namespace="$enableval" ;;
esac],
[google_namespace="$google_namespace_default"])
if test -n "$google_namespace"; then
ac_google_namespace="::$google_namespace"
ac_google_start_namespace="namespace $google_namespace {"
ac_google_end_namespace="}"
else
ac_google_namespace=""
ac_google_start_namespace=""
ac_google_end_namespace=""
fi
AC_DEFINE_UNQUOTED(GOOGLE_NAMESPACE, $ac_google_namespace,
Namespace for Google classes)
AC_DEFINE_UNQUOTED(_START_GOOGLE_NAMESPACE_, $ac_google_start_namespace,
Puts following code inside the Google namespace)
AC_DEFINE_UNQUOTED(_END_GOOGLE_NAMESPACE_, $ac_google_end_namespace,
Stops putting the code inside the Google namespace)
])

View File

@ -1,15 +0,0 @@
# Checks whether the compiler implements namespaces
AC_DEFUN([AC_CXX_NAMESPACES],
[AC_CACHE_CHECK(whether the compiler implements namespaces,
ac_cv_cxx_namespaces,
[AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([namespace Outer {
namespace Inner { int i = 0; }}],
[using namespace Outer::Inner; return i;],
ac_cv_cxx_namespaces=yes,
ac_cv_cxx_namespaces=no)
AC_LANG_RESTORE])
if test "$ac_cv_cxx_namespaces" = yes; then
AC_DEFINE(HAVE_NAMESPACES, 1, [define if the compiler implements namespaces])
fi])

View File

@ -1,70 +0,0 @@
# We check two things: where the include file is for
# unordered_map/hash_map (we prefer the first form), and what
# namespace unordered/hash_map lives in within that include file. We
# include AC_TRY_COMPILE for all the combinations we've seen in the
# wild. We define HASH_MAP_H to the location of the header file, and
# HASH_NAMESPACE to the namespace the class (unordered_map or
# hash_map) is in. We define HAVE_UNORDERED_MAP if the class we found
# is named unordered_map, or leave it undefined if not.
# This also checks if unordered map exists.
AC_DEFUN([AC_CXX_STL_HASH],
[AC_REQUIRE([AC_CXX_NAMESPACES])
AC_MSG_CHECKING(the location of hash_map)
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ac_cv_cxx_hash_map=""
# First try unordered_map, but not on gcc's before 4.2 -- I've
# seen unexplainable unordered_map bugs with -O2 on older gcc's.
AC_TRY_COMPILE([#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
# error GCC too old for unordered_map
#endif
],
[/* no program body necessary */],
[stl_hash_old_gcc=no],
[stl_hash_old_gcc=yes])
for location in unordered_map tr1/unordered_map; do
for namespace in std std::tr1; do
if test -z "$ac_cv_cxx_hash_map" -a "$stl_hash_old_gcc" != yes; then
# Some older gcc's have a buggy tr1, so test a bit of code.
AC_TRY_COMPILE([#include <$location>],
[const ${namespace}::unordered_map<int, int> t;
return t.find(5) == t.end();],
[ac_cv_cxx_hash_map="<$location>";
ac_cv_cxx_hash_namespace="$namespace";
ac_cv_cxx_have_unordered_map="yes";])
fi
done
done
# Now try hash_map
for location in ext/hash_map hash_map; do
for namespace in __gnu_cxx "" std stdext; do
if test -z "$ac_cv_cxx_hash_map"; then
AC_TRY_COMPILE([#include <$location>],
[${namespace}::hash_map<int, int> t],
[ac_cv_cxx_hash_map="<$location>";
ac_cv_cxx_hash_namespace="$namespace";
ac_cv_cxx_have_unordered_map="no";])
fi
done
done
ac_cv_cxx_hash_set=`echo "$ac_cv_cxx_hash_map" | sed s/map/set/`;
if test -n "$ac_cv_cxx_hash_map"; then
AC_DEFINE(HAVE_HASH_MAP, 1, [define if the compiler has hash_map])
AC_DEFINE(HAVE_HASH_SET, 1, [define if the compiler has hash_set])
AC_DEFINE_UNQUOTED(HASH_MAP_H,$ac_cv_cxx_hash_map,
[the location of <unordered_map> or <hash_map>])
AC_DEFINE_UNQUOTED(HASH_SET_H,$ac_cv_cxx_hash_set,
[the location of <unordered_set> or <hash_set>])
AC_DEFINE_UNQUOTED(HASH_NAMESPACE,$ac_cv_cxx_hash_namespace,
[the namespace of hash_map/hash_set])
if test "$ac_cv_cxx_have_unordered_map" = yes; then
AC_DEFINE(HAVE_UNORDERED_MAP,1,
[define if the compiler supports unordered_{map,set}])
fi
AC_MSG_RESULT([$ac_cv_cxx_hash_map])
else
AC_MSG_RESULT()
AC_MSG_WARN([could not find an STL hash_map])
fi
])

View File

@ -1,36 +0,0 @@
# We just try to figure out where hash<> is defined. It's in some file
# that ends in hash_fun.h...
#
# Ideally we'd use AC_CACHE_CHECK, but that only lets us store one value
# at a time, and we need to store two (filename and namespace).
# prints messages itself, so we have to do the message-printing ourselves
# via AC_MSG_CHECKING + AC_MSG_RESULT. (TODO(csilvers): can we cache?)
#
# tr1/functional_hash.h: new gcc's with tr1 support
# stl_hash_fun.h: old gcc's (gc2.95?)
# ext/hash_fun.h: newer gcc's (gcc4)
# stl/_hash_fun.h: STLport
AC_DEFUN([AC_CXX_STL_HASH_FUN],
[AC_REQUIRE([AC_CXX_STL_HASH])
AC_MSG_CHECKING(how to include hash_fun directly)
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ac_cv_cxx_stl_hash_fun=""
for location in functional tr1/functional \
ext/hash_fun.h ext/stl_hash_fun.h \
hash_fun.h stl_hash_fun.h \
stl/_hash_fun.h; do
if test -z "$ac_cv_cxx_stl_hash_fun"; then
AC_TRY_COMPILE([#include <$location>],
[int x = ${ac_cv_cxx_hash_namespace}::hash<int>()(5)],
[ac_cv_cxx_stl_hash_fun="<$location>";])
fi
done
AC_LANG_RESTORE
AC_DEFINE_UNQUOTED(HASH_FUN_H,$ac_cv_cxx_stl_hash_fun,
[the location of the header defining hash functions])
AC_DEFINE_UNQUOTED(HASH_NAMESPACE,$ac_cv_cxx_hash_namespace,
[the namespace of the hash<> function])
AC_MSG_RESULT([$ac_cv_cxx_stl_hash_fun])
])

View File

@ -1,25 +0,0 @@
# We check what namespace stl code like vector expects to be executed in
AC_DEFUN([AC_CXX_STL_NAMESPACE],
[AC_CACHE_CHECK(
what namespace STL code is in,
ac_cv_cxx_stl_namespace,
[AC_REQUIRE([AC_CXX_NAMESPACES])
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([#include <vector>],
[vector<int> t; return 0;],
ac_cv_cxx_stl_namespace=none)
AC_TRY_COMPILE([#include <vector>],
[std::vector<int> t; return 0;],
ac_cv_cxx_stl_namespace=std)
AC_LANG_RESTORE])
if test "$ac_cv_cxx_stl_namespace" = none; then
AC_DEFINE(STL_NAMESPACE,,
[the namespace where STL code like vector<> is defined])
fi
if test "$ac_cv_cxx_stl_namespace" = std; then
AC_DEFINE(STL_NAMESPACE,std,
[the namespace where STL code like vector<> is defined])
fi
])

View File

@ -1,360 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2005-06-08.21
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
case "$1" in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
tar)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View File

@ -1,158 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
scriptversion=2005-06-29.22
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain.
#
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
errstatus=0
dirmode=
usage="\
Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
Create each directory DIR (with mode MODE, if specified), including all
leading file name components.
Report bugs to <bug-automake@gnu.org>."
# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage"
exit $?
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--version)
echo "$0 $scriptversion"
exit $?
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
# mkdir -p a/c at the same time, both will detect that a is missing,
# one will create a, then the other will try to create a and die with
# a "File exists" error. This is a problem when calling mkinstalldirs
# from a parallel make. We use --version in the probe to restrict
# ourselves to GNU mkdir, which is thread-safe.
case $dirmode in
'')
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
else
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because `.' already
# exists.
test -d ./-p && rmdir ./-p
test -d ./--version && rmdir ./--version
fi
;;
*)
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
test ! -d ./--version; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
else
# Clean up after NextStep and OpenStep mkdir.
for d in ./-m ./-p ./--version "./$dirmode";
do
test -d $d && rmdir $d
done
fi
;;
esac
for file
do
case $file in
/*) pathcomp=/ ;;
*) pathcomp= ;;
esac
oIFS=$IFS
IFS=/
set fnord $file
shift
IFS=$oIFS
for d
do
test "x$d" = x && continue
pathcomp=$pathcomp$d
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp=$pathcomp/
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View File

@ -1,74 +0,0 @@
#!/bin/bash -e
# This takes one commandline argument, the name of the package. If no
# name is given, then we'll end up just using the name associated with
# an arbitrary .tar.gz file in the rootdir. That's fine: there's probably
# only one.
#
# Run this from the 'packages' directory, just under rootdir
## Set LIB to lib if exporting a library, empty-string else
LIB=
#LIB=lib
PACKAGE="$1"
VERSION="$2"
# We can only build Debian packages, if the Debian build tools are installed
if [ \! -x /usr/bin/debuild ]; then
echo "Cannot find /usr/bin/debuild. Not building Debian packages." 1>&2
exit 0
fi
# Double-check we're in the packages directory, just under rootdir
if [ \! -r ../Makefile -a \! -r ../INSTALL ]; then
echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2
echo "Also, you must run \"make dist\" before running this script." 1>&2
exit 0
fi
# Find the top directory for this package
topdir="${PWD%/*}"
# Find the tar archive built by "make dist"
archive="${PACKAGE}-${VERSION}"
archive_with_underscore="${PACKAGE}_${VERSION}"
if [ -z "${archive}" ]; then
echo "Cannot find ../$PACKAGE*.tar.gz. Run \"make dist\" first." 1>&2
exit 0
fi
# Create a pristine directory for building the Debian package files
trap 'rm -rf '`pwd`/tmp'; exit $?' EXIT SIGHUP SIGINT SIGTERM
rm -rf tmp
mkdir -p tmp
cd tmp
# Debian has very specific requirements about the naming of build
# directories, and tar archives. It also wants to write all generated
# packages to the parent of the source directory. We accommodate these
# requirements by building directly from the tar file.
ln -s "${topdir}/${archive}.tar.gz" "${LIB}${archive}.orig.tar.gz"
# Some version of debuilder want foo.orig.tar.gz with _ between versions.
ln -s "${topdir}/${archive}.tar.gz" "${LIB}${archive_with_underscore}.orig.tar.gz"
tar zfx "${LIB}${archive}.orig.tar.gz"
[ -n "${LIB}" ] && mv "${archive}" "${LIB}${archive}"
cd "${LIB}${archive}"
# This is one of those 'specific requirements': where the deb control files live
cp -a "packages/deb" "debian"
# Now, we can call Debian's standard build tool
debuild -uc -us
cd ../.. # get back to the original top-level dir
# We'll put the result in a subdirectory that's named after the OS version
# we've made this .deb file for.
destdir="debian-$(cat /etc/debian_version 2>/dev/null || echo UNKNOWN)"
rm -rf "$destdir"
mkdir -p "$destdir"
mv $(find tmp -mindepth 1 -maxdepth 1 -type f) "$destdir"
echo
echo "The Debian package files are located in $PWD/$destdir"

View File

@ -1,7 +0,0 @@
The list of files here isn't complete. For a step-by-step guide on
how to set this package up correctly, check out
http://www.debian.org/doc/maint-guide/
Most of the files that are in this directory are boilerplate.
However, you may need to change the list of binary-arch dependencies
in 'rules'.

View File

@ -1,113 +0,0 @@
sparsehash (1.6-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Fri, 08 Jan 2010 14:47:55 -0800
sparsehash (1.5.2-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Tue, 12 May 2009 14:16:38 -0700
sparsehash (1.5.1-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Fri, 08 May 2009 15:23:44 -0700
sparsehash (1.5-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Wed, 06 May 2009 11:28:49 -0700
sparsehash (1.4-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Wed, 28 Jan 2009 17:11:31 -0800
sparsehash (1.3-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Thu, 06 Nov 2008 15:06:09 -0800
sparsehash (1.2-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Thu, 18 Sep 2008 13:53:20 -0700
sparsehash (1.1-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Mon, 11 Feb 2008 16:30:11 -0800
sparsehash (1.0-1) unstable; urgency=low
* New upstream release. We are now out of beta.
-- Google Inc. <opensource@google.com> Tue, 13 Nov 2007 15:15:46 -0800
sparsehash (0.9.1-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Fri, 12 Oct 2007 12:35:24 -0700
sparsehash (0.9-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Tue, 09 Oct 2007 14:15:21 -0700
sparsehash (0.8-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Tue, 03 Jul 2007 12:55:04 -0700
sparsehash (0.7-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Mon, 11 Jun 2007 11:33:41 -0700
sparsehash (0.6-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Tue, 20 Mar 2007 17:29:34 -0700
sparsehash (0.5-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Sat, 21 Oct 2006 13:47:47 -0700
sparsehash (0.4-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Sun, 23 Apr 2006 22:42:35 -0700
sparsehash (0.3-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Thu, 03 Nov 2005 20:12:31 -0800
sparsehash (0.2-1) unstable; urgency=low
* New upstream release.
-- Google Inc. <opensource@google.com> Mon, 02 May 2005 07:04:46 -0700
sparsehash (0.1-1) unstable; urgency=low
* Initial release.
-- Google Inc. <opensource@google.com> Tue, 15 Feb 2005 07:17:02 -0800

View File

@ -1 +0,0 @@
4

View File

@ -1,17 +0,0 @@
Source: sparsehash
Section: libdevel
Priority: optional
Maintainer: Google Inc. <opensource@google.com>
Build-Depends: debhelper (>= 4.0.0)
Standards-Version: 3.6.1
Package: sparsehash
Section: libs
Architecture: any
Description: hash_map and hash_set classes with minimal space overhead
This package contains several hash-map implementations, similar
in API to SGI's hash_map class, but with different performance
characteristics. sparse_hash_map uses very little space overhead: 1-2
bits per entry. dense_hash_map is typically faster than the default
SGI STL implementation. This package also includes hash-set analogues
of these classes.

View File

@ -1,35 +0,0 @@
This package was debianized by Google Inc. <opensource@google.com> on
15 February 2005.
It was downloaded from http://code.google.com/
Upstream Author: opensource@google.com
Copyright (c) 2005, Google Inc.
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 Google Inc. nor the names of its
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.

View File

@ -1,16 +0,0 @@
AUTHORS
COPYING
ChangeLog
INSTALL
NEWS
README
TODO
doc/dense_hash_map.html
doc/dense_hash_set.html
doc/sparse_hash_map.html
doc/sparse_hash_set.html
doc/sparsetable.html
doc/implementation.html
doc/performance.html
doc/index.html
doc/designstyle.css

View File

@ -1,117 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
CFLAGS = -Wall -g
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
# shared library versions, option 1
#version=2.0.5
#major=2
# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
version=`ls src/.libs/lib*.so.* | \
awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
major=`ls src/.libs/lib*.so.* | \
awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
config.status: configure
dh_testdir
# Add here commands to configure the package.
CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
build: build-stamp
build-stamp: config.status
dh_testdir
# Add here commands to compile the package.
$(MAKE)
touch build-stamp
clean:
dh_testdir
dh_testroot
rm -f build-stamp
# Add here commands to clean up after the build process.
-$(MAKE) distclean
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
cp -f /usr/share/misc/config.sub config.sub
endif
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
cp -f /usr/share/misc/config.guess config.guess
endif
dh_clean
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/tmp
$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installchangelogs ChangeLog
dh_installdocs
dh_installexamples
dh_install --sourcedir=debian/tmp
# dh_installmenu
# dh_installdebconf
# dh_installlogrotate
# dh_installemacsen
# dh_installpam
# dh_installmime
# dh_installinit
# dh_installcron
# dh_installinfo
dh_installman
dh_link
dh_strip
dh_compress
dh_fixperms
# dh_perl
# dh_python
dh_makeshlibs
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

View File

@ -1,2 +0,0 @@
usr/include
usr/include/google

View File

@ -1,2 +0,0 @@
usr/include/google/*
debian/tmp/usr/include/google/*

View File

@ -1,86 +0,0 @@
#!/bin/sh -e
# Run this from the 'packages' directory, just under rootdir
# We can only build rpm packages, if the rpm build tools are installed
if [ \! -x /usr/bin/rpmbuild ]
then
echo "Cannot find /usr/bin/rpmbuild. Not building an rpm." 1>&2
exit 0
fi
# Check the commandline flags
PACKAGE="$1"
VERSION="$2"
fullname="${PACKAGE}-${VERSION}"
archive=../$fullname.tar.gz
if [ -z "$1" -o -z "$2" ]
then
echo "Usage: $0 <package name> <package version>" 1>&2
exit 0
fi
# Double-check we're in the packages directory, just under rootdir
if [ \! -r ../Makefile -a \! -r ../INSTALL ]
then
echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2
echo "Also, you must run \"make dist\" before running this script." 1>&2
exit 0
fi
if [ \! -r "$archive" ]
then
echo "Cannot find $archive. Run \"make dist\" first." 1>&2
exit 0
fi
# Create the directory where the input lives, and where the output should live
RPM_SOURCE_DIR="/tmp/rpmsource-$fullname"
RPM_BUILD_DIR="/tmp/rpmbuild-$fullname"
trap 'rm -rf $RPM_SOURCE_DIR $RPM_BUILD_DIR; exit $?' EXIT SIGHUP SIGINT SIGTERM
rm -rf "$RPM_SOURCE_DIR" "$RPM_BUILD_DIR"
mkdir "$RPM_SOURCE_DIR"
mkdir "$RPM_BUILD_DIR"
cp "$archive" "$RPM_SOURCE_DIR"
# rpmbuild -- as far as I can tell -- asks the OS what CPU it has.
# This may differ from what kind of binaries gcc produces. dpkg
# does a better job of this, so if we can run 'dpkg --print-architecture'
# to get the build CPU, we use that in preference of the rpmbuild
# default.
target=`dpkg --print-architecture 2>/dev/null` # "" if dpkg isn't found
if [ -n "$target" ]
then
target=" --target $target"
fi
rpmbuild -bb rpm/rpm.spec $target \
--define "NAME $PACKAGE" \
--define "VERSION $VERSION" \
--define "_sourcedir $RPM_SOURCE_DIR" \
--define "_builddir $RPM_BUILD_DIR" \
--define "_rpmdir $RPM_SOURCE_DIR"
# We put the output in a directory based on what system we've built for
destdir=rpm-unknown
if [ -r /etc/issue ]
then
grep "Red Hat.*release 7" /etc/issue >/dev/null 2>&1 && destdir=rh7
grep "Red Hat.*release 8" /etc/issue >/dev/null 2>&1 && destdir=rh8
grep "Red Hat.*release 9" /etc/issue >/dev/null 2>&1 && destdir=rh9
grep "Fedora Core.*release 1" /etc/issue >/dev/null 2>&1 && destdir=fc1
grep "Fedora Core.*release 2" /etc/issue >/dev/null 2>&1 && destdir=fc2
grep "Fedora Core.*release 3" /etc/issue >/dev/null 2>&1 && destdir=fc3
fi
rm -rf "$destdir"
mkdir -p "$destdir"
# We want to get not only the main package but devel etc, hence the middle *
mv "$RPM_SOURCE_DIR"/*/"${PACKAGE}"-*"${VERSION}"*.rpm "$destdir"
echo
echo "The rpm package file(s) are located in $PWD/$destdir"

View File

@ -1,61 +0,0 @@
%define RELEASE 1
%define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE}
%define prefix /usr
Name: %NAME
Summary: hash_map and hash_set classes with minimal space overhead
Version: %VERSION
Release: %rel
Group: Development/Libraries
URL: http://code.google.com/p/google-sparsehash
License: BSD
Vendor: Google
Packager: Google <opensource@google.com>
Source: http://%{NAME}.googlecode.com/files/%{NAME}-%{VERSION}.tar.gz
Distribution: Redhat 7 and above.
Buildroot: %{_tmppath}/%{name}-root
Prefix: %prefix
Buildarch: noarch
%description
The %name package contains several hash-map implementations, similar
in API to the SGI hash_map class, but with different performance
characteristics. sparse_hash_map uses very little space overhead: 1-2
bits per entry. dense_hash_map is typically faster than the default
SGI STL implementation. This package also includes hash-set analogues
of these classes.
%changelog
* Wed Apr 22 2009 <opensource@google.com>
- Change build rule to use %configure instead of ./configure
- Change install to use DESTDIR instead of prefix for make install
- Use wildcards for doc/ and lib/ directories
- Use {_includedir} instead of {prefix}/include
* Fri Jan 14 2005 <opensource@google.com>
- First draft
%prep
%setup
%build
# I can't use '% configure', because it defines -m32 which breaks on
# my development environment for some reason. But I do take
# as much from % configure (in /usr/lib/rpm/macros) as I can.
./configure --prefix=%{_prefix} --exec-prefix=%{_exec_prefix} --bindir=%{_bindir} --sbindir=%{_sbindir} --sysconfdir=%{_sysconfdir} --datadir=%{_datadir} --includedir=%{_includedir} --libdir=%{_libdir} --libexecdir=%{_libexecdir} --localstatedir=%{_localstatedir} --sharedstatedir=%{_sharedstatedir} --mandir=%{_mandir} --infodir=%{_infodir}
make
%install
rm -rf $RPM_BUILD_ROOT
make DESTDIR=$RPM_BUILD_ROOT install
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%docdir %{prefix}/share/doc/%{NAME}-%{VERSION}
%{prefix}/share/doc/%{NAME}-%{VERSION}/*
%{_includedir}/google

Binary file not shown.

View File

@ -1,132 +0,0 @@
/* src/config.h. Generated from config.h.in by configure. */
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Namespace for Google classes */
#define GOOGLE_NAMESPACE ::google
/* the location of the header defining hash functions */
#define HASH_FUN_H <tr1/functional>
/* the location of <unordered_map> or <hash_map> */
#define HASH_MAP_H <tr1/unordered_map>
/* the namespace of the hash<> function */
#define HASH_NAMESPACE std::tr1
/* the location of <unordered_set> or <hash_set> */
#define HASH_SET_H <tr1/unordered_set>
/* Define to 1 if you have the <google/malloc_extension.h> header file. */
/* #undef HAVE_GOOGLE_MALLOC_EXTENSION_H */
/* define if the compiler has hash_map */
#define HAVE_HASH_MAP 1
/* define if the compiler has hash_set */
#define HAVE_HASH_SET 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if the system has the type `long long'. */
#define HAVE_LONG_LONG 1
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES 1
/* Define if you have POSIX threads libraries and header files. */
/* #undef HAVE_PTHREAD */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/utsname.h> header file. */
#define HAVE_SYS_UTSNAME_H 1
/* Define to 1 if the system has the type `uint16_t'. */
#define HAVE_UINT16_T 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* define if the compiler supports unordered_{map,set} */
#define HAVE_UNORDERED_MAP 1
/* Define to 1 if the system has the type `u_int16_t'. */
#define HAVE_U_INT16_T 1
/* Define to 1 if the system has the type `__uint16'. */
/* #undef HAVE___UINT16 */
/* Name of package */
#define PACKAGE "sparsehash"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "opensource@google.com"
/* Define to the full name of this package. */
#define PACKAGE_NAME "sparsehash"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "sparsehash 1.6"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "sparsehash"
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.6"
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
/* #undef PTHREAD_CREATE_JOINABLE */
/* The system-provided hash function including the namespace. */
#define SPARSEHASH_HASH HASH_NAMESPACE::hash
/* The system-provided hash function, in namespace HASH_NAMESPACE. */
#define SPARSEHASH_HASH_NO_NAMESPACE hash
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* the namespace where STL code like vector<> is defined */
#define STL_NAMESPACE std
/* Version number of package */
#define VERSION "1.6"
/* Stops putting the code inside the Google namespace */
#define _END_GOOGLE_NAMESPACE_ }
/* Puts following code inside the Google namespace */
#define _START_GOOGLE_NAMESPACE_ namespace google {

View File

@ -1,131 +0,0 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Namespace for Google classes */
#undef GOOGLE_NAMESPACE
/* the location of the header defining hash functions */
#undef HASH_FUN_H
/* the location of <unordered_map> or <hash_map> */
#undef HASH_MAP_H
/* the namespace of the hash<> function */
#undef HASH_NAMESPACE
/* the location of <unordered_set> or <hash_set> */
#undef HASH_SET_H
/* Define to 1 if you have the <google/malloc_extension.h> header file. */
#undef HAVE_GOOGLE_MALLOC_EXTENSION_H
/* define if the compiler has hash_map */
#undef HAVE_HASH_MAP
/* define if the compiler has hash_set */
#undef HAVE_HASH_SET
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if the system has the type `long long'. */
#undef HAVE_LONG_LONG
/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* define if the compiler implements namespaces */
#undef HAVE_NAMESPACES
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/utsname.h> header file. */
#undef HAVE_SYS_UTSNAME_H
/* Define to 1 if the system has the type `uint16_t'. */
#undef HAVE_UINT16_T
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* define if the compiler supports unordered_{map,set} */
#undef HAVE_UNORDERED_MAP
/* Define to 1 if the system has the type `u_int16_t'. */
#undef HAVE_U_INT16_T
/* Define to 1 if the system has the type `__uint16'. */
#undef HAVE___UINT16
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* The system-provided hash function including the namespace. */
#undef SPARSEHASH_HASH
/* The system-provided hash function, in namespace HASH_NAMESPACE. */
#undef SPARSEHASH_HASH_NO_NAMESPACE
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* the namespace where STL code like vector<> is defined */
#undef STL_NAMESPACE
/* Version number of package */
#undef VERSION
/* Stops putting the code inside the Google namespace */
#undef _END_GOOGLE_NAMESPACE_
/* Puts following code inside the Google namespace */
#undef _START_GOOGLE_NAMESPACE_

View File

@ -1,23 +0,0 @@
/***
*** These are #defines that autoheader puts in config.h.in that we
*** want to show up in sparseconfig.h, the minimal config.h file
*** #included by all our .h files. The reason we don't take
*** everything that autoheader emits is that we have to include a
*** config.h in installed header files, and we want to minimize the
*** number of #defines we make so as to not pollute the namespace.
***/
GOOGLE_NAMESPACE
HASH_NAMESPACE
HASH_FUN_H
SPARSEHASH_HASH
HAVE_UINT16_T
HAVE_U_INT16_T
HAVE___UINT16
HAVE_LONG_LONG
HAVE_SYS_TYPES_H
HAVE_STDINT_H
HAVE_INTTYPES_H
HAVE_MEMCPY
STL_NAMESPACE
_END_GOOGLE_NAMESPACE_
_START_GOOGLE_NAMESPACE_

View File

@ -1,319 +0,0 @@
// Copyright (c) 2005, Google Inc.
// 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 Google Inc. nor the names of its
// 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.
// ----
// Author: Craig Silverstein
//
// This is just a very thin wrapper over densehashtable.h, just
// like sgi stl's stl_hash_map is a very thin wrapper over
// stl_hashtable. The major thing we define is operator[], because
// we have a concept of a data_type which stl_hashtable doesn't
// (it only has a key and a value).
//
// NOTE: this is exactly like sparse_hash_map.h, with the word
// "sparse" replaced by "dense", except for the addition of
// set_empty_key().
//
// YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION.
//
// Otherwise your program will die in mysterious ways.
//
// In other respects, we adhere mostly to the STL semantics for
// hash-map. One important exception is that insert() may invalidate
// iterators entirely -- STL semantics are that insert() may reorder
// iterators, but they all still refer to something valid in the
// hashtable. Not so for us. Likewise, insert() may invalidate
// pointers into the hashtable. (Whether insert invalidates iterators
// and pointers depends on whether it results in a hashtable resize).
// On the plus side, delete() doesn't invalidate iterators or pointers
// at all, or even change the ordering of elements.
//
// Here are a few "power user" tips:
//
// 1) set_deleted_key():
// If you want to use erase() you *must* call set_deleted_key(),
// in addition to set_empty_key(), after construction.
// The deleted and empty keys must differ.
//
// 2) resize(0):
// When an item is deleted, its memory isn't freed right
// away. This allows you to iterate over a hashtable,
// and call erase(), without invalidating the iterator.
// To force the memory to be freed, call resize(0).
// For tr1 compatibility, this can also be called as rehash(0).
//
// 3) min_load_factor(0.0)
// Setting the minimum load factor to 0.0 guarantees that
// the hash table will never shrink.
//
// Roughly speaking:
// (1) dense_hash_map: fastest, uses the most memory unless entries are small
// (2) sparse_hash_map: slowest, uses the least memory
// (3) hash_map / unordered_map (STL): in the middle
//
// Typically I use sparse_hash_map when I care about space and/or when
// I need to save the hashtable on disk. I use hash_map otherwise. I
// don't personally use dense_hash_set ever; some people use it for
// small sets with lots of lookups.
//
// - dense_hash_map has, typically, about 78% memory overhead (if your
// data takes up X bytes, the hash_map uses .78X more bytes in overhead).
// - sparse_hash_map has about 4 bits overhead per entry.
// - sparse_hash_map can be 3-7 times slower than the others for lookup and,
// especially, inserts. See time_hash_map.cc for details.
//
// See /usr/(local/)?doc/sparsehash-*/dense_hash_map.html
// for information about how to use this class.
#ifndef _DENSE_HASH_MAP_H_
#define _DENSE_HASH_MAP_H_
#include <google/sparsehash/sparseconfig.h>
#include <stdio.h> // for FILE * in read()/write()
#include <algorithm> // for the default template args
#include <functional> // for equal_to
#include <memory> // for alloc<>
#include <utility> // for pair<>
#include HASH_FUN_H // defined in config.h
#include <google/sparsehash/densehashtable.h>
_START_GOOGLE_NAMESPACE_
using STL_NAMESPACE::pair;
template <class Key, class T,
class HashFcn = SPARSEHASH_HASH<Key>, // defined in sparseconfig.h
class EqualKey = STL_NAMESPACE::equal_to<Key>,
class Alloc = STL_NAMESPACE::allocator<T> >
class dense_hash_map {
private:
// Apparently select1st is not stl-standard, so we define our own
struct SelectKey {
const Key& operator()(const pair<const Key, T>& p) const {
return p.first;
}
};
struct SetKey {
void operator()(pair<const Key, T>* value, const Key& new_key) const {
*const_cast<Key*>(&value->first) = new_key;
// It would be nice to clear the rest of value here as well, in
// case it's taking up a lot of memory. We do this by clearing
// the value. This assumes T has a zero-arg constructor!
value->second = T();
}
};
// The actual data
typedef dense_hashtable<pair<const Key, T>, Key, HashFcn,
SelectKey, SetKey, EqualKey, Alloc> ht;
ht rep;
public:
typedef typename ht::key_type key_type;
typedef T data_type;
typedef T mapped_type;
typedef typename ht::value_type value_type;
typedef typename ht::hasher hasher;
typedef typename ht::key_equal key_equal;
typedef Alloc allocator_type;
typedef typename ht::size_type size_type;
typedef typename ht::difference_type difference_type;
typedef typename ht::pointer pointer;
typedef typename ht::const_pointer const_pointer;
typedef typename ht::reference reference;
typedef typename ht::const_reference const_reference;
typedef typename ht::iterator iterator;
typedef typename ht::const_iterator const_iterator;
typedef typename ht::local_iterator local_iterator;
typedef typename ht::const_local_iterator const_local_iterator;
// Iterator functions
iterator begin() { return rep.begin(); }
iterator end() { return rep.end(); }
const_iterator begin() const { return rep.begin(); }
const_iterator end() const { return rep.end(); }
// These come from tr1's unordered_map. For us, a bucket has 0 or 1 elements.
local_iterator begin(size_type i) { return rep.begin(i); }
local_iterator end(size_type i) { return rep.end(i); }
const_local_iterator begin(size_type i) const { return rep.begin(i); }
const_local_iterator end(size_type i) const { return rep.end(i); }
// Accessor functions
// TODO(csilvers): implement Alloc get_allocator() const;
hasher hash_funct() const { return rep.hash_funct(); }
hasher hash_function() const { return hash_funct(); }
key_equal key_eq() const { return rep.key_eq(); }
// Constructors
explicit dense_hash_map(size_type expected_max_items_in_table = 0,
const hasher& hf = hasher(),
const key_equal& eql = key_equal())
: rep(expected_max_items_in_table, hf, eql) { }
template <class InputIterator>
dense_hash_map(InputIterator f, InputIterator l,
size_type expected_max_items_in_table = 0,
const hasher& hf = hasher(),
const key_equal& eql = key_equal())
: rep(expected_max_items_in_table, hf, eql) {
rep.insert(f, l);
}
// We use the default copy constructor
// We use the default operator=()
// We use the default destructor
void clear() { rep.clear(); }
// This clears the hash map without resizing it down to the minimum
// bucket count, but rather keeps the number of buckets constant
void clear_no_resize() { rep.clear_no_resize(); }
void swap(dense_hash_map& hs) { rep.swap(hs.rep); }
// Functions concerning size
size_type size() const { return rep.size(); }
size_type max_size() const { return rep.max_size(); }
bool empty() const { return rep.empty(); }
size_type bucket_count() const { return rep.bucket_count(); }
size_type max_bucket_count() const { return rep.max_bucket_count(); }
// These are tr1 methods. bucket() is the bucket the key is or would be in.
size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
size_type bucket(const key_type& key) const { return rep.bucket(key); }
float load_factor() const {
return size() * 1.0f / bucket_count();
}
float max_load_factor() const {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
return grow;
}
void max_load_factor(float new_grow) {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
rep.set_resizing_parameters(shrink, new_grow);
}
// These aren't tr1 methods but perhaps ought to be.
float min_load_factor() const {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
return shrink;
}
void min_load_factor(float new_shrink) {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
rep.set_resizing_parameters(new_shrink, grow);
}
// Deprecated; use min_load_factor() or max_load_factor() instead.
void set_resizing_parameters(float shrink, float grow) {
return rep.set_resizing_parameters(shrink, grow);
}
void resize(size_type hint) { rep.resize(hint); }
void rehash(size_type hint) { resize(hint); } // the tr1 name
// Lookup routines
iterator find(const key_type& key) { return rep.find(key); }
const_iterator find(const key_type& key) const { return rep.find(key); }
data_type& operator[](const key_type& key) { // This is our value-add!
iterator it = find(key);
if (it != end()) {
return it->second;
} else {
return insert(value_type(key, data_type())).first->second;
}
}
size_type count(const key_type& key) const { return rep.count(key); }
pair<iterator, iterator> equal_range(const key_type& key) {
return rep.equal_range(key);
}
pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
return rep.equal_range(key);
}
// Insertion routines
pair<iterator, bool> insert(const value_type& obj) { return rep.insert(obj); }
template <class InputIterator>
void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
// required for std::insert_iterator; the passed-in iterator is ignored
iterator insert(iterator, const value_type& obj) { return insert(obj).first; }
// Deletion and empty routines
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
// value to identify deleted and empty buckets. You can change the
// deleted key as time goes on, or get rid of it entirely to be insert-only.
void set_empty_key(const key_type& key) { // YOU MUST CALL THIS!
rep.set_empty_key(value_type(key, data_type())); // rep wants a value
}
key_type empty_key() const {
return rep.empty_key().first; // rep returns a value
}
void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
void clear_deleted_key() { rep.clear_deleted_key(); }
key_type deleted_key() const { return rep.deleted_key(); }
// These are standard
size_type erase(const key_type& key) { return rep.erase(key); }
void erase(iterator it) { rep.erase(it); }
void erase(iterator f, iterator l) { rep.erase(f, l); }
// Comparison
bool operator==(const dense_hash_map& hs) const { return rep == hs.rep; }
bool operator!=(const dense_hash_map& hs) const { return rep != hs.rep; }
// I/O -- this is an add-on for writing metainformation to disk
bool write_metadata(FILE *fp) { return rep.write_metadata(fp); }
bool read_metadata(FILE *fp) { return rep.read_metadata(fp); }
bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); }
bool read_nopointer_data(FILE *fp) { return rep.read_nopointer_data(fp); }
};
// We need a global swap as well
template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
inline void swap(dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) {
hm1.swap(hm2);
}
_END_GOOGLE_NAMESPACE_
#endif /* _DENSE_HASH_MAP_H_ */

View File

@ -1,296 +0,0 @@
// Copyright (c) 2005, Google Inc.
// 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 Google Inc. nor the names of its
// 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.
// ---
// Author: Craig Silverstein
//
// This is just a very thin wrapper over densehashtable.h, just
// like sgi stl's stl_hash_set is a very thin wrapper over
// stl_hashtable. The major thing we define is operator[], because
// we have a concept of a data_type which stl_hashtable doesn't
// (it only has a key and a value).
//
// This is more different from dense_hash_map than you might think,
// because all iterators for sets are const (you obviously can't
// change the key, and for sets there is no value).
//
// NOTE: this is exactly like sparse_hash_set.h, with the word
// "sparse" replaced by "dense", except for the addition of
// set_empty_key().
//
// YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION.
//
// Otherwise your program will die in mysterious ways.
//
// In other respects, we adhere mostly to the STL semantics for
// hash-map. One important exception is that insert() may invalidate
// iterators entirely -- STL semantics are that insert() may reorder
// iterators, but they all still refer to something valid in the
// hashtable. Not so for us. Likewise, insert() may invalidate
// pointers into the hashtable. (Whether insert invalidates iterators
// and pointers depends on whether it results in a hashtable resize).
// On the plus side, delete() doesn't invalidate iterators or pointers
// at all, or even change the ordering of elements.
//
// Here are a few "power user" tips:
//
// 1) set_deleted_key():
// If you want to use erase() you must call set_deleted_key(),
// in addition to set_empty_key(), after construction.
// The deleted and empty keys must differ.
//
// 2) resize(0):
// When an item is deleted, its memory isn't freed right
// away. This allows you to iterate over a hashtable,
// and call erase(), without invalidating the iterator.
// To force the memory to be freed, call resize(0).
// For tr1 compatibility, this can also be called as rehash(0).
//
// 3) min_load_factor(0.0)
// Setting the minimum load factor to 0.0 guarantees that
// the hash table will never shrink.
//
// Roughly speaking:
// (1) dense_hash_set: fastest, uses the most memory unless entries are small
// (2) sparse_hash_set: slowest, uses the least memory
// (3) hash_set / unordered_set (STL): in the middle
//
// Typically I use sparse_hash_set when I care about space and/or when
// I need to save the hashtable on disk. I use hash_set otherwise. I
// don't personally use dense_hash_set ever; some people use it for
// small sets with lots of lookups.
//
// - dense_hash_set has, typically, about 78% memory overhead (if your
// data takes up X bytes, the hash_set uses .78X more bytes in overhead).
// - sparse_hash_set has about 4 bits overhead per entry.
// - sparse_hash_set can be 3-7 times slower than the others for lookup and,
// especially, inserts. See time_hash_map.cc for details.
//
// See /usr/(local/)?doc/sparsehash-*/dense_hash_set.html
// for information about how to use this class.
#ifndef _DENSE_HASH_SET_H_
#define _DENSE_HASH_SET_H_
#include <google/sparsehash/sparseconfig.h>
#include <stdio.h> // for FILE * in read()/write()
#include <algorithm> // for the default template args
#include <functional> // for equal_to
#include <memory> // for alloc<>
#include <utility> // for pair<>
#include HASH_FUN_H // defined in config.h
#include <google/sparsehash/densehashtable.h>
_START_GOOGLE_NAMESPACE_
using STL_NAMESPACE::pair;
template <class Value,
class HashFcn = SPARSEHASH_HASH<Value>, // defined in sparseconfig.h
class EqualKey = STL_NAMESPACE::equal_to<Value>,
class Alloc = STL_NAMESPACE::allocator<Value> >
class dense_hash_set {
private:
// Apparently identity is not stl-standard, so we define our own
struct Identity {
Value& operator()(Value& v) const { return v; }
const Value& operator()(const Value& v) const { return v; }
};
struct SetKey {
void operator()(Value* value, const Value& new_key) const {
*value = new_key;
}
};
// The actual data
typedef dense_hashtable<Value, Value, HashFcn,
Identity, SetKey, EqualKey, Alloc> ht;
ht rep;
public:
typedef typename ht::key_type key_type;
typedef typename ht::value_type value_type;
typedef typename ht::hasher hasher;
typedef typename ht::key_equal key_equal;
typedef Alloc allocator_type;
typedef typename ht::size_type size_type;
typedef typename ht::difference_type difference_type;
typedef typename ht::const_pointer pointer;
typedef typename ht::const_pointer const_pointer;
typedef typename ht::const_reference reference;
typedef typename ht::const_reference const_reference;
typedef typename ht::const_iterator iterator;
typedef typename ht::const_iterator const_iterator;
typedef typename ht::const_local_iterator local_iterator;
typedef typename ht::const_local_iterator const_local_iterator;
// Iterator functions -- recall all iterators are const
iterator begin() const { return rep.begin(); }
iterator end() const { return rep.end(); }
// These come from tr1's unordered_set. For us, a bucket has 0 or 1 elements.
local_iterator begin(size_type i) const { return rep.begin(i); }
local_iterator end(size_type i) const { return rep.end(i); }
// Accessor functions
hasher hash_funct() const { return rep.hash_funct(); }
key_equal key_eq() const { return rep.key_eq(); }
// Constructors
explicit dense_hash_set(size_type expected_max_items_in_table = 0,
const hasher& hf = hasher(),
const key_equal& eql = key_equal())
: rep(expected_max_items_in_table, hf, eql) { }
template <class InputIterator>
dense_hash_set(InputIterator f, InputIterator l,
size_type expected_max_items_in_table = 0,
const hasher& hf = hasher(),
const key_equal& eql = key_equal())
: rep(expected_max_items_in_table, hf, eql) {
rep.insert(f, l);
}
// We use the default copy constructor
// We use the default operator=()
// We use the default destructor
void clear() { rep.clear(); }
// This clears the hash set without resizing it down to the minimum
// bucket count, but rather keeps the number of buckets constant
void clear_no_resize() { rep.clear_no_resize(); }
void swap(dense_hash_set& hs) { rep.swap(hs.rep); }
// Functions concerning size
size_type size() const { return rep.size(); }
size_type max_size() const { return rep.max_size(); }
bool empty() const { return rep.empty(); }
size_type bucket_count() const { return rep.bucket_count(); }
size_type max_bucket_count() const { return rep.max_bucket_count(); }
// These are tr1 methods. bucket() is the bucket the key is or would be in.
size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
size_type bucket(const key_type& key) const { return rep.bucket(key); }
float load_factor() const {
return size() * 1.0f / bucket_count();
}
float max_load_factor() const {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
return grow;
}
void max_load_factor(float new_grow) {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
rep.set_resizing_parameters(shrink, new_grow);
}
// These aren't tr1 methods but perhaps ought to be.
float min_load_factor() const {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
return shrink;
}
void min_load_factor(float new_shrink) {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
rep.set_resizing_parameters(new_shrink, grow);
}
// Deprecated; use min_load_factor() or max_load_factor() instead.
void set_resizing_parameters(float shrink, float grow) {
return rep.set_resizing_parameters(shrink, grow);
}
void resize(size_type hint) { rep.resize(hint); }
void rehash(size_type hint) { resize(hint); } // the tr1 name
// Lookup routines
iterator find(const key_type& key) const { return rep.find(key); }
size_type count(const key_type& key) const { return rep.count(key); }
pair<iterator, iterator> equal_range(const key_type& key) const {
return rep.equal_range(key);
}
// Insertion routines
pair<iterator, bool> insert(const value_type& obj) {
pair<typename ht::iterator, bool> p = rep.insert(obj);
return pair<iterator, bool>(p.first, p.second); // const to non-const
}
template <class InputIterator>
void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
// required for std::insert_iterator; the passed-in iterator is ignored
iterator insert(iterator, const value_type& obj) { return insert(obj).first; }
// Deletion and empty routines
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
// value to identify deleted and empty buckets. You can change the
// deleted key as time goes on, or get rid of it entirely to be insert-only.
void set_empty_key(const key_type& key) { rep.set_empty_key(key); }
key_type empty_key() const { return rep.empty_key(); }
void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
void clear_deleted_key() { rep.clear_deleted_key(); }
key_type deleted_key() const { return rep.deleted_key(); }
// These are standard
size_type erase(const key_type& key) { return rep.erase(key); }
void erase(iterator it) { rep.erase(it); }
void erase(iterator f, iterator l) { rep.erase(f, l); }
// Comparison
bool operator==(const dense_hash_set& hs) const { return rep == hs.rep; }
bool operator!=(const dense_hash_set& hs) const { return rep != hs.rep; }
// I/O -- this is an add-on for writing metainformation to disk
bool write_metadata(FILE *fp) { return rep.write_metadata(fp); }
bool read_metadata(FILE *fp) { return rep.read_metadata(fp); }
bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); }
bool read_nopointer_data(FILE *fp) { return rep.read_nopointer_data(fp); }
};
template <class Val, class HashFcn, class EqualKey, class Alloc>
inline void swap(dense_hash_set<Val, HashFcn, EqualKey, Alloc>& hs1,
dense_hash_set<Val, HashFcn, EqualKey, Alloc>& hs2) {
hs1.swap(hs2);
}
_END_GOOGLE_NAMESPACE_
#endif /* _DENSE_HASH_SET_H_ */

View File

@ -1,301 +0,0 @@
// Copyright (c) 2005, Google Inc.
// 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 Google Inc. nor the names of its
// 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.
// ---
// Author: Craig Silverstein
//
// This is just a very thin wrapper over sparsehashtable.h, just
// like sgi stl's stl_hash_map is a very thin wrapper over
// stl_hashtable. The major thing we define is operator[], because
// we have a concept of a data_type which stl_hashtable doesn't
// (it only has a key and a value).
//
// We adhere mostly to the STL semantics for hash-map. One important
// exception is that insert() may invalidate iterators entirely -- STL
// semantics are that insert() may reorder iterators, but they all
// still refer to something valid in the hashtable. Not so for us.
// Likewise, insert() may invalidate pointers into the hashtable.
// (Whether insert invalidates iterators and pointers depends on
// whether it results in a hashtable resize). On the plus side,
// delete() doesn't invalidate iterators or pointers at all, or even
// change the ordering of elements.
//
// Here are a few "power user" tips:
//
// 1) set_deleted_key():
// Unlike STL's hash_map, if you want to use erase() you
// *must* call set_deleted_key() after construction.
//
// 2) resize(0):
// When an item is deleted, its memory isn't freed right
// away. This is what allows you to iterate over a hashtable
// and call erase() without invalidating the iterator.
// To force the memory to be freed, call resize(0).
// For tr1 compatibility, this can also be called as rehash(0).
//
// 3) min_load_factor(0.0)
// Setting the minimum load factor to 0.0 guarantees that
// the hash table will never shrink.
//
// Roughly speaking:
// (1) dense_hash_map: fastest, uses the most memory unless entries are small
// (2) sparse_hash_map: slowest, uses the least memory
// (3) hash_map / unordered_map (STL): in the middle
//
// Typically I use sparse_hash_map when I care about space and/or when
// I need to save the hashtable on disk. I use hash_map otherwise. I
// don't personally use dense_hash_map ever; some people use it for
// small maps with lots of lookups.
//
// - dense_hash_map has, typically, about 78% memory overhead (if your
// data takes up X bytes, the hash_map uses .78X more bytes in overhead).
// - sparse_hash_map has about 4 bits overhead per entry.
// - sparse_hash_map can be 3-7 times slower than the others for lookup and,
// especially, inserts. See time_hash_map.cc for details.
//
// See /usr/(local/)?doc/sparsehash-*/sparse_hash_map.html
// for information about how to use this class.
#ifndef _SPARSE_HASH_MAP_H_
#define _SPARSE_HASH_MAP_H_
#include <google/sparsehash/sparseconfig.h>
#include <stdio.h> // for FILE * in read()/write()
#include <algorithm> // for the default template args
#include <functional> // for equal_to
#include <memory> // for alloc<>
#include <utility> // for pair<>
#include HASH_FUN_H // defined in config.h
#include <google/sparsehash/sparsehashtable.h>
_START_GOOGLE_NAMESPACE_
using STL_NAMESPACE::pair;
template <class Key, class T,
class HashFcn = SPARSEHASH_HASH<Key>, // defined in sparseconfig.h
class EqualKey = STL_NAMESPACE::equal_to<Key>,
class Alloc = STL_NAMESPACE::allocator<T> >
class sparse_hash_map {
private:
// Apparently select1st is not stl-standard, so we define our own
struct SelectKey {
const Key& operator()(const pair<const Key, T>& p) const {
return p.first;
}
};
struct SetKey {
void operator()(pair<const Key, T>* value, const Key& new_key) const {
*const_cast<Key*>(&value->first) = new_key;
// It would be nice to clear the rest of value here as well, in
// case it's taking up a lot of memory. We do this by clearing
// the value. This assumes T has a zero-arg constructor!
value->second = T();
}
};
// The actual data
typedef sparse_hashtable<pair<const Key, T>, Key, HashFcn,
SelectKey, SetKey, EqualKey, Alloc> ht;
ht rep;
public:
typedef typename ht::key_type key_type;
typedef T data_type;
typedef T mapped_type;
typedef typename ht::value_type value_type;
typedef typename ht::hasher hasher;
typedef typename ht::key_equal key_equal;
typedef Alloc allocator_type;
typedef typename ht::size_type size_type;
typedef typename ht::difference_type difference_type;
typedef typename ht::pointer pointer;
typedef typename ht::const_pointer const_pointer;
typedef typename ht::reference reference;
typedef typename ht::const_reference const_reference;
typedef typename ht::iterator iterator;
typedef typename ht::const_iterator const_iterator;
typedef typename ht::local_iterator local_iterator;
typedef typename ht::const_local_iterator const_local_iterator;
// Iterator functions
iterator begin() { return rep.begin(); }
iterator end() { return rep.end(); }
const_iterator begin() const { return rep.begin(); }
const_iterator end() const { return rep.end(); }
// These come from tr1's unordered_map. For us, a bucket has 0 or 1 elements.
local_iterator begin(size_type i) { return rep.begin(i); }
local_iterator end(size_type i) { return rep.end(i); }
const_local_iterator begin(size_type i) const { return rep.begin(i); }
const_local_iterator end(size_type i) const { return rep.end(i); }
// Accessor functions
// TODO(csilvers): implement Alloc get_allocator() const;
hasher hash_funct() const { return rep.hash_funct(); }
hasher hash_function() const { return hash_funct(); }
key_equal key_eq() const { return rep.key_eq(); }
// Constructors
explicit sparse_hash_map(size_type expected_max_items_in_table = 0,
const hasher& hf = hasher(),
const key_equal& eql = key_equal())
: rep(expected_max_items_in_table, hf, eql) { }
template <class InputIterator>
sparse_hash_map(InputIterator f, InputIterator l,
size_type expected_max_items_in_table = 0,
const hasher& hf = hasher(),
const key_equal& eql = key_equal())
: rep(expected_max_items_in_table, hf, eql) {
rep.insert(f, l);
}
// We use the default copy constructor
// We use the default operator=()
// We use the default destructor
void clear() { rep.clear(); }
void swap(sparse_hash_map& hs) { rep.swap(hs.rep); }
// Functions concerning size
size_type size() const { return rep.size(); }
size_type max_size() const { return rep.max_size(); }
bool empty() const { return rep.empty(); }
size_type bucket_count() const { return rep.bucket_count(); }
size_type max_bucket_count() const { return rep.max_bucket_count(); }
// These are tr1 methods. bucket() is the bucket the key is or would be in.
size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
size_type bucket(const key_type& key) const { return rep.bucket(key); }
float load_factor() const {
return size() * 1.0f / bucket_count();
}
float max_load_factor() const {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
return grow;
}
void max_load_factor(float new_grow) {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
rep.set_resizing_parameters(shrink, new_grow);
}
// These aren't tr1 methods but perhaps ought to be.
float min_load_factor() const {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
return shrink;
}
void min_load_factor(float new_shrink) {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
rep.set_resizing_parameters(new_shrink, grow);
}
// Deprecated; use min_load_factor() or max_load_factor() instead.
void set_resizing_parameters(float shrink, float grow) {
return rep.set_resizing_parameters(shrink, grow);
}
void resize(size_type hint) { rep.resize(hint); }
void rehash(size_type hint) { resize(hint); } // the tr1 name
// Lookup routines
iterator find(const key_type& key) { return rep.find(key); }
const_iterator find(const key_type& key) const { return rep.find(key); }
data_type& operator[](const key_type& key) { // This is our value-add!
iterator it = find(key);
if (it != end()) {
return it->second;
} else {
return insert(value_type(key, data_type())).first->second;
}
}
size_type count(const key_type& key) const { return rep.count(key); }
pair<iterator, iterator> equal_range(const key_type& key) {
return rep.equal_range(key);
}
pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
return rep.equal_range(key);
}
// Insertion routines
pair<iterator, bool> insert(const value_type& obj) { return rep.insert(obj); }
template <class InputIterator>
void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
// required for std::insert_iterator; the passed-in iterator is ignored
iterator insert(iterator, const value_type& obj) { return insert(obj).first; }
// Deletion routines
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
// value to identify deleted buckets. You can change the key as
// time goes on, or get rid of it entirely to be insert-only.
void set_deleted_key(const key_type& key) {
rep.set_deleted_key(key);
}
void clear_deleted_key() { rep.clear_deleted_key(); }
key_type deleted_key() const { return rep.deleted_key(); }
// These are standard
size_type erase(const key_type& key) { return rep.erase(key); }
void erase(iterator it) { rep.erase(it); }
void erase(iterator f, iterator l) { rep.erase(f, l); }
// Comparison
bool operator==(const sparse_hash_map& hs) const { return rep == hs.rep; }
bool operator!=(const sparse_hash_map& hs) const { return rep != hs.rep; }
// I/O -- this is an add-on for writing metainformation to disk
bool write_metadata(FILE *fp) { return rep.write_metadata(fp); }
bool read_metadata(FILE *fp) { return rep.read_metadata(fp); }
bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); }
bool read_nopointer_data(FILE *fp) { return rep.read_nopointer_data(fp); }
};
// We need a global swap as well
template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
inline void swap(sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) {
hm1.swap(hm2);
}
_END_GOOGLE_NAMESPACE_
#endif /* _SPARSE_HASH_MAP_H_ */

View File

@ -1,282 +0,0 @@
// Copyright (c) 2005, Google Inc.
// 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 Google Inc. nor the names of its
// 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.
// ---
// Author: Craig Silverstein
//
// This is just a very thin wrapper over sparsehashtable.h, just
// like sgi stl's stl_hash_set is a very thin wrapper over
// stl_hashtable. The major thing we define is operator[], because
// we have a concept of a data_type which stl_hashtable doesn't
// (it only has a key and a value).
//
// This is more different from sparse_hash_map than you might think,
// because all iterators for sets are const (you obviously can't
// change the key, and for sets there is no value).
//
// We adhere mostly to the STL semantics for hash-map. One important
// exception is that insert() may invalidate iterators entirely -- STL
// semantics are that insert() may reorder iterators, but they all
// still refer to something valid in the hashtable. Not so for us.
// Likewise, insert() may invalidate pointers into the hashtable.
// (Whether insert invalidates iterators and pointers depends on
// whether it results in a hashtable resize). On the plus side,
// delete() doesn't invalidate iterators or pointers at all, or even
// change the ordering of elements.
//
// Here are a few "power user" tips:
//
// 1) set_deleted_key():
// Unlike STL's hash_map, if you want to use erase() you
// *must* call set_deleted_key() after construction.
//
// 2) resize(0):
// When an item is deleted, its memory isn't freed right
// away. This allows you to iterate over a hashtable,
// and call erase(), without invalidating the iterator.
// To force the memory to be freed, call resize(0).
// For tr1 compatibility, this can also be called as rehash(0).
//
// 3) min_load_factor(0.0)
// Setting the minimum load factor to 0.0 guarantees that
// the hash table will never shrink.
//
// Roughly speaking:
// (1) dense_hash_set: fastest, uses the most memory unless entries are small
// (2) sparse_hash_set: slowest, uses the least memory
// (3) hash_set / unordered_set (STL): in the middle
//
// Typically I use sparse_hash_set when I care about space and/or when
// I need to save the hashtable on disk. I use hash_set otherwise. I
// don't personally use dense_hash_set ever; some people use it for
// small sets with lots of lookups.
//
// - dense_hash_set has, typically, about 78% memory overhead (if your
// data takes up X bytes, the hash_set uses .78X more bytes in overhead).
// - sparse_hash_set has about 4 bits overhead per entry.
// - sparse_hash_set can be 3-7 times slower than the others for lookup and,
// especially, inserts. See time_hash_map.cc for details.
//
// See /usr/(local/)?doc/sparsehash-*/sparse_hash_set.html
// for information about how to use this class.
#ifndef _SPARSE_HASH_SET_H_
#define _SPARSE_HASH_SET_H_
#include <google/sparsehash/sparseconfig.h>
#include <stdio.h> // for FILE * in read()/write()
#include <algorithm> // for the default template args
#include <functional> // for equal_to
#include <memory> // for alloc<>
#include <utility> // for pair<>
#include HASH_FUN_H // defined in config.h
#include <google/sparsehash/sparsehashtable.h>
_START_GOOGLE_NAMESPACE_
using STL_NAMESPACE::pair;
template <class Value,
class HashFcn = SPARSEHASH_HASH<Value>, // defined in sparseconfig.h
class EqualKey = STL_NAMESPACE::equal_to<Value>,
class Alloc = STL_NAMESPACE::allocator<Value> >
class sparse_hash_set {
private:
// Apparently identity is not stl-standard, so we define our own
struct Identity {
Value& operator()(Value& v) const { return v; }
const Value& operator()(const Value& v) const { return v; }
};
struct SetKey {
void operator()(Value* value, const Value& new_key) const {
*value = new_key;
}
};
// The actual data
typedef sparse_hashtable<Value, Value, HashFcn,
Identity, SetKey, EqualKey, Alloc> ht;
ht rep;
public:
typedef typename ht::key_type key_type;
typedef typename ht::value_type value_type;
typedef typename ht::hasher hasher;
typedef typename ht::key_equal key_equal;
typedef Alloc allocator_type;
typedef typename ht::size_type size_type;
typedef typename ht::difference_type difference_type;
typedef typename ht::const_pointer pointer;
typedef typename ht::const_pointer const_pointer;
typedef typename ht::const_reference reference;
typedef typename ht::const_reference const_reference;
typedef typename ht::const_iterator iterator;
typedef typename ht::const_iterator const_iterator;
typedef typename ht::const_local_iterator local_iterator;
typedef typename ht::const_local_iterator const_local_iterator;
// Iterator functions -- recall all iterators are const
iterator begin() const { return rep.begin(); }
iterator end() const { return rep.end(); }
// These come from tr1's unordered_set. For us, a bucket has 0 or 1 elements.
local_iterator begin(size_type i) const { return rep.begin(i); }
local_iterator end(size_type i) const { return rep.end(i); }
// Accessor functions
// TODO(csilvers): implement Alloc get_allocator() const;
hasher hash_funct() const { return rep.hash_funct(); }
hasher hash_function() const { return hash_funct(); } // tr1 name
key_equal key_eq() const { return rep.key_eq(); }
// Constructors
explicit sparse_hash_set(size_type expected_max_items_in_table = 0,
const hasher& hf = hasher(),
const key_equal& eql = key_equal())
: rep(expected_max_items_in_table, hf, eql) { }
template <class InputIterator>
sparse_hash_set(InputIterator f, InputIterator l,
size_type expected_max_items_in_table = 0,
const hasher& hf = hasher(),
const key_equal& eql = key_equal())
: rep(expected_max_items_in_table, hf, eql) {
rep.insert(f, l);
}
// We use the default copy constructor
// We use the default operator=()
// We use the default destructor
void clear() { rep.clear(); }
void swap(sparse_hash_set& hs) { rep.swap(hs.rep); }
// Functions concerning size
size_type size() const { return rep.size(); }
size_type max_size() const { return rep.max_size(); }
bool empty() const { return rep.empty(); }
size_type bucket_count() const { return rep.bucket_count(); }
size_type max_bucket_count() const { return rep.max_bucket_count(); }
// These are tr1 methods. bucket() is the bucket the key is or would be in.
size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
size_type bucket(const key_type& key) const { return rep.bucket(key); }
float load_factor() const {
return size() * 1.0f / bucket_count();
}
float max_load_factor() const {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
return grow;
}
void max_load_factor(float new_grow) {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
rep.set_resizing_parameters(shrink, new_grow);
}
// These aren't tr1 methods but perhaps ought to be.
float min_load_factor() const {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
return shrink;
}
void min_load_factor(float new_shrink) {
float shrink, grow;
rep.get_resizing_parameters(&shrink, &grow);
rep.set_resizing_parameters(new_shrink, grow);
}
// Deprecated; use min_load_factor() or max_load_factor() instead.
void set_resizing_parameters(float shrink, float grow) {
return rep.set_resizing_parameters(shrink, grow);
}
void resize(size_type hint) { rep.resize(hint); }
void rehash(size_type hint) { resize(hint); } // the tr1 name
// Lookup routines
iterator find(const key_type& key) const { return rep.find(key); }
size_type count(const key_type& key) const { return rep.count(key); }
pair<iterator, iterator> equal_range(const key_type& key) const {
return rep.equal_range(key);
}
// Insertion routines
pair<iterator, bool> insert(const value_type& obj) {
pair<typename ht::iterator, bool> p = rep.insert(obj);
return pair<iterator, bool>(p.first, p.second); // const to non-const
}
template <class InputIterator>
void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
// required for std::insert_iterator; the passed-in iterator is ignored
iterator insert(iterator, const value_type& obj) { return insert(obj).first; }
// Deletion routines
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
// value to identify deleted buckets. You can change the key as
// time goes on, or get rid of it entirely to be insert-only.
void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
void clear_deleted_key() { rep.clear_deleted_key(); }
key_type deleted_key() const { return rep.deleted_key(); }
// These are standard
size_type erase(const key_type& key) { return rep.erase(key); }
void erase(iterator it) { rep.erase(it); }
void erase(iterator f, iterator l) { rep.erase(f, l); }
// Comparison
bool operator==(const sparse_hash_set& hs) const { return rep == hs.rep; }
bool operator!=(const sparse_hash_set& hs) const { return rep != hs.rep; }
// I/O -- this is an add-on for writing metainformation to disk
bool write_metadata(FILE *fp) { return rep.write_metadata(fp); }
bool read_metadata(FILE *fp) { return rep.read_metadata(fp); }
bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); }
bool read_nopointer_data(FILE *fp) { return rep.read_nopointer_data(fp); }
};
template <class Val, class HashFcn, class EqualKey, class Alloc>
inline void swap(sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs1,
sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs2) {
hs1.swap(hs2);
}
_END_GOOGLE_NAMESPACE_
#endif /* _SPARSE_HASH_SET_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,49 +0,0 @@
/*
* NOTE: This file is for internal use only.
* Do not use these #defines in your own program!
*/
/* Namespace for Google classes */
#define GOOGLE_NAMESPACE ::google
/* the location of the header defining hash functions */
#define HASH_FUN_H <tr1/functional>
/* the namespace of the hash<> function */
#define HASH_NAMESPACE std::tr1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if the system has the type `long long'. */
#define HAVE_LONG_LONG 1
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if the system has the type `uint16_t'. */
#define HAVE_UINT16_T 1
/* Define to 1 if the system has the type `u_int16_t'. */
#define HAVE_U_INT16_T 1
/* Define to 1 if the system has the type `__uint16'. */
/* #undef HAVE___UINT16 */
/* The system-provided hash function including the namespace. */
#define SPARSEHASH_HASH HASH_NAMESPACE::hash
/* the namespace where STL code like vector<> is defined */
#define STL_NAMESPACE std
/* Stops putting the code inside the Google namespace */
#define _END_GOOGLE_NAMESPACE_ }
/* Puts following code inside the Google namespace */
#define _START_GOOGLE_NAMESPACE_ namespace google {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,250 +0,0 @@
// Copyright (c) 2006, Google Inc.
// 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 Google Inc. nor the names of its
// 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.
// ----
// Author: Matt Austern
//
// Define a small subset of tr1 type traits. The traits we define are:
// is_integral
// is_floating_point
// is_pointer
// is_reference
// is_pod
// has_trivial_constructor
// has_trivial_copy
// has_trivial_assign
// has_trivial_destructor
// remove_const
// remove_volatile
// remove_cv
// remove_reference
// remove_pointer
// is_convertible
// We can add more type traits as required.
#ifndef BASE_TYPE_TRAITS_H_
#define BASE_TYPE_TRAITS_H_
#include <google/sparsehash/sparseconfig.h>
#include <utility> // For pair
_START_GOOGLE_NAMESPACE_
// integral_constant, defined in tr1, is a wrapper for an integer
// value. We don't really need this generality; we could get away
// with hardcoding the integer type to bool. We use the fully
// general integer_constant for compatibility with tr1.
template<class T, T v>
struct integral_constant {
static const T value = v;
typedef T value_type;
typedef integral_constant<T, v> type;
};
template <class T, T v> const T integral_constant<T, v>::value;
// Abbreviations: true_type and false_type are structs that represent
// boolean true and false values.
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
// Types small_ and big_ are guaranteed such that sizeof(small_) <
// sizeof(big_)
typedef char small_;
struct big_ {
char dummy[2];
};
// is_integral is false except for the built-in integer types.
template <class T> struct is_integral : false_type { };
template<> struct is_integral<bool> : true_type { };
template<> struct is_integral<char> : true_type { };
template<> struct is_integral<unsigned char> : true_type { };
template<> struct is_integral<signed char> : true_type { };
#if defined(_MSC_VER)
// wchar_t is not by default a distinct type from unsigned short in
// Microsoft C.
// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
template<> struct is_integral<__wchar_t> : true_type { };
#else
template<> struct is_integral<wchar_t> : true_type { };
#endif
template<> struct is_integral<short> : true_type { };
template<> struct is_integral<unsigned short> : true_type { };
template<> struct is_integral<int> : true_type { };
template<> struct is_integral<unsigned int> : true_type { };
template<> struct is_integral<long> : true_type { };
template<> struct is_integral<unsigned long> : true_type { };
#ifdef HAVE_LONG_LONG
template<> struct is_integral<long long> : true_type { };
template<> struct is_integral<unsigned long long> : true_type { };
#endif
// is_floating_point is false except for the built-in floating-point types.
template <class T> struct is_floating_point : false_type { };
template<> struct is_floating_point<float> : true_type { };
template<> struct is_floating_point<double> : true_type { };
template<> struct is_floating_point<long double> : true_type { };
// is_pointer is false except for pointer types.
template <class T> struct is_pointer : false_type { };
template <class T> struct is_pointer<T*> : true_type { };
// is_reference is false except for reference types.
template<typename T> struct is_reference : false_type {};
template<typename T> struct is_reference<T&> : true_type {};
// We can't get is_pod right without compiler help, so fail conservatively.
// We will assume it's false except for arithmetic types and pointers,
// and const versions thereof. Note that std::pair is not a POD.
template <class T> struct is_pod
: integral_constant<bool, (is_integral<T>::value ||
is_floating_point<T>::value ||
is_pointer<T>::value)> { };
template <class T> struct is_pod<const T> : is_pod<T> { };
// We can't get has_trivial_constructor right without compiler help, so
// fail conservatively. We will assume it's false except for: (1) types
// for which is_pod is true. (2) std::pair of types with trivial
// constructors. (3) array of a type with a trivial constructor.
// (4) const versions thereof.
template <class T> struct has_trivial_constructor : is_pod<T> { };
template <class T, class U> struct has_trivial_constructor<std::pair<T, U> >
: integral_constant<bool,
(has_trivial_constructor<T>::value &&
has_trivial_constructor<U>::value)> { };
template <class A, int N> struct has_trivial_constructor<A[N]>
: has_trivial_constructor<A> { };
template <class T> struct has_trivial_constructor<const T>
: has_trivial_constructor<T> { };
// We can't get has_trivial_copy right without compiler help, so fail
// conservatively. We will assume it's false except for: (1) types
// for which is_pod is true. (2) std::pair of types with trivial copy
// constructors. (3) array of a type with a trivial copy constructor.
// (4) const versions thereof.
template <class T> struct has_trivial_copy : is_pod<T> { };
template <class T, class U> struct has_trivial_copy<std::pair<T, U> >
: integral_constant<bool,
(has_trivial_copy<T>::value &&
has_trivial_copy<U>::value)> { };
template <class A, int N> struct has_trivial_copy<A[N]>
: has_trivial_copy<A> { };
template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { };
// We can't get has_trivial_assign right without compiler help, so fail
// conservatively. We will assume it's false except for: (1) types
// for which is_pod is true. (2) std::pair of types with trivial copy
// constructors. (3) array of a type with a trivial assign constructor.
template <class T> struct has_trivial_assign : is_pod<T> { };
template <class T, class U> struct has_trivial_assign<std::pair<T, U> >
: integral_constant<bool,
(has_trivial_assign<T>::value &&
has_trivial_assign<U>::value)> { };
template <class A, int N> struct has_trivial_assign<A[N]>
: has_trivial_assign<A> { };
// We can't get has_trivial_destructor right without compiler help, so
// fail conservatively. We will assume it's false except for: (1) types
// for which is_pod is true. (2) std::pair of types with trivial
// destructors. (3) array of a type with a trivial destructor.
// (4) const versions thereof.
template <class T> struct has_trivial_destructor : is_pod<T> { };
template <class T, class U> struct has_trivial_destructor<std::pair<T, U> >
: integral_constant<bool,
(has_trivial_destructor<T>::value &&
has_trivial_destructor<U>::value)> { };
template <class A, int N> struct has_trivial_destructor<A[N]>
: has_trivial_destructor<A> { };
template <class T> struct has_trivial_destructor<const T>
: has_trivial_destructor<T> { };
// Specified by TR1 [4.7.1]
template<typename T> struct remove_const { typedef T type; };
template<typename T> struct remove_const<T const> { typedef T type; };
template<typename T> struct remove_volatile { typedef T type; };
template<typename T> struct remove_volatile<T volatile> { typedef T type; };
template<typename T> struct remove_cv {
typedef typename remove_const<typename remove_volatile<T>::type>::type type;
};
// Specified by TR1 [4.7.2]
template<typename T> struct remove_reference { typedef T type; };
template<typename T> struct remove_reference<T&> { typedef T type; };
// Specified by TR1 [4.7.4] Pointer modifications.
template<typename T> struct remove_pointer { typedef T type; };
template<typename T> struct remove_pointer<T*> { typedef T type; };
template<typename T> struct remove_pointer<T* const> { typedef T type; };
template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
template<typename T> struct remove_pointer<T* const volatile> {
typedef T type; };
// Specified by TR1 [4.6] Relationships between types
#ifndef _MSC_VER
namespace internal {
// This class is an implementation detail for is_convertible, and you
// don't need to know how it works to use is_convertible. For those
// who care: we declare two different functions, one whose argument is
// of type To and one with a variadic argument list. We give them
// return types of different size, so we can use sizeof to trick the
// compiler into telling us which function it would have chosen if we
// had called it with an argument of type From. See Alexandrescu's
// _Modern C++ Design_ for more details on this sort of trick.
template <typename From, typename To>
struct ConvertHelper {
static small_ Test(To);
static big_ Test(...);
static From Create();
};
} // namespace internal
// Inherits from true_type if From is convertible to To, false_type otherwise.
template <typename From, typename To>
struct is_convertible
: integral_constant<bool,
sizeof(internal::ConvertHelper<From, To>::Test(
internal::ConvertHelper<From, To>::Create()))
== sizeof(small_)> {
};
#endif
_END_GOOGLE_NAMESPACE_
#endif // BASE_TYPE_TRAITS_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,103 +0,0 @@
// Copyright (c) 2007, Google Inc.
// 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 Google Inc. nor the names of its
// 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.
// ---
// Author: Craig Silverstein
//
// This tests mostly that we can #include the files correctly
// and have them work. This unittest purposefully does not
// #include <config.h>; it's meant to emulate what a 'regular
// install' of sparsehash would be able to see.
#include <stdio.h>
#include <google/sparse_hash_set>
#include <google/sparse_hash_map>
#include <google/dense_hash_set>
#include <google/dense_hash_map>
#define CHECK_IFF(cond, when) do { \
if (when) { \
if (!(cond)) { \
puts("ERROR: " #cond " failed when " #when " is true\n"); \
exit(1); \
} \
} else { \
if (cond) { \
puts("ERROR: " #cond " succeeded when " #when " is false\n"); \
exit(1); \
} \
} \
} while (0)
int main(int argc, char** argv) {
// Run with an argument to get verbose output
const bool verbose = argc > 1;
google::sparse_hash_set<int> sset;
google::sparse_hash_map<int, int> smap;
google::dense_hash_set<int> dset;
google::dense_hash_map<int, int> dmap;
dset.set_empty_key(-1);
dmap.set_empty_key(-1);
for (int i = 0; i < 100; i += 10) { // go by tens
sset.insert(i);
smap[i] = i+1;
dset.insert(i + 5);
dmap[i+5] = i+6;
}
if (verbose) {
for (google::sparse_hash_set<int>::const_iterator it = sset.begin();
it != sset.end(); ++it)
printf("sset: %d\n", *it);
for (google::sparse_hash_map<int,int>::const_iterator it = smap.begin();
it != smap.end(); ++it)
printf("smap: %d -> %d\n", it->first, it->second);
for (google::dense_hash_set<int>::const_iterator it = dset.begin();
it != dset.end(); ++it)
printf("dset: %d\n", *it);
for (google::dense_hash_map<int,int>::const_iterator it = dmap.begin();
it != dmap.end(); ++it)
printf("dmap: %d -> %d\n", it->first, it->second);
}
for (int i = 0; i < 100; i++) {
CHECK_IFF(sset.find(i) != sset.end(), (i % 10) == 0);
CHECK_IFF(smap.find(i) != smap.end(), (i % 10) == 0);
CHECK_IFF(smap.find(i) != smap.end() && smap.find(i)->second == i+1,
(i % 10) == 0);
CHECK_IFF(dset.find(i) != dset.end(), (i % 10) == 5);
CHECK_IFF(dmap.find(i) != dmap.end(), (i % 10) == 5);
CHECK_IFF(dmap.find(i) != dmap.end() && dmap.find(i)->second == i+1,
(i % 10) == 5);
}
printf("PASS\n");
return 0;
}

View File

@ -1,696 +0,0 @@
// Copyright (c) 2005, Google Inc.
// 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 Google Inc. nor the names of its
// 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.
// ---
// Author: Craig Silverstein
//
// This tests <google/sparsetable>
//
// Since sparsetable is templatized, it's important that we test every
// function in every class in this file -- not just to see if it
// works, but even if it compiles.
#include "config.h"
#include <string>
#include <stdio.h>
#include <string.h> // for memcmp()
#include <stdlib.h> // defines unlink() on some windows platforms(?)
#ifdef HAVE_UNISTD_H
#include <unistd.h> // for unlink()
#include <sys/types.h> // for size_t
#include <string>
#endif
#include <google/sparsetable>
using STL_NAMESPACE::string;
using GOOGLE_NAMESPACE::sparsetable;
// Many sparsetable operations return a size_t. Rather than have to
// use PRIuS everywhere, we'll just cast to a "big enough" value.
#define UL(x) ( static_cast<unsigned long>(x) )
static char outbuf[10240]; // big enough for these tests
static char* out = outbuf; // where to write next
#define LEFT (outbuf + sizeof(outbuf) - out)
#define TEST(cond) out += snprintf(out, LEFT, #cond "? %s\n", \
(cond) ? "yes" : "no");
inline string AsString(int n) {
const int N = 64;
char buf[N];
snprintf(buf, N, "%d", n);
return string(buf);
}
// Test sparsetable with a POD type, int.
void TestInt() {
out += snprintf(out, LEFT, "int test\n");
sparsetable<int> x(7), y(70), z;
x.set(4, 10);
y.set(12, -12);
y.set(47, -47);
y.set(48, -48);
y.set(49, -49);
const sparsetable<int> constx(x);
const sparsetable<int> consty(y);
// ----------------------------------------------------------------------
// Test the plain iterators
for ( sparsetable<int>::iterator it = x.begin(); it != x.end(); ++it ) {
out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(it - x.begin()), int(*it));
}
for ( sparsetable<int>::const_iterator it = x.begin(); it != x.end(); ++it ) {
out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(it - x.begin()), *it);
}
for ( sparsetable<int>::reverse_iterator it = x.rbegin(); it != x.rend(); ++it ) {
out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(x.rend()-1 - it), int(*it));
}
for ( sparsetable<int>::const_reverse_iterator it = constx.rbegin(); it != constx.rend(); ++it ) {
out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(constx.rend()-1 - it), *it);
}
for ( sparsetable<int>::iterator it = z.begin(); it != z.end(); ++it ) {
out += snprintf(out, LEFT, "z[%lu]: %d\n", UL(it - z.begin()), int(*it));
}
{ // array version
out += snprintf(out, LEFT, "x[3]: %d\n", int(x[3]));
out += snprintf(out, LEFT, "x[4]: %d\n", int(x[4]));
out += snprintf(out, LEFT, "x[5]: %d\n", int(x[5]));
}
{
sparsetable<int>::iterator it; // non-const version
out += snprintf(out, LEFT, "x[4]: %d\n", int(x.begin()[4]));
it = x.begin() + 4; // should point to the non-zero value
out += snprintf(out, LEFT, "x[4]: %d\n", int(*it));
it--;
--it;
it += 5;
it -= 2;
it++;
++it;
it = it - 3;
it = 1 + it; // now at 5
out += snprintf(out, LEFT, "x[3]: %d\n", int(it[-2]));
out += snprintf(out, LEFT, "x[4]: %d\n", int(it[-1]));
*it = 55;
out += snprintf(out, LEFT, "x[5]: %d\n", int(it[0]));
out += snprintf(out, LEFT, "x[5]: %d\n", int(*it));
int *x6 = &(it[1]);
*x6 = 66;
out += snprintf(out, LEFT, "x[6]: %d\n", int(*(it + 1)));
// Let's test comparitors as well
TEST(it == it);
TEST(!(it != it));
TEST(!(it < it));
TEST(!(it > it));
TEST(it <= it);
TEST(it >= it);
sparsetable<int>::iterator it_minus_1 = it - 1;
TEST(!(it == it_minus_1));
TEST(it != it_minus_1);
TEST(!(it < it_minus_1));
TEST(it > it_minus_1);
TEST(!(it <= it_minus_1));
TEST(it >= it_minus_1);
TEST(!(it_minus_1 == it));
TEST(it_minus_1 != it);
TEST(it_minus_1 < it);
TEST(!(it_minus_1 > it));
TEST(it_minus_1 <= it);
TEST(!(it_minus_1 >= it));
sparsetable<int>::iterator it_plus_1 = it + 1;
TEST(!(it == it_plus_1));
TEST(it != it_plus_1);
TEST(it < it_plus_1);
TEST(!(it > it_plus_1));
TEST(it <= it_plus_1);
TEST(!(it >= it_plus_1));
TEST(!(it_plus_1 == it));
TEST(it_plus_1 != it);
TEST(!(it_plus_1 < it));
TEST(it_plus_1 > it);
TEST(!(it_plus_1 <= it));
TEST(it_plus_1 >= it);
}
{
sparsetable<int>::const_iterator it; // const version
out += snprintf(out, LEFT, "x[4]: %d\n", int(x.begin()[4]));
it = x.begin() + 4; // should point to the non-zero value
out += snprintf(out, LEFT, "x[4]: %d\n", *it);
it--;
--it;
it += 5;
it -= 2;
it++;
++it;
it = it - 3;
it = 1 + it; // now at 5
out += snprintf(out, LEFT, "x[3]: %d\n", it[-2]);
out += snprintf(out, LEFT, "x[4]: %d\n", it[-1]);
out += snprintf(out, LEFT, "x[5]: %d\n", *it);
out += snprintf(out, LEFT, "x[6]: %d\n", *(it + 1));
// Let's test comparitors as well
TEST(it == it);
TEST(!(it != it));
TEST(!(it < it));
TEST(!(it > it));
TEST(it <= it);
TEST(it >= it);
sparsetable<int>::const_iterator it_minus_1 = it - 1;
TEST(!(it == it_minus_1));
TEST(it != it_minus_1);
TEST(!(it < it_minus_1));
TEST(it > it_minus_1);
TEST(!(it <= it_minus_1));
TEST(it >= it_minus_1);
TEST(!(it_minus_1 == it));
TEST(it_minus_1 != it);
TEST(it_minus_1 < it);
TEST(!(it_minus_1 > it));
TEST(it_minus_1 <= it);
TEST(!(it_minus_1 >= it));
sparsetable<int>::const_iterator it_plus_1 = it + 1;
TEST(!(it == it_plus_1));
TEST(it != it_plus_1);
TEST(it < it_plus_1);
TEST(!(it > it_plus_1));
TEST(it <= it_plus_1);
TEST(!(it >= it_plus_1));
TEST(!(it_plus_1 == it));
TEST(it_plus_1 != it);
TEST(!(it_plus_1 < it));
TEST(it_plus_1 > it);
TEST(!(it_plus_1 <= it));
TEST(it_plus_1 >= it);
}
TEST(x.begin() == x.begin() + 1 - 1);
TEST(x.begin() < x.end());
TEST(z.begin() < z.end());
TEST(z.begin() <= z.end());
TEST(z.begin() == z.end());
// ----------------------------------------------------------------------
// Test the non-empty iterators
for ( sparsetable<int>::nonempty_iterator it = x.nonempty_begin(); it != x.nonempty_end(); ++it ) {
out += snprintf(out, LEFT, "x[??]: %d\n", *it);
}
for ( sparsetable<int>::const_nonempty_iterator it = y.nonempty_begin(); it != y.nonempty_end(); ++it ) {
out += snprintf(out, LEFT, "y[??]: %d\n", *it);
}
for ( sparsetable<int>::reverse_nonempty_iterator it = y.nonempty_rbegin(); it != y.nonempty_rend(); ++it ) {
out += snprintf(out, LEFT, "y[??]: %d\n", *it);
}
for ( sparsetable<int>::const_reverse_nonempty_iterator it = consty.nonempty_rbegin(); it != consty.nonempty_rend(); ++it ) {
out += snprintf(out, LEFT, "y[??]: %d\n", *it);
}
for ( sparsetable<int>::nonempty_iterator it = z.nonempty_begin(); it != z.nonempty_end(); ++it ) {
out += snprintf(out, LEFT, "z[??]: %d\n", *it);
}
{
sparsetable<int>::nonempty_iterator it; // non-const version
out += snprintf(out, LEFT, "first non-empty y: %d\n", *y.nonempty_begin());
out += snprintf(out, LEFT, "first non-empty x: %d\n", *x.nonempty_begin());
it = x.nonempty_begin();
++it; // should be at end
--it;
out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
it--;
out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
}
{
sparsetable<int>::const_nonempty_iterator it; // non-const version
out += snprintf(out, LEFT, "first non-empty y: %d\n", *y.nonempty_begin());
out += snprintf(out, LEFT, "first non-empty x: %d\n", *x.nonempty_begin());
it = x.nonempty_begin();
++it; // should be at end
--it;
out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
it--;
out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
}
TEST(x.begin() == x.begin() + 1 - 1);
TEST(z.begin() != z.end());
// ----------------------------------------------------------------------
// Test sparsetable functions
out += snprintf(out, LEFT, "x has %lu/%lu buckets, "
"y %lu/%lu, z %lu/%lu\n",
UL(x.num_nonempty()), UL(x.size()),
UL(y.num_nonempty()), UL(y.size()),
UL(z.num_nonempty()), UL(z.size()));
y.resize(48); // should get rid of 48 and 49
y.resize(70); // 48 and 49 should still be gone
out += snprintf(out, LEFT, "y shrank and grew: it's now %lu/%lu\n",
UL(y.num_nonempty()), UL(y.size()));
out += snprintf(out, LEFT, "y[12] = %d, y.get(12) = %d\n", int(y[12]), y.get(12));
y.erase(12);
out += snprintf(out, LEFT, "y[12] cleared. y now %lu/%lu. "
"y[12] = %d, y.get(12) = %d\n",
UL(y.num_nonempty()), UL(y.size()), int(y[12]), y.get(12));
swap(x, y);
y.clear();
TEST(y == z);
y.resize(70);
for ( int i = 10; i < 40; ++i )
y[i] = -i;
y.erase(y.begin() + 15, y.begin() + 30);
y.erase(y.begin() + 34);
y.erase(12);
y.resize(38);
y.resize(10000);
y[9898] = -9898;
for ( sparsetable<int>::const_iterator it = y.begin(); it != y.end(); ++it ) {
if ( y.test(it) )
out += snprintf(out, LEFT, "y[%lu] is set\n", UL(it - y.begin()));
}
out += snprintf(out, LEFT, "That's %lu set buckets\n", UL(y.num_nonempty()));
out += snprintf(out, LEFT, "Starting from y[32]...\n");
for ( sparsetable<int>::const_nonempty_iterator it = y.get_iter(32);
it != y.nonempty_end(); ++it )
out += snprintf(out, LEFT, "y[??] = %d\n", *it);
out += snprintf(out, LEFT, "From y[32] down...\n");
for ( sparsetable<int>::nonempty_iterator it = y.get_iter(32);
it != y.nonempty_begin(); )
out += snprintf(out, LEFT, "y[??] = %d\n", *--it);
// ----------------------------------------------------------------------
// Test I/O
string filestr = "/tmp/.sparsetable.test";
const char *file = filestr.c_str();
FILE *fp = fopen(file, "wb");
if ( fp == NULL ) {
// maybe we can't write to /tmp/. Try the current directory
file = ".sparsetable.test";
fp = fopen(file, "wb");
}
if ( fp == NULL ) {
out += snprintf(out, LEFT, "Can't open %s, skipping disk write...\n", file);
} else {
y.write_metadata(fp); // only write meta-information
y.write_nopointer_data(fp);
fclose(fp);
}
fp = fopen(file, "rb");
if ( fp == NULL ) {
out += snprintf(out, LEFT, "Can't open %s, skipping disk read...\n", file);
} else {
sparsetable<int> y2;
y2.read_metadata(fp);
y2.read_nopointer_data(fp);
fclose(fp);
for ( sparsetable<int>::const_iterator it = y2.begin(); it != y2.end(); ++it ) {
if ( y2.test(it) )
out += snprintf(out, LEFT, "y2[%lu] is %d\n", UL(it - y2.begin()), *it);
}
out += snprintf(out, LEFT, "That's %lu set buckets\n", UL(y2.num_nonempty()));
}
unlink(file);
}
// Test sparsetable with a non-POD type, std::string
void TestString() {
out += snprintf(out, LEFT, "string test\n");
sparsetable<string> x(7), y(70), z;
x.set(4, "foo");
y.set(12, "orange");
y.set(47, "grape");
y.set(48, "pear");
y.set(49, "apple");
// ----------------------------------------------------------------------
// Test the plain iterators
for ( sparsetable<string>::iterator it = x.begin(); it != x.end(); ++it ) {
out += snprintf(out, LEFT, "x[%lu]: %s\n",
UL(it - x.begin()), static_cast<string>(*it).c_str());
}
for ( sparsetable<string>::iterator it = z.begin(); it != z.end(); ++it ) {
out += snprintf(out, LEFT, "z[%lu]: %s\n",
UL(it - z.begin()), static_cast<string>(*it).c_str());
}
TEST(x.begin() == x.begin() + 1 - 1);
TEST(x.begin() < x.end());
TEST(z.begin() < z.end());
TEST(z.begin() <= z.end());
TEST(z.begin() == z.end());
// ----------------------------------------------------------------------
// Test the non-empty iterators
for ( sparsetable<string>::nonempty_iterator it = x.nonempty_begin(); it != x.nonempty_end(); ++it ) {
out += snprintf(out, LEFT, "x[??]: %s\n", it->c_str());
}
for ( sparsetable<string>::const_nonempty_iterator it = y.nonempty_begin(); it != y.nonempty_end(); ++it ) {
out += snprintf(out, LEFT, "y[??]: %s\n", it->c_str());
}
for ( sparsetable<string>::nonempty_iterator it = z.nonempty_begin(); it != z.nonempty_end(); ++it ) {
out += snprintf(out, LEFT, "z[??]: %s\n", it->c_str());
}
// ----------------------------------------------------------------------
// Test sparsetable functions
out += snprintf(out, LEFT, "x has %lu/%lu buckets, y %lu/%lu, z %lu/%lu\n",
UL(x.num_nonempty()), UL(x.size()),
UL(y.num_nonempty()), UL(y.size()),
UL(z.num_nonempty()), UL(z.size()));
y.resize(48); // should get rid of 48 and 49
y.resize(70); // 48 and 49 should still be gone
out += snprintf(out, LEFT, "y shrank and grew: it's now %lu/%lu\n",
UL(y.num_nonempty()), UL(y.size()));
out += snprintf(out, LEFT, "y[12] = %s, y.get(12) = %s\n",
static_cast<string>(y[12]).c_str(), y.get(12).c_str());
y.erase(12);
out += snprintf(out, LEFT, "y[12] cleared. y now %lu/%lu. "
"y[12] = %s, y.get(12) = %s\n",
UL(y.num_nonempty()), UL(y.size()),
static_cast<string>(y[12]).c_str(),
static_cast<string>(y.get(12)).c_str());
swap(x, y);
y.clear();
TEST(y == z);
y.resize(70);
for ( int i = 10; i < 40; ++i )
y.set(i, AsString(-i));
y.erase(y.begin() + 15, y.begin() + 30);
y.erase(y.begin() + 34);
y.erase(12);
y.resize(38);
y.resize(10000);
y.set(9898, AsString(-9898));
for ( sparsetable<string>::const_iterator it = y.begin(); it != y.end(); ++it ) {
if ( y.test(it) )
out += snprintf(out, LEFT, "y[%lu] is set\n", UL(it - y.begin()));
}
out += snprintf(out, LEFT, "That's %lu set buckets\n", UL(y.num_nonempty()));
out += snprintf(out, LEFT, "Starting from y[32]...\n");
for ( sparsetable<string>::const_nonempty_iterator it = y.get_iter(32);
it != y.nonempty_end(); ++it )
out += snprintf(out, LEFT, "y[??] = %s\n", it->c_str());
out += snprintf(out, LEFT, "From y[32] down...\n");
for ( sparsetable<string>::nonempty_iterator it = y.get_iter(32);
it != y.nonempty_begin(); )
out += snprintf(out, LEFT, "y[??] = %s\n", (*--it).c_str());
}
// The expected output from all of the above: TestInt() and TestString()
static const char g_expected[] = (
"int test\n"
"x[0]: 0\n"
"x[1]: 0\n"
"x[2]: 0\n"
"x[3]: 0\n"
"x[4]: 10\n"
"x[5]: 0\n"
"x[6]: 0\n"
"x[0]: 0\n"
"x[1]: 0\n"
"x[2]: 0\n"
"x[3]: 0\n"
"x[4]: 10\n"
"x[5]: 0\n"
"x[6]: 0\n"
"x[6]: 0\n"
"x[5]: 0\n"
"x[4]: 10\n"
"x[3]: 0\n"
"x[2]: 0\n"
"x[1]: 0\n"
"x[0]: 0\n"
"x[6]: 0\n"
"x[5]: 0\n"
"x[4]: 10\n"
"x[3]: 0\n"
"x[2]: 0\n"
"x[1]: 0\n"
"x[0]: 0\n"
"x[3]: 0\n"
"x[4]: 10\n"
"x[5]: 0\n"
"x[4]: 10\n"
"x[4]: 10\n"
"x[3]: 0\n"
"x[4]: 10\n"
"x[5]: 55\n"
"x[5]: 55\n"
"x[6]: 66\n"
"it == it? yes\n"
"!(it != it)? yes\n"
"!(it < it)? yes\n"
"!(it > it)? yes\n"
"it <= it? yes\n"
"it >= it? yes\n"
"!(it == it_minus_1)? yes\n"
"it != it_minus_1? yes\n"
"!(it < it_minus_1)? yes\n"
"it > it_minus_1? yes\n"
"!(it <= it_minus_1)? yes\n"
"it >= it_minus_1? yes\n"
"!(it_minus_1 == it)? yes\n"
"it_minus_1 != it? yes\n"
"it_minus_1 < it? yes\n"
"!(it_minus_1 > it)? yes\n"
"it_minus_1 <= it? yes\n"
"!(it_minus_1 >= it)? yes\n"
"!(it == it_plus_1)? yes\n"
"it != it_plus_1? yes\n"
"it < it_plus_1? yes\n"
"!(it > it_plus_1)? yes\n"
"it <= it_plus_1? yes\n"
"!(it >= it_plus_1)? yes\n"
"!(it_plus_1 == it)? yes\n"
"it_plus_1 != it? yes\n"
"!(it_plus_1 < it)? yes\n"
"it_plus_1 > it? yes\n"
"!(it_plus_1 <= it)? yes\n"
"it_plus_1 >= it? yes\n"
"x[4]: 10\n"
"x[4]: 10\n"
"x[3]: 0\n"
"x[4]: 10\n"
"x[5]: 55\n"
"x[6]: 66\n"
"it == it? yes\n"
"!(it != it)? yes\n"
"!(it < it)? yes\n"
"!(it > it)? yes\n"
"it <= it? yes\n"
"it >= it? yes\n"
"!(it == it_minus_1)? yes\n"
"it != it_minus_1? yes\n"
"!(it < it_minus_1)? yes\n"
"it > it_minus_1? yes\n"
"!(it <= it_minus_1)? yes\n"
"it >= it_minus_1? yes\n"
"!(it_minus_1 == it)? yes\n"
"it_minus_1 != it? yes\n"
"it_minus_1 < it? yes\n"
"!(it_minus_1 > it)? yes\n"
"it_minus_1 <= it? yes\n"
"!(it_minus_1 >= it)? yes\n"
"!(it == it_plus_1)? yes\n"
"it != it_plus_1? yes\n"
"it < it_plus_1? yes\n"
"!(it > it_plus_1)? yes\n"
"it <= it_plus_1? yes\n"
"!(it >= it_plus_1)? yes\n"
"!(it_plus_1 == it)? yes\n"
"it_plus_1 != it? yes\n"
"!(it_plus_1 < it)? yes\n"
"it_plus_1 > it? yes\n"
"!(it_plus_1 <= it)? yes\n"
"it_plus_1 >= it? yes\n"
"x.begin() == x.begin() + 1 - 1? yes\n"
"x.begin() < x.end()? yes\n"
"z.begin() < z.end()? no\n"
"z.begin() <= z.end()? yes\n"
"z.begin() == z.end()? yes\n"
"x[??]: 10\n"
"x[??]: 55\n"
"x[??]: 66\n"
"y[??]: -12\n"
"y[??]: -47\n"
"y[??]: -48\n"
"y[??]: -49\n"
"y[??]: -49\n"
"y[??]: -48\n"
"y[??]: -47\n"
"y[??]: -12\n"
"y[??]: -49\n"
"y[??]: -48\n"
"y[??]: -47\n"
"y[??]: -12\n"
"first non-empty y: -12\n"
"first non-empty x: 10\n"
"first non-empty x: 10\n"
"first non-empty x: 10\n"
"first non-empty y: -12\n"
"first non-empty x: 10\n"
"first non-empty x: 10\n"
"first non-empty x: 10\n"
"x.begin() == x.begin() + 1 - 1? yes\n"
"z.begin() != z.end()? no\n"
"x has 3/7 buckets, y 4/70, z 0/0\n"
"y shrank and grew: it's now 2/70\n"
"y[12] = -12, y.get(12) = -12\n"
"y[12] cleared. y now 1/70. y[12] = 0, y.get(12) = 0\n"
"y == z? no\n"
"y[10] is set\n"
"y[11] is set\n"
"y[13] is set\n"
"y[14] is set\n"
"y[30] is set\n"
"y[31] is set\n"
"y[32] is set\n"
"y[33] is set\n"
"y[35] is set\n"
"y[36] is set\n"
"y[37] is set\n"
"y[9898] is set\n"
"That's 12 set buckets\n"
"Starting from y[32]...\n"
"y[??] = -32\n"
"y[??] = -33\n"
"y[??] = -35\n"
"y[??] = -36\n"
"y[??] = -37\n"
"y[??] = -9898\n"
"From y[32] down...\n"
"y[??] = -31\n"
"y[??] = -30\n"
"y[??] = -14\n"
"y[??] = -13\n"
"y[??] = -11\n"
"y[??] = -10\n"
"y2[10] is -10\n"
"y2[11] is -11\n"
"y2[13] is -13\n"
"y2[14] is -14\n"
"y2[30] is -30\n"
"y2[31] is -31\n"
"y2[32] is -32\n"
"y2[33] is -33\n"
"y2[35] is -35\n"
"y2[36] is -36\n"
"y2[37] is -37\n"
"y2[9898] is -9898\n"
"That's 12 set buckets\n"
"string test\n"
"x[0]: \n"
"x[1]: \n"
"x[2]: \n"
"x[3]: \n"
"x[4]: foo\n"
"x[5]: \n"
"x[6]: \n"
"x.begin() == x.begin() + 1 - 1? yes\n"
"x.begin() < x.end()? yes\n"
"z.begin() < z.end()? no\n"
"z.begin() <= z.end()? yes\n"
"z.begin() == z.end()? yes\n"
"x[??]: foo\n"
"y[??]: orange\n"
"y[??]: grape\n"
"y[??]: pear\n"
"y[??]: apple\n"
"x has 1/7 buckets, y 4/70, z 0/0\n"
"y shrank and grew: it's now 2/70\n"
"y[12] = orange, y.get(12) = orange\n"
"y[12] cleared. y now 1/70. y[12] = , y.get(12) = \n"
"y == z? no\n"
"y[10] is set\n"
"y[11] is set\n"
"y[13] is set\n"
"y[14] is set\n"
"y[30] is set\n"
"y[31] is set\n"
"y[32] is set\n"
"y[33] is set\n"
"y[35] is set\n"
"y[36] is set\n"
"y[37] is set\n"
"y[9898] is set\n"
"That's 12 set buckets\n"
"Starting from y[32]...\n"
"y[??] = -32\n"
"y[??] = -33\n"
"y[??] = -35\n"
"y[??] = -36\n"
"y[??] = -37\n"
"y[??] = -9898\n"
"From y[32] down...\n"
"y[??] = -31\n"
"y[??] = -30\n"
"y[??] = -14\n"
"y[??] = -13\n"
"y[??] = -11\n"
"y[??] = -10\n"
);
// defined at bottom of file for ease of maintainence
int main(int argc, char **argv) { // though we ignore the args
TestInt();
TestString();
// Finally, check to see if our output (in out) is what it's supposed to be.
const size_t r = sizeof(g_expected) - 1;
if ( r != out - outbuf || // output not the same size
memcmp(outbuf, g_expected, r) ) { // or bytes differed
fprintf(stderr, "TESTS FAILED\n\nEXPECTED:\n\n%s\n\nACTUAL:\n\n%s\n\n",
g_expected, outbuf);
return 1;
} else {
printf("PASS.\n");
return 0;
}
}

View File

@ -1 +0,0 @@
timestamp for src/config.h

View File

@ -1,488 +0,0 @@
// Copyright (c) 2005, Google Inc.
// 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 Google Inc. nor the names of its
// 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.
// ---
// Authors: Sanjay Ghemawat and Craig Silverstein
//
// Time various hash map implementations
//
// See PERFORMANCE for the output of one example run.
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern "C" {
#include <time.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#ifdef HAVE_SYS_UTSNAME_H
#include <sys/utsname.h> // for uname()
#endif
#ifdef HAVE_WINDOWS_H
#include <Windows.h> // for GetTickCount()
#endif
}
// The functions that we call on each map, that differ for different types.
// By default each is a noop, but we redefine them for types that need them.
#include <map>
#include HASH_MAP_H
#include <google/type_traits.h>
#include <google/sparse_hash_map>
using GOOGLE_NAMESPACE::sparse_hash_map;
#include <google/dense_hash_map>
using GOOGLE_NAMESPACE::dense_hash_map;
static const int kDefaultIters = 10000000;
// Normally I don't like non-const references, but using them here ensures
// the inlined code ends up as efficient as possible.
// These are operations that are supported on some hash impls but not others
template<class MapType> inline void SET_DELETED_KEY(MapType& m, int key) {}
template<class MapType> inline void SET_EMPTY_KEY(MapType& m, int key) {}
template<class MapType> inline void RESIZE(MapType& m, int iters) {}
template<class K, class V, class H>
inline void SET_DELETED_KEY(sparse_hash_map<K,V,H>& m, int key) {
m.set_deleted_key(key);
}
template<class K, class V, class H>
inline void SET_DELETED_KEY(dense_hash_map<K,V,H>& m, int key) {
m.set_deleted_key(key);
}
template<class K, class V, class H>
inline void SET_EMPTY_KEY(dense_hash_map<K,V,H>& m, int key) {
m.set_empty_key(key);
}
template<class K, class V, class H>
inline void RESIZE(sparse_hash_map<K,V,H>& m, int iters) {
m.resize(iters);
}
template<class K, class V, class H>
inline void RESIZE(dense_hash_map<K,V,H>& m, int iters) {
m.resize(iters);
}
#if defined(HAVE_UNORDERED_MAP)
template<class K, class V, class H>
inline void RESIZE(HASH_NAMESPACE::unordered_map<K,V,H>& m, int iters) {
m.rehash(iters); // the tr1 name for resize()
}
#elif defined(HAVE_HASH_MAP)
template<class K, class V, class H>
inline void RESIZE(HASH_NAMESPACE::hash_map<K,V,H>& m, int iters) {
#ifndef _MSC_VER /* apparently windows hash_map doesn't support resizing */
m.resize(iters);
#endif // _MSC_VER
}
#endif // HAVE_HASH_MAP
/*
* These are the objects we hash. Size is the size of the object
* (must be > sizeof(int). Hashsize is how many of these bytes we
* use when hashing (must be > sizeof(int) and < Size).
*/
template<int Size, int Hashsize> class HashObject {
public:
typedef HashObject<Size, Hashsize> class_type;
HashObject() {}
HashObject(int i) : i_(i) {
memset(buffer_, i & 255, sizeof(buffer_)); // a "random" char
}
size_t Hash() const {
int hashval = i_;
for (int i = 0; i < Hashsize - sizeof(i_); ++i) {
hashval += buffer_[i];
}
return SPARSEHASH_HASH<int>()(hashval); // defined in sparseconfig.h
}
bool operator==(const class_type& that) const { return this->i_ == that.i_; }
bool operator< (const class_type& that) const { return this->i_ < that.i_; }
bool operator<=(const class_type& that) const { return this->i_ <= that.i_; }
private:
int i_; // the key used for hashing
char buffer_[Size - sizeof(int)];
};
// A specialization for the case sizeof(buffer_) == 0
template<> class HashObject<sizeof(int), sizeof(int)> {
public:
typedef HashObject<sizeof(int), sizeof(int)> class_type;
HashObject() {}
HashObject(int i) : i_(i) {}
size_t Hash() const { return SPARSEHASH_HASH<int>()(i_); }
bool operator==(const class_type& that) const { return this->i_ == that.i_; }
bool operator< (const class_type& that) const { return this->i_ < that.i_; }
bool operator<=(const class_type& that) const { return this->i_ <= that.i_; }
private:
int i_; // the key used for hashing
};
// Let the hashtable implementations know it can use an optimized memcpy,
// because the compiler defines both the destructor and copy constructor.
_START_GOOGLE_NAMESPACE_
template<int Size, int Hashsize>
struct has_trivial_copy< HashObject<Size, Hashsize> > : true_type { };
template<int Size, int Hashsize>
struct has_trivial_destructor< HashObject<Size, Hashsize> > : true_type { };
_END_GOOGLE_NAMESPACE_
class HashFn {
public:
template<int Size, int Hashsize>
size_t operator()(const HashObject<Size,Hashsize>& obj) const {
return obj.Hash();
}
// For windows
template<int Size, int Hashsize>
bool operator()(const HashObject<Size,Hashsize>& a,
const HashObject<Size,Hashsize>& b) const {
return a < b;
}
// These two public members are required by msvc. 4 and 8 are defaults.
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
};
/*
* Measure resource usage.
*/
class Rusage {
public:
/* Start collecting usage */
Rusage() { Reset(); }
/* Reset collection */
void Reset();
/* Show usage */
double UserTime();
private:
#if defined HAVE_SYS_RESOURCE_H
struct rusage start;
#elif defined HAVE_WINDOWS_H
long long int start;
#else
time_t start_time_t;
#endif
};
inline void Rusage::Reset() {
#if defined HAVE_SYS_RESOURCE_H
getrusage(RUSAGE_SELF, &start);
#elif defined HAVE_WINDOWS_H
start = GetTickCount();
#else
time(&start_time_t);
#endif
}
inline double Rusage::UserTime() {
#if defined HAVE_SYS_RESOURCE_H
struct rusage u;
getrusage(RUSAGE_SELF, &u);
struct timeval result;
result.tv_sec = u.ru_utime.tv_sec - start.ru_utime.tv_sec;
result.tv_usec = u.ru_utime.tv_usec - start.ru_utime.tv_usec;
return double(result.tv_sec) + double(result.tv_usec) / 1000000.0;
#elif defined HAVE_WINDOWS_H
return double(GetTickCount() - start) / 1000.0;
#else
time_t now;
time(&now);
return now - start_time_t;
#endif
}
static void print_uname() {
#ifdef HAVE_SYS_UTSNAME_H
struct utsname u;
if (uname(&u) == 0) {
printf("%s %s %s %s %s\n",
u.sysname, u.nodename, u.release, u.version, u.machine);
}
#endif
}
// Generate stamp for this run
static void stamp_run(int iters) {
time_t now = time(0);
printf("======\n");
fflush(stdout);
print_uname();
printf("Average over %d iterations\n", iters);
fflush(stdout);
// don't need asctime_r/gmtime_r: we're not threaded
printf("Current time (GMT): %s", asctime(gmtime(&now)));
}
// If you have google-perftools (http://code.google.com/p/google-perftools),
// then you can figure out how much memory these implementations use
// as well.
#ifdef HAVE_GOOGLE_MALLOC_EXTENSION_H
#include <google/malloc_extension.h>
static size_t CurrentMemoryUsage() {
size_t result;
if (MallocExtension::instance()->GetNumericProperty(
"generic.current_allocated_bytes",
&result)) {
return result;
} else {
return 0;
}
}
#else /* not HAVE_GOOGLE_MALLOC_EXTENSION_H */
static size_t CurrentMemoryUsage() { return 0; }
#endif
static void report(char const* title, double t,
int iters,
size_t heap_growth) {
// Construct heap growth report text if applicable
char heap[100];
if (heap_growth > 0) {
snprintf(heap, sizeof(heap), "%8.1f MB", heap_growth / 1048576.0);
} else {
heap[0] = '\0';
}
printf("%-20s %8.1f ns %s\n", title, (t * 1000000000.0 / iters), heap);
fflush(stdout);
}
template<class MapType>
static void time_map_grow(int iters) {
MapType set;
Rusage t;
SET_EMPTY_KEY(set, -2);
const size_t start = CurrentMemoryUsage();
t.Reset();
for (int i = 0; i < iters; i++) {
set[i] = i+1;
}
double ut = t.UserTime();
const size_t finish = CurrentMemoryUsage();
report("map_grow", ut, iters, finish - start);
}
template<class MapType>
static void time_map_grow_predicted(int iters) {
MapType set;
Rusage t;
SET_EMPTY_KEY(set, -2);
const size_t start = CurrentMemoryUsage();
RESIZE(set, iters);
t.Reset();
for (int i = 0; i < iters; i++) {
set[i] = i+1;
}
double ut = t.UserTime();
const size_t finish = CurrentMemoryUsage();
report("map_predict/grow", ut, iters, finish - start);
}
template<class MapType>
static void time_map_replace(int iters) {
MapType set;
Rusage t;
int i;
SET_EMPTY_KEY(set, -2);
for (i = 0; i < iters; i++) {
set[i] = i+1;
}
t.Reset();
for (i = 0; i < iters; i++) {
set[i] = i+1;
}
double ut = t.UserTime();
report("map_replace", ut, iters, 0);
}
template<class MapType>
static void time_map_fetch(int iters) {
MapType set;
Rusage t;
int r;
int i;
SET_EMPTY_KEY(set, -2);
for (i = 0; i < iters; i++) {
set[i] = i+1;
}
r = 1;
t.Reset();
for (i = 0; i < iters; i++) {
r ^= static_cast<int>(set.find(i) != set.end());
}
double ut = t.UserTime();
srand(r); // keep compiler from optimizing away r (we never call rand())
report("map_fetch", ut, iters, 0);
}
template<class MapType>
static void time_map_fetch_empty(int iters) {
MapType set;
Rusage t;
int r;
int i;
SET_EMPTY_KEY(set, -2);
r = 1;
t.Reset();
for (i = 0; i < iters; i++) {
r ^= static_cast<int>(set.find(i) != set.end());
}
double ut = t.UserTime();
srand(r); // keep compiler from optimizing away r (we never call rand())
report("map_fetch_empty", ut, iters, 0);
}
template<class MapType>
static void time_map_remove(int iters) {
MapType set;
Rusage t;
int i;
SET_EMPTY_KEY(set, -2);
for (i = 0; i < iters; i++) {
set[i] = i+1;
}
t.Reset();
SET_DELETED_KEY(set, -1);
for (i = 0; i < iters; i++) {
set.erase(i);
}
double ut = t.UserTime();
report("map_remove", ut, iters, 0);
}
template<class MapType>
static void time_map_toggle(int iters) {
MapType set;
Rusage t;
int i;
const size_t start = CurrentMemoryUsage();
t.Reset();
SET_DELETED_KEY(set, -1);
SET_EMPTY_KEY(set, -2);
for (i = 0; i < iters; i++) {
set[i] = i+1;
set.erase(i);
}
double ut = t.UserTime();
const size_t finish = CurrentMemoryUsage();
report("map_toggle", ut, iters, finish - start);
}
template<class MapType>
static void measure_map(const char* label, int iters) {
printf("\n%s:\n", label);
if (1) time_map_grow<MapType>(iters);
if (1) time_map_grow_predicted<MapType>(iters);
if (1) time_map_replace<MapType>(iters);
if (1) time_map_fetch<MapType>(iters);
if (1) time_map_fetch_empty<MapType>(iters);
if (1) time_map_remove<MapType>(iters);
if (1) time_map_toggle<MapType>(iters);
}
int main(int argc, char** argv) {
int iters = kDefaultIters;
if (argc > 1) { // first arg is # of iterations
iters = atoi(argv[1]);
}
// It would be nice to set these at run-time, but by setting them at
// compile-time, we allow optimizations that make it as fast to use
// a HashObject as it would be to use just a straight int/char buffer.
const int obj_size = 4;
const int hash_size = 4;
typedef HashObject<obj_size, hash_size> HashObj;
stamp_run(iters);
#ifndef HAVE_SYS_RESOURCE_H
printf("\n*** WARNING ***: sys/resources.h was not found, so all times\n"
" reported are wall-clock time, not user time\n");
#endif
measure_map< sparse_hash_map<HashObj,int,HashFn> >("SPARSE_HASH_MAP", iters);
measure_map< dense_hash_map<HashObj,int,HashFn> >("DENSE_HASH_MAP", iters);
#if defined(HAVE_UNORDERED_MAP)
measure_map< HASH_NAMESPACE::unordered_map<HashObj,int,HashFn> >(
"TR1 UNORDERED_MAP", iters);
#elif defined(HAVE_HASH_MAP)
measure_map< HASH_NAMESPACE::hash_map<HashObj,int,HashFn> >(
"STANDARD HASH_MAP", iters);
#endif
measure_map< STL_NAMESPACE::map<HashObj,int,HashFn> >("STANDARD MAP", iters);
return 0;
}

View File

@ -1,492 +0,0 @@
// Copyright (c) 2006, Google Inc.
// 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 Google Inc. nor the names of its
// 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.
// ----
// Author: Matt Austern
#include "config.h"
#include <stdlib.h> // for exit()
#include <stdio.h>
#include <string>
#include <vector>
#include <google/type_traits.h>
using STL_NAMESPACE::string;
using STL_NAMESPACE::vector;
using STL_NAMESPACE::pair;
#define ASSERT_TRUE(cond) do { \
if ( !(cond) ) { \
printf("Test failed: " #cond "\n"); \
exit(1); \
} \
} while (0)
#define ASSERT_FALSE(cond) ASSERT_TRUE(!(cond))
// A user-defined POD type.
struct A {
int n_;
};
// A user-defined non-POD type with a trivial copy constructor.
class B {
public:
explicit B(int n) : n_(n) { }
private:
int n_;
};
// Another user-defined non-POD type with a trivial copy constructor.
// We will explicitly declare C to have a trivial copy constructor
// by specializing has_trivial_copy.
class C {
public:
explicit C(int n) : n_(n) { }
private:
int n_;
};
_START_GOOGLE_NAMESPACE_
template<> struct has_trivial_copy<C> : true_type { };
_END_GOOGLE_NAMESPACE_
// Another user-defined non-POD type with a trivial assignment operator.
// We will explicitly declare C to have a trivial assignment operator
// by specializing has_trivial_assign.
class D {
public:
explicit D(int n) : n_(n) { }
private:
int n_;
};
_START_GOOGLE_NAMESPACE_
template<> struct has_trivial_assign<D> : true_type { };
_END_GOOGLE_NAMESPACE_
// Another user-defined non-POD type with a trivial constructor.
// We will explicitly declare E to have a trivial constructor
// by specializing has_trivial_constructor.
class E {
public:
int n_;
};
_START_GOOGLE_NAMESPACE_
template<> struct has_trivial_constructor<E> : true_type { };
_END_GOOGLE_NAMESPACE_
// Another user-defined non-POD type with a trivial destructor.
// We will explicitly declare E to have a trivial destructor
// by specializing has_trivial_destructor.
class F {
public:
explicit F(int n) : n_(n) { }
private:
int n_;
};
_START_GOOGLE_NAMESPACE_
template<> struct has_trivial_destructor<F> : true_type { };
_END_GOOGLE_NAMESPACE_
namespace {
// type_equals_ is a template type comparator, similar to Loki IsSameType.
// type_equals_<A, B>::value is true iff "A" is the same type as "B".
template<typename A, typename B>
struct type_equals_ : public GOOGLE_NAMESPACE::false_type {
};
template<typename A>
struct type_equals_<A, A> : public GOOGLE_NAMESPACE::true_type {
};
// A base class and a derived class that inherits from it, used for
// testing conversion type traits.
class Base {
public:
virtual ~Base() { }
};
class Derived : public Base {
};
// This assertion produces errors like "error: invalid use of
// undefined type 'struct <unnamed>::AssertTypesEq<const int, int>'"
// when it fails.
template<typename T, typename U> struct AssertTypesEq;
template<typename T> struct AssertTypesEq<T, T> {};
#define COMPILE_ASSERT_TYPES_EQ(T, U) AssertTypesEq<T, U>()
class TypeTraitsTest {
public:
static void TestIsInteger() {
// Verify that is_integral is true for all integer types.
ASSERT_TRUE(GOOGLE_NAMESPACE::is_integral<bool>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_integral<char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_integral<unsigned char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_integral<signed char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_integral<wchar_t>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_integral<int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_integral<unsigned int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_integral<short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_integral<unsigned short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_integral<long>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_integral<unsigned long>::value);
// Verify that is_integral is false for a few non-integer types.
ASSERT_FALSE(GOOGLE_NAMESPACE::is_integral<void>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_integral<float>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_integral<string>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_integral<int*>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_integral<A>::value);
ASSERT_FALSE((GOOGLE_NAMESPACE::is_integral<pair<int, int> >::value));
}
static void TestIsFloating() {
// Verify that is_floating_point is true for all floating-point types.
ASSERT_TRUE(GOOGLE_NAMESPACE::is_floating_point<float>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_floating_point<double>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_floating_point<long double>::value);
// Verify that is_floating_point is false for a few non-float types.
ASSERT_FALSE(GOOGLE_NAMESPACE::is_floating_point<void>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_floating_point<long>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_floating_point<string>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_floating_point<float*>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_floating_point<A>::value);
ASSERT_FALSE((GOOGLE_NAMESPACE::is_floating_point<pair<int, int> >::value));
}
static void TestIsReference() {
// Verifies that is_reference is true for all reference types.
ASSERT_TRUE(GOOGLE_NAMESPACE::is_reference<float&>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_reference<const int&>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_reference<const int*&>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_reference<int (&)(bool)>::value);
// Verifies that is_reference is false for all non-reference types.
ASSERT_FALSE(GOOGLE_NAMESPACE::is_reference<float>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_reference<const int*>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_reference<int()>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_reference<void(*)(const char&)>::value);
}
static void TestIsPod() {
// Verify that arithmetic types and pointers are marked as PODs.
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<bool>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<unsigned char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<signed char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<wchar_t>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<unsigned int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<unsigned short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<long>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<unsigned long>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<float>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<double>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<long double>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<string*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<A*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<const B*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::is_pod<C**>::value);
// Verify that some non-POD types are not marked as PODs.
ASSERT_FALSE(GOOGLE_NAMESPACE::is_pod<void>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_pod<string>::value);
ASSERT_FALSE((GOOGLE_NAMESPACE::is_pod<pair<int, int> >::value));
ASSERT_FALSE(GOOGLE_NAMESPACE::is_pod<A>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_pod<B>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::is_pod<C>::value);
}
static void TestHasTrivialCopy() {
// Verify that arithmetic types and pointers have trivial copy
// constructors.
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<bool>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<unsigned char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<signed char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<wchar_t>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<unsigned int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<unsigned short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<long>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<unsigned long>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<float>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<double>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<long double>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<string*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<A*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<const B*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<C**>::value);
// Verify that pairs and arrays of such types have trivial
// copy constructors.
typedef int int10[10];
ASSERT_TRUE((GOOGLE_NAMESPACE::has_trivial_copy<pair<int, char*> >::value));
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<int10>::value);
// Verify that types without trivial copy constructors are
// correctly marked as such.
ASSERT_FALSE(GOOGLE_NAMESPACE::has_trivial_copy<string>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::has_trivial_copy<vector<int> >::value);
// Verify that pairs of types without trivial copy constructors
// are not marked as trivial.
ASSERT_FALSE((GOOGLE_NAMESPACE::has_trivial_copy<pair<int, string> >::value));
ASSERT_FALSE((GOOGLE_NAMESPACE::has_trivial_copy<pair<string, int> >::value));
// Verify that C, which we have declared to have a trivial
// copy constructor, is correctly marked as such.
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_copy<C>::value);
}
static void TestHasTrivialConstructor() {
// Verify that arithmetic types and pointers have trivial constructors.
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<bool>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<unsigned char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<signed char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<wchar_t>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<unsigned int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<unsigned short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<long>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<unsigned long>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<float>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<double>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<long double>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<string*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<A*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<const B*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<C**>::value);
// Verify that pairs and arrays of such types have trivial
// constructors.
typedef int int10[10];
ASSERT_TRUE((GOOGLE_NAMESPACE::has_trivial_constructor<pair<int, char*> >::value));
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<int10>::value);
// Verify that pairs of types without trivial constructors
// are not marked as trivial.
ASSERT_FALSE((GOOGLE_NAMESPACE::has_trivial_constructor<pair<int, string> >::value));
ASSERT_FALSE((GOOGLE_NAMESPACE::has_trivial_constructor<pair<string, int> >::value));
// Verify that types without trivial constructors are
// correctly marked as such.
ASSERT_FALSE(GOOGLE_NAMESPACE::has_trivial_constructor<string>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::has_trivial_constructor<vector<int> >::value);
// Verify that E, which we have declared to have a trivial
// constructor, is correctly marked as such.
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_constructor<E>::value);
}
static void TestHasTrivialAssign() {
// Verify that arithmetic types and pointers have trivial assignment
// operators.
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<bool>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<unsigned char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<signed char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<wchar_t>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<unsigned int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<unsigned short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<long>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<unsigned long>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<float>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<double>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<long double>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<string*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<A*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<const B*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<C**>::value);
// Verify that pairs and arrays of such types have trivial
// assignment operators.
typedef int int10[10];
ASSERT_TRUE((GOOGLE_NAMESPACE::has_trivial_assign<pair<int, char*> >::value));
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<int10>::value);
// Verify that pairs of types without trivial assignment operators
// are not marked as trivial.
ASSERT_FALSE((GOOGLE_NAMESPACE::has_trivial_assign<pair<int, string> >::value));
ASSERT_FALSE((GOOGLE_NAMESPACE::has_trivial_assign<pair<string, int> >::value));
// Verify that types without trivial assignment operators are
// correctly marked as such.
ASSERT_FALSE(GOOGLE_NAMESPACE::has_trivial_assign<string>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::has_trivial_assign<vector<int> >::value);
// Verify that D, which we have declared to have a trivial
// assignment operator, is correctly marked as such.
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_assign<D>::value);
}
static void TestHasTrivialDestructor() {
// Verify that arithmetic types and pointers have trivial destructors.
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<bool>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<unsigned char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<signed char>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<wchar_t>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<unsigned int>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<unsigned short>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<long>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<unsigned long>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<float>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<double>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<long double>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<string*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<A*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<const B*>::value);
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<C**>::value);
// Verify that pairs and arrays of such types have trivial
// destructors.
typedef int int10[10];
ASSERT_TRUE((GOOGLE_NAMESPACE::has_trivial_destructor<pair<int, char*> >::value));
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<int10>::value);
// Verify that pairs of types without trivial destructors
// are not marked as trivial.
ASSERT_FALSE((GOOGLE_NAMESPACE::has_trivial_destructor<pair<int, string> >::value));
ASSERT_FALSE((GOOGLE_NAMESPACE::has_trivial_destructor<pair<string, int> >::value));
// Verify that types without trivial destructors are
// correctly marked as such.
ASSERT_FALSE(GOOGLE_NAMESPACE::has_trivial_destructor<string>::value);
ASSERT_FALSE(GOOGLE_NAMESPACE::has_trivial_destructor<vector<int> >::value);
// Verify that F, which we have declared to have a trivial
// destructor, is correctly marked as such.
ASSERT_TRUE(GOOGLE_NAMESPACE::has_trivial_destructor<F>::value);
}
// Tests remove_pointer.
static void TestRemovePointer() {
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_pointer<int>::type);
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_pointer<int*>::type);
COMPILE_ASSERT_TYPES_EQ(const int, GOOGLE_NAMESPACE::remove_pointer<const int*>::type);
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_pointer<int* const>::type);
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_pointer<int* volatile>::type);
}
static void TestRemoveConst() {
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_const<int>::type);
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_const<const int>::type);
COMPILE_ASSERT_TYPES_EQ(int *, GOOGLE_NAMESPACE::remove_const<int * const>::type);
// TR1 examples.
COMPILE_ASSERT_TYPES_EQ(const int *, GOOGLE_NAMESPACE::remove_const<const int *>::type);
COMPILE_ASSERT_TYPES_EQ(volatile int,
GOOGLE_NAMESPACE::remove_const<const volatile int>::type);
}
static void TestRemoveVolatile() {
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_volatile<int>::type);
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_volatile<volatile int>::type);
COMPILE_ASSERT_TYPES_EQ(int *, GOOGLE_NAMESPACE::remove_volatile<int * volatile>::type);
// TR1 examples.
COMPILE_ASSERT_TYPES_EQ(volatile int *,
GOOGLE_NAMESPACE::remove_volatile<volatile int *>::type);
COMPILE_ASSERT_TYPES_EQ(const int,
GOOGLE_NAMESPACE::remove_volatile<const volatile int>::type);
}
static void TestRemoveReference() {
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_reference<int>::type);
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_reference<int&>::type);
COMPILE_ASSERT_TYPES_EQ(const int, GOOGLE_NAMESPACE::remove_reference<const int&>::type);
COMPILE_ASSERT_TYPES_EQ(int*, GOOGLE_NAMESPACE::remove_reference<int * &>::type);
}
static void TestRemoveCV() {
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_cv<int>::type);
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_cv<volatile int>::type);
COMPILE_ASSERT_TYPES_EQ(int, GOOGLE_NAMESPACE::remove_cv<const int>::type);
COMPILE_ASSERT_TYPES_EQ(int *, GOOGLE_NAMESPACE::remove_cv<int * const volatile>::type);
// TR1 examples.
COMPILE_ASSERT_TYPES_EQ(const volatile int *,
GOOGLE_NAMESPACE::remove_cv<const volatile int *>::type);
COMPILE_ASSERT_TYPES_EQ(int,
GOOGLE_NAMESPACE::remove_cv<const volatile int>::type);
}
static void TestIsConvertible() {
#ifndef _MSC_VER
ASSERT_TRUE((GOOGLE_NAMESPACE::is_convertible<int, int>::value));
ASSERT_TRUE((GOOGLE_NAMESPACE::is_convertible<int, long>::value));
ASSERT_TRUE((GOOGLE_NAMESPACE::is_convertible<long, int>::value));
ASSERT_TRUE((GOOGLE_NAMESPACE::is_convertible<int*, void*>::value));
ASSERT_FALSE((GOOGLE_NAMESPACE::is_convertible<void*, int*>::value));
ASSERT_TRUE((GOOGLE_NAMESPACE::is_convertible<Derived*, Base*>::value));
ASSERT_FALSE((GOOGLE_NAMESPACE::is_convertible<Base*, Derived*>::value));
ASSERT_TRUE((GOOGLE_NAMESPACE::is_convertible<Derived*, const Base*>::value));
ASSERT_FALSE((GOOGLE_NAMESPACE::is_convertible<const Derived*, Base*>::value));
#endif // #ifdef MSC_VER
}
}; // end class TypeTraitsTest
} // end anonymous namespace
int main(int argc, char **argv) {
TypeTraitsTest::TestIsInteger();
TypeTraitsTest::TestIsFloating();
TypeTraitsTest::TestIsReference();
TypeTraitsTest::TestIsPod();
TypeTraitsTest::TestHasTrivialCopy();
TypeTraitsTest::TestHasTrivialConstructor();
TypeTraitsTest::TestHasTrivialAssign();
TypeTraitsTest::TestHasTrivialDestructor();
TypeTraitsTest::TestRemovePointer();
TypeTraitsTest::TestRemoveConst();
TypeTraitsTest::TestRemoveVolatile();
TypeTraitsTest::TestRemoveReference();
TypeTraitsTest::TestRemoveCV();
TypeTraitsTest::TestIsConvertible();
printf("PASS\n");
return 0;
}

View File

@ -1,149 +0,0 @@
#ifndef GOOGLE_SPARSEHASH_WINDOWS_CONFIG_H_
#define GOOGLE_SPARSEHASH_WINDOWS_CONFIG_H_
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Namespace for Google classes */
#define GOOGLE_NAMESPACE ::google
/* the location of the header defining hash functions */
#define HASH_FUN_H <hash_map>
/* the location of <unordered_map> or <hash_map> */
#define HASH_MAP_H <hash_map>
/* the namespace of the hash<> function */
#define HASH_NAMESPACE stdext
/* the location of <unordered_set> or <hash_set> */
#define HASH_SET_H <hash_set>
/* Define to 1 if you have the <google/malloc_extension.h> header file. */
#undef HAVE_GOOGLE_MALLOC_EXTENSION_H
/* define if the compiler has hash_map */
#define HAVE_HASH_MAP 1
/* define if the compiler has hash_set */
#define HAVE_HASH_SET 1
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if the system has the type `long long'. */
#define HAVE_LONG_LONG 1
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES 1
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/utsname.h> header file. */
#undef HAVE_SYS_UTSNAME_H
/* Define to 1 if the system has the type `uint16_t'. */
#undef HAVE_UINT16_T
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* define if the compiler supports unordered_{map,set} */
#undef HAVE_UNORDERED_MAP
/* Define to 1 if the system has the type `u_int16_t'. */
#undef HAVE_U_INT16_T
/* Define to 1 if the system has the type `__uint16'. */
#define HAVE___UINT16 1
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* The system-provided hash function including the namespace. */
#define SPARSEHASH_HASH HASH_NAMESPACE::hash_compare
/* The system-provided hash function, in namespace HASH_NAMESPACE. */
#define SPARSEHASH_HASH_NO_NAMESPACE hash_compare
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* the namespace where STL code like vector<> is defined */
#define STL_NAMESPACE std
/* Version number of package */
#undef VERSION
/* Stops putting the code inside the Google namespace */
#define _END_GOOGLE_NAMESPACE_ }
/* Puts following code inside the Google namespace */
#define _START_GOOGLE_NAMESPACE_ namespace google {
// ---------------------------------------------------------------------
// Extra stuff not found in config.h.in
#define HAVE_WINDOWS_H 1 // used in time_hash_map
// This makes sure the definitions in config.h and sparseconfig.h match
// up. If they don't, the compiler will complain about redefinition.
#include <google/sparsehash/sparseconfig.h>
// TODO(csilvers): include windows/port.h in every relevant source file instead?
#include "windows/port.h"
#endif /* GOOGLE_SPARSEHASH_WINDOWS_CONFIG_H_ */

View File

@ -1,32 +0,0 @@
#ifndef SPARSEHASH_WINDOWS_SPARSECONFIG_H_
#define SPARSEHASH_WINDOWS_SPARSECONFIG_H_
/***
*** These are #defines that autoheader puts in config.h.in that we
*** want to show up in sparseconfig.h, the minimal config.h file
*** #included by all our .h files. The reason we don't take
*** everything that autoheader emits is that we have to include a
*** config.h in installed header files, and we want to minimize the
*** number of #defines we make so as to not pollute the namespace.
***/
/* NOTE: these are for internal use only. Don't use these
* #defines in your own programs!
*/
#define GOOGLE_NAMESPACE ::google
#define HASH_NAMESPACE stdext
#define HASH_FUN_H <hash_map>
#define SPARSEHASH_HASH HASH_NAMESPACE::hash_compare
#undef HAVE_UINT16_T
#undef HAVE_U_INT16_T
#define HAVE___UINT16 1
#define HAVE_LONG_LONG 1
#define HAVE_SYS_TYPES_H 1
#undef HAVE_STDINT_H
#undef HAVE_INTTYPES_H
#define HAVE_MEMCPY 1
#define STL_NAMESPACE std
#define _END_GOOGLE_NAMESPACE_ }
#define _START_GOOGLE_NAMESPACE_ namespace google {
#endif /* SPARSEHASH_WINDOWS_SPARSECONFIG_H_ */

View File

@ -1,63 +0,0 @@
/* Copyright (c) 2007, Google Inc.
* 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 Google Inc. nor the names of its
* 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.
*
* ---
* Author: Craig Silverstein
*/
#ifndef WIN32
# error You should only be including windows/port.cc in a windows environment!
#endif
#include "config.h"
#include <stdarg.h> // for va_list, va_start, va_end
#include "port.h"
// Calls the windows _vsnprintf, but always NUL-terminate.
int snprintf(char *str, size_t size, const char *format, ...) {
if (size == 0) // not even room for a \0?
return -1; // not what C99 says to do, but what windows does
str[size-1] = '\0';
va_list ap;
va_start(ap, format);
const int r = _vsnprintf(str, size-1, format, ap);
va_end(ap);
return r;
}
std::string TmpFile(const char* basename) {
char tmppath_buffer[1024];
int tmppath_len = GetTempPathA(sizeof(tmppath_buffer), tmppath_buffer);
if (tmppath_len <= 0 || tmppath_len >= sizeof(tmppath_buffer)) {
return basename; // an error, so just bail on tmppath
}
snprintf(tmppath_buffer + tmppath_len, sizeof(tmppath_buffer) - tmppath_len,
"\\%s", basename);
return tmppath_buffer;
}

View File

@ -1,81 +0,0 @@
/* Copyright (c) 2007, Google Inc.
* 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 Google Inc. nor the names of its
* 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.
*
* ---
* Author: Craig Silverstein
*
* These are some portability typedefs and defines to make it a bit
* easier to compile this code -- in particular, unittests -- under VC++.
* Other portability code is found in windows/google/sparsehash/sparseconfig.h.
*
* Several of these are taken from glib:
* http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
*/
#ifndef SPARSEHASH_WINDOWS_PORT_H_
#define SPARSEHASH_WINDOWS_PORT_H_
#include "config.h"
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN /* We always want minimal includes */
#include <windows.h>
#include <io.h> /* because we so often use open/close/etc */
#include <string>
// 4996: Yes, we're ok using the "unsafe" functions like _vsnprintf and fopen
// 4127: We use "while (1)" sometimes: yes, we know it's a constant
#pragma warning(disable:4996 4127)
// file I/O
#define PATH_MAX 1024
#define access _access
#define getcwd _getcwd
#define open _open
#define read _read
#define write _write
#define lseek _lseek
#define close _close
#define unlink _unlink
#define popen _popen
#define pclose _pclose
#define strdup _strdup
// We can't just use _snprintf as a drop-in replacement, because it
// doesn't always NUL-terminate. :-(
extern int snprintf(char *str, size_t size, const char *format, ...);
extern std::string TmpFile(const char* basename); // used in hashtable_unittest
#endif /* WIN32 */
#endif /* SPARSEHASH_WINDOWS_PORT_H_ */

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,185 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="hashtable_unittest"
ProjectGUID="{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/hashtable_unittest.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/hashtable_unittest.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/hashtable_unittest.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\src\hashtable_unittest.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\windows\port.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\..\src\windows\config.h">
</File>
<File
RelativePath="..\..\src\google\dense_hash_map">
</File>
<File
RelativePath="..\..\src\google\dense_hash_set">
</File>
<File
RelativePath="..\..\src\google\sparsehash\densehashtable.h">
</File>
<File
RelativePath="..\..\src\windows\port.h">
</File>
<File
RelativePath="..\..\src\google\sparse_hash_map">
</File>
<File
RelativePath="..\..\src\google\sparse_hash_set">
</File>
<File
RelativePath="..\..\src\windows\google\sparsehash\sparseconfig.h">
</File>
<File
RelativePath="..\..\src\google\sparsehash\sparsehashtable.h">
</File>
<File
RelativePath="..\..\src\google\sparsetable">
</File>
<File
RelativePath="..\..\src\google\type_traits.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,170 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="sparsetable_unittest"
ProjectGUID="{E420867B-8BFA-4739-99EC-E008AB762FF9}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/sparsetable_unittest.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/sparsetable_unittest.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/sparsetable_unittest.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\src\windows\port.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\sparsetable_unittest.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\..\src\windows\config.h">
</File>
<File
RelativePath="..\..\src\windows\port.h">
</File>
<File
RelativePath="..\..\src\windows\google\sparsehash\sparseconfig.h">
</File>
<File
RelativePath="..\..\src\google\sparsehash\sparsehashtable.h">
</File>
<File
RelativePath="..\..\src\google\sparsetable">
</File>
<File
RelativePath="..\..\src\google\type_traits.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,185 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="time_hash_map"
ProjectGUID="{A74E5DB8-5295-487A-AB1D-23859F536F45}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/time_hash_map.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/time_hash_map.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/time_hash_map.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\src\windows\port.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\time_hash_map.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\..\src\windows\config.h">
</File>
<File
RelativePath="..\..\src\google\dense_hash_map">
</File>
<File
RelativePath="..\..\src\google\dense_hash_set">
</File>
<File
RelativePath="..\..\src\google\sparsehash\densehashtable.h">
</File>
<File
RelativePath="..\..\src\windows\port.h">
</File>
<File
RelativePath="..\..\src\google\sparse_hash_map">
</File>
<File
RelativePath="..\..\src\google\sparse_hash_set">
</File>
<File
RelativePath="..\..\src\windows\google\sparsehash\sparseconfig.h">
</File>
<File
RelativePath="..\..\src\google\sparsehash\sparsehashtable.h">
</File>
<File
RelativePath="..\..\src\google\sparsetable">
</File>
<File
RelativePath="..\..\src\google\type_traits.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,167 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="type_traits_unittest"
ProjectGUID="{008CCFED-7D7B-46F8-8E13-03837A2258B3}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/type_traits_unittest.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/type_traits_unittest.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/type_traits_unittest.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\src\windows\port.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\type_traits_unittest.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\..\src\windows\config.h">
</File>
<File
RelativePath="..\..\src\windows\port.h">
</File>
<File
RelativePath="..\..\src\windows\google\sparsehash\sparseconfig.h">
</File>
<File
RelativePath="..\..\src\google\sparsetable">
</File>
<File
RelativePath="..\..\src\google\type_traits.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>