google_hash 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog.txt +2 -0
- data/VERSION +1 -1
- data/ext/clean.bat +0 -0
- data/ext/clean.sh +4 -0
- data/ext/extconf.rb +4 -5
- data/ext/go.bat +0 -0
- data/ext/sparsehash-2.0.2/AUTHORS +2 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/COPYING +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/ChangeLog +60 -0
- data/ext/sparsehash-2.0.2/INSTALL +365 -0
- data/ext/sparsehash-2.0.2/Makefile +1336 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/Makefile.am +97 -40
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/Makefile.in +538 -256
- data/ext/sparsehash-2.0.2/NEWS +188 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/README +4 -10
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/README_windows.txt +3 -3
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/TODO +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/aclocal.m4 +266 -166
- data/ext/sparsehash-2.0.2/allocator.patch +31 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/config.guess +235 -234
- data/ext/sparsehash-2.0.2/config.status +1238 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/config.sub +198 -64
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/configure +1118 -1000
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/configure.ac +4 -5
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/depcomp +136 -36
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/dense_hash_map.html +182 -67
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/dense_hash_set.html +173 -74
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/designstyle.css +0 -6
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/implementation.html +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/index.html +4 -5
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/performance.html +1 -1
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/sparse_hash_map.html +190 -58
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/sparse_hash_set.html +180 -65
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/sparsetable.html +1 -1
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/Makefile +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/README +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/example.c +1 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/libchash.c +1 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/libchash.h +1 -0
- data/ext/sparsehash-2.0.2/install-sh +520 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/acx_pthread.m4 +34 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/google_namespace.m4 +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/namespaces.m4 +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/stl_hash.m4 +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/stl_hash_fun.m4 +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/missing +60 -44
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb.sh +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/README +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/changelog +42 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/compat +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/control +1 -1
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/copyright +5 -4
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/docs +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/rules +0 -0
- data/ext/sparsehash-2.0.2/packages/deb/sparsehash.dirs +5 -0
- data/ext/sparsehash-2.0.2/packages/deb/sparsehash.install +6 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/rpm.sh +1 -1
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/rpm/rpm.spec +5 -3
- data/ext/{sparsehash-1.8.1/google-sparsehash.sln → sparsehash-2.0.2/sparsehash.sln} +0 -0
- data/ext/sparsehash-2.0.2/src/config.h +132 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/config.h.in +0 -3
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/config.h.include +0 -1
- data/ext/sparsehash-2.0.2/src/google/dense_hash_map +34 -0
- data/ext/sparsehash-2.0.2/src/google/dense_hash_set +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparse_hash_map +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparse_hash_set +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparsehash/densehashtable.h +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparsehash/hashtable-common.h +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparsehash/libc_allocator_with_realloc.h +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparsehash/sparsehashtable.h +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparsetable +34 -0
- data/ext/sparsehash-2.0.2/src/google/template_util.h +34 -0
- data/ext/sparsehash-2.0.2/src/google/type_traits.h +34 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/hash_test_interface.h +64 -37
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/hashtable_test.cc +415 -141
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/libc_allocator_with_realloc_test.cc +16 -23
- data/ext/sparsehash-2.0.2/src/simple_compat_test.cc +106 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/simple_test.cc +8 -5
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/dense_hash_map +80 -37
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/dense_hash_set +64 -34
- data/ext/{sparsehash-1.8.1/src/google/sparsehash → sparsehash-2.0.2/src/sparsehash/internal}/densehashtable.h +247 -173
- data/ext/sparsehash-2.0.2/src/sparsehash/internal/hashtable-common.h +381 -0
- data/ext/{sparsehash-1.8.1/src/google/sparsehash → sparsehash-2.0.2/src/sparsehash/internal}/libc_allocator_with_realloc.h +5 -7
- data/ext/{sparsehash-1.8.1/src/google/sparsehash → sparsehash-2.0.2/src/sparsehash/internal}/sparsehashtable.h +154 -93
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/sparse_hash_map +96 -36
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/sparse_hash_set +85 -32
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/sparsetable +520 -258
- data/ext/sparsehash-2.0.2/src/sparsehash/template_util.h +134 -0
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/type_traits.h +153 -35
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/sparsetable_unittest.cc +108 -22
- data/ext/sparsehash-2.0.2/src/stamp-h1 +1 -0
- data/ext/sparsehash-2.0.2/src/template_util_unittest.cc +134 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/testutil.h +16 -1
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/time_hash_map.cc +259 -94
- data/ext/sparsehash-2.0.2/src/type_traits_unittest.cc +636 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/windows/config.h +4 -4
- data/ext/sparsehash-2.0.2/src/windows/google/sparsehash/sparseconfig.h +49 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/windows/port.cc +1 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/windows/port.h +4 -13
- data/ext/sparsehash-2.0.2/src/windows/sparsehash/internal/sparseconfig.h +49 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/hashtable_test/hashtable_test.vcproj +11 -11
- data/ext/sparsehash-2.0.2/vsprojects/libc_allocator_with_realloc_test/libc_allocator_with_realloc_test.vcproj +161 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/simple_test/simple_test.vcproj +10 -10
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj +4 -4
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/time_hash_map/time_hash_map.vcproj +10 -10
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/type_traits_unittest/type_traits_unittest.vcproj +3 -3
- data/ext/spec.bat +0 -0
- data/ext/template/google_hash.cpp.erb +6 -5
- metadata +106 -86
- data/ext/sparsehash-1.8.1/AUTHORS +0 -2
- data/ext/sparsehash-1.8.1/INSTALL +0 -236
- data/ext/sparsehash-1.8.1/NEWS +0 -71
- data/ext/sparsehash-1.8.1/compile +0 -99
- data/ext/sparsehash-1.8.1/install-sh +0 -323
- data/ext/sparsehash-1.8.1/m4/stl_namespace.m4 +0 -25
- data/ext/sparsehash-1.8.1/mkinstalldirs +0 -158
- data/ext/sparsehash-1.8.1/packages/deb/sparsehash.dirs +0 -2
- data/ext/sparsehash-1.8.1/packages/deb/sparsehash.install +0 -2
- data/ext/sparsehash-1.8.1/src/google/sparsehash/hashtable-common.h +0 -178
- data/ext/sparsehash-1.8.1/src/type_traits_unittest.cc +0 -502
- data/ext/sparsehash-1.8.1/src/windows/google/sparsehash/sparseconfig.h +0 -32
|
@@ -88,7 +88,7 @@ details.)
|
|
|
88
88
|
|
|
89
89
|
<pre>
|
|
90
90
|
#include <iostream>
|
|
91
|
-
#include <
|
|
91
|
+
#include <sparsehash/dense_hash_set>
|
|
92
92
|
|
|
93
93
|
using google::dense_hash_set; // namespace where class lives by default
|
|
94
94
|
using std::cout;
|
|
@@ -590,7 +590,7 @@ None.
|
|
|
590
590
|
<tt>Unordered Associative Container</tt> (tr1)
|
|
591
591
|
</TD>
|
|
592
592
|
<TD VAlign=top>
|
|
593
|
-
If the key exists in the
|
|
593
|
+
If the key exists in the set, returns the index of the bucket
|
|
594
594
|
containing the given key, otherwise, return the bucket the key
|
|
595
595
|
would be inserted into.
|
|
596
596
|
This value may be passed to <tt>begin(size_type)</tt> and
|
|
@@ -1094,7 +1094,7 @@ void insert(InputIterator f, InputIterator l) </pre> <A href="#1">[2]</A>
|
|
|
1094
1094
|
<tt>void clear_no_resize()</tt>
|
|
1095
1095
|
</TD>
|
|
1096
1096
|
<TD VAlign=top>
|
|
1097
|
-
<tt>
|
|
1097
|
+
<tt>dense_hash_set</tt>
|
|
1098
1098
|
</TD>
|
|
1099
1099
|
<TD VAlign=top>
|
|
1100
1100
|
<A HREF="#new">See below</A>.
|
|
@@ -1146,7 +1146,8 @@ key_type& k) const</pre>
|
|
|
1146
1146
|
|
|
1147
1147
|
<TR>
|
|
1148
1148
|
<TD VAlign=top>
|
|
1149
|
-
<tt>
|
|
1149
|
+
<tt>template <ValueSerializer, OUTPUT>
|
|
1150
|
+
bool serialize(ValueSerializer serializer, OUTPUT *fp)</tt>
|
|
1150
1151
|
</TD>
|
|
1151
1152
|
<TD VAlign=top>
|
|
1152
1153
|
<tt>dense_hash_set</tt>
|
|
@@ -1158,7 +1159,8 @@ key_type& k) const</pre>
|
|
|
1158
1159
|
|
|
1159
1160
|
<TR>
|
|
1160
1161
|
<TD VAlign=top>
|
|
1161
|
-
<tt>
|
|
1162
|
+
<tt>template <ValueSerializer, INPUT>
|
|
1163
|
+
bool unserialize(ValueSerializer serializer, INPUT *fp)</tt>
|
|
1162
1164
|
</TD>
|
|
1163
1165
|
<TD VAlign=top>
|
|
1164
1166
|
<tt>dense_hash_set</tt>
|
|
@@ -1170,7 +1172,7 @@ key_type& k) const</pre>
|
|
|
1170
1172
|
|
|
1171
1173
|
<TR>
|
|
1172
1174
|
<TD VAlign=top>
|
|
1173
|
-
<tt>
|
|
1175
|
+
<tt>NopointerSerializer</tt>
|
|
1174
1176
|
</TD>
|
|
1175
1177
|
<TD VAlign=top>
|
|
1176
1178
|
<tt>dense_hash_set</tt>
|
|
@@ -1180,6 +1182,42 @@ key_type& k) const</pre>
|
|
|
1180
1182
|
</TD>
|
|
1181
1183
|
</TR>
|
|
1182
1184
|
|
|
1185
|
+
<TR>
|
|
1186
|
+
<TD VAlign=top>
|
|
1187
|
+
<tt>bool write_metadata(FILE *fp)</tt>
|
|
1188
|
+
</TD>
|
|
1189
|
+
<TD VAlign=top>
|
|
1190
|
+
<tt>dense_hash_set</tt>
|
|
1191
|
+
</TD>
|
|
1192
|
+
<TD VAlign=top>
|
|
1193
|
+
DEPRECATED. <A HREF="#new">See below</A>.
|
|
1194
|
+
</TD>
|
|
1195
|
+
</TR>
|
|
1196
|
+
|
|
1197
|
+
<TR>
|
|
1198
|
+
<TD VAlign=top>
|
|
1199
|
+
<tt>bool read_metadata(FILE *fp)</tt>
|
|
1200
|
+
</TD>
|
|
1201
|
+
<TD VAlign=top>
|
|
1202
|
+
<tt>dense_hash_set</tt>
|
|
1203
|
+
</TD>
|
|
1204
|
+
<TD VAlign=top>
|
|
1205
|
+
DEPRECATED. <A HREF="#new">See below</A>.
|
|
1206
|
+
</TD>
|
|
1207
|
+
</TR>
|
|
1208
|
+
|
|
1209
|
+
<TR>
|
|
1210
|
+
<TD VAlign=top>
|
|
1211
|
+
<tt>bool write_nopointer_data(FILE *fp)</tt>
|
|
1212
|
+
</TD>
|
|
1213
|
+
<TD VAlign=top>
|
|
1214
|
+
<tt>dense_hash_set</tt>
|
|
1215
|
+
</TD>
|
|
1216
|
+
<TD VAlign=top>
|
|
1217
|
+
DEPRECATED. <A HREF="#new">See below</A>.
|
|
1218
|
+
</TD>
|
|
1219
|
+
</TR>
|
|
1220
|
+
|
|
1183
1221
|
<TR>
|
|
1184
1222
|
<TD VAlign=top>
|
|
1185
1223
|
<tt>bool read_nopointer_data(FILE *fp)</tt>
|
|
@@ -1188,7 +1226,7 @@ key_type& k) const</pre>
|
|
|
1188
1226
|
<tt>dense_hash_set</tt>
|
|
1189
1227
|
</TD>
|
|
1190
1228
|
<TD VAlign=top>
|
|
1191
|
-
<A HREF="#new">See below</A>.
|
|
1229
|
+
DEPRECATED. <A HREF="#new">See below</A>.
|
|
1192
1230
|
</TD>
|
|
1193
1231
|
</TR>
|
|
1194
1232
|
|
|
@@ -1279,12 +1317,35 @@ Container</tt> requirements, but are specific to
|
|
|
1279
1317
|
</TD>
|
|
1280
1318
|
</TR>
|
|
1281
1319
|
|
|
1320
|
+
<TR>
|
|
1321
|
+
<TD VAlign=top>
|
|
1322
|
+
<tt>template <ValueSerializer, OUTPUT>
|
|
1323
|
+
bool serialize(ValueSerializer serializer, OUTPUT *fp)</tt>
|
|
1324
|
+
</TD>
|
|
1325
|
+
<TD VAlign=top>
|
|
1326
|
+
Emit a serialization of the hash_set to a stream.
|
|
1327
|
+
See <A HREF="#io">below</A>.
|
|
1328
|
+
</TD>
|
|
1329
|
+
</TR>
|
|
1330
|
+
|
|
1331
|
+
<TR>
|
|
1332
|
+
<TD VAlign=top>
|
|
1333
|
+
<tt>template <ValueSerializer, INPUT>
|
|
1334
|
+
bool unserialize(ValueSerializer serializer, INPUT *fp)</tt>
|
|
1335
|
+
</TD>
|
|
1336
|
+
<TD VAlign=top>
|
|
1337
|
+
Read in a serialization of a hash_set from a stream, replacing the
|
|
1338
|
+
existing hash_set contents with the serialized contents.
|
|
1339
|
+
See <A HREF="#io">below</A>.
|
|
1340
|
+
</TD>
|
|
1341
|
+
</TR>
|
|
1342
|
+
|
|
1282
1343
|
<TR>
|
|
1283
1344
|
<TD VAlign=top>
|
|
1284
1345
|
<tt>bool write_metadata(FILE *fp)</tt>
|
|
1285
1346
|
</TD>
|
|
1286
1347
|
<TD VAlign=top>
|
|
1287
|
-
|
|
1348
|
+
This function is DEPRECATED. See <A HREF="#io">below</A>.
|
|
1288
1349
|
</TD>
|
|
1289
1350
|
</TR>
|
|
1290
1351
|
|
|
@@ -1293,7 +1354,7 @@ Container</tt> requirements, but are specific to
|
|
|
1293
1354
|
<tt>bool read_metadata(FILE *fp)</tt>
|
|
1294
1355
|
</TD>
|
|
1295
1356
|
<TD VAlign=top>
|
|
1296
|
-
|
|
1357
|
+
This function is DEPRECATED. See <A HREF="#io">below</A>.
|
|
1297
1358
|
</TD>
|
|
1298
1359
|
</TR>
|
|
1299
1360
|
|
|
@@ -1302,8 +1363,7 @@ Container</tt> requirements, but are specific to
|
|
|
1302
1363
|
<tt>bool write_nopointer_data(FILE *fp)</tt>
|
|
1303
1364
|
</TD>
|
|
1304
1365
|
<TD VAlign=top>
|
|
1305
|
-
|
|
1306
|
-
hashtable key and value are "plain" data. See <A HREF="#io">below</A>.
|
|
1366
|
+
This function is DEPRECATED. See <A HREF="#io">below</A>.
|
|
1307
1367
|
</TD>
|
|
1308
1368
|
</TR>
|
|
1309
1369
|
|
|
@@ -1312,8 +1372,7 @@ Container</tt> requirements, but are specific to
|
|
|
1312
1372
|
<tt>bool read_nopointer_data(FILE *fp)</tt>
|
|
1313
1373
|
</TD>
|
|
1314
1374
|
<TD VAlign=top>
|
|
1315
|
-
|
|
1316
|
-
hashtable key and value are "plain" data. See <A HREF="#io">below</A>.
|
|
1375
|
+
This function is DEPRECATED. See <A HREF="#io">below</A>.
|
|
1317
1376
|
</TD>
|
|
1318
1377
|
</TR>
|
|
1319
1378
|
|
|
@@ -1390,74 +1449,114 @@ insertion but no hashtable entries can be deleted until
|
|
|
1390
1449
|
|
|
1391
1450
|
<h3><A NAME=io>Input/Output</A></h3>
|
|
1392
1451
|
|
|
1393
|
-
<table border=1 cellpadding=5><tr><td>
|
|
1394
|
-
<p><b>IMPORTANT IMPLEMENTATION NOTE:</b> In the current version of
|
|
1395
|
-
this code, the input/output routines for <tt>dense_hash_set</tt> have
|
|
1396
|
-
<b>not yet been implemented</b>. This section explains the API, but
|
|
1397
|
-
note that all calls to these routines will fail (return
|
|
1398
|
-
<tt>false</tt>). It is a TODO to remedy this situation.</p>
|
|
1399
|
-
</td></tr></table>
|
|
1400
|
-
|
|
1401
1452
|
<p>It is possible to save and restore <tt>dense_hash_set</tt> objects
|
|
1402
|
-
to
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
<p>
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
<
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
<tt>
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
and
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
data on the same endian architecture as you write the data.</p>
|
|
1453
|
+
to an arbitrary stream (such as a disk file) using the
|
|
1454
|
+
<tt>serialize()</tt> and <tt>unserialize()</tt> methods.</p>
|
|
1455
|
+
|
|
1456
|
+
<p>Each of these methods takes two arguments: a <i>serializer</i>,
|
|
1457
|
+
which says how to write hashtable items to disk, and a <i>stream</i>,
|
|
1458
|
+
which can be a C++ stream (<tt>istream</tt> or its subclasses for
|
|
1459
|
+
input, <tt>ostream</tt> or its subclasses for output), a
|
|
1460
|
+
<tt>FILE*</tt>, or a user-defined type (as described below).</p>
|
|
1461
|
+
|
|
1462
|
+
<p>The <it>serializer</i> is a functor that takes a stream and a
|
|
1463
|
+
single hashtable element (a <tt>value_type</tt>) and copies the
|
|
1464
|
+
hashtable element to the stream (for <tt>serialize()</tt>) or fills
|
|
1465
|
+
the hashtable element contents from the stream (for
|
|
1466
|
+
<tt>unserialize()</tt>), and returns true on success or false on
|
|
1467
|
+
error. The copy-in and copy-out functions can be provided in a single
|
|
1468
|
+
functor. Here is a sample serializer that read/writes a hashtable
|
|
1469
|
+
element for a string hash_set to a <tt>FILE*</tt>:</p>
|
|
1420
1470
|
|
|
1421
|
-
<p>If you cannot use <tt>write_nopointer_data()</tt> for any reason,
|
|
1422
|
-
you can write the data yourself by iterating over the
|
|
1423
|
-
<tt>dense_hash_set</tt> with a <tt>const_iterator</tt> and writing
|
|
1424
|
-
the key and data in any manner you wish.</p>
|
|
1425
|
-
|
|
1426
|
-
<p>To read the hashtable information from disk, first you must create
|
|
1427
|
-
a <tt>dense_hash_set</tt> object. Then open a file pointer to point
|
|
1428
|
-
to the saved hashtable, and call <tt>read_metadata()</tt>. If you
|
|
1429
|
-
saved the data via <tt>write_nopointer_data()</tt>, you can follow the
|
|
1430
|
-
<tt>read_metadata()</tt> call with a call to
|
|
1431
|
-
<tt>read_nopointer_data()</tt>. This is all that is needed.</p>
|
|
1432
|
-
|
|
1433
|
-
<p>If you saved the data through a custom write routine, you must call
|
|
1434
|
-
a custom read routine to read in the data. To do this, iterate over
|
|
1435
|
-
the <tt>dense_hash_set</tt> with an <tt>iterator</tt>; this operation
|
|
1436
|
-
is sensical because the metadata has already been set up. For each
|
|
1437
|
-
iterator item, you can read the key and value from disk, and set it
|
|
1438
|
-
appropriately. You will need to do a <tt>const_cast</tt> on the
|
|
1439
|
-
iterator, since <tt>*it</tt> is always <tt>const</tt>. The
|
|
1440
|
-
code might look like this:</p>
|
|
1441
1471
|
<pre>
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1472
|
+
struct StringSerializer {
|
|
1473
|
+
bool operator()(FILE* fp, const std::string& value) const {
|
|
1474
|
+
assert(value.length() <= 255); // we only support writing small strings
|
|
1475
|
+
const unsigned char size = value.length();
|
|
1476
|
+
if (fwrite(&size, 1, 1, fp) != 1)
|
|
1477
|
+
return false;
|
|
1478
|
+
if (fwrite(value.data(), size, 1, fp) != 1)
|
|
1479
|
+
return false;
|
|
1480
|
+
return true;
|
|
1481
|
+
}
|
|
1482
|
+
bool operator()(FILE* fp, std::string* value) const {
|
|
1483
|
+
unsigned char size; // all strings are <= 255 chars long
|
|
1484
|
+
if (fread(&size, 1, 1, fp) != 1)
|
|
1485
|
+
return false;
|
|
1486
|
+
char* buf = new char[size];
|
|
1487
|
+
if (fread(buf, size, 1, fp) != 1) {
|
|
1488
|
+
delete[] buf;
|
|
1489
|
+
return false;
|
|
1490
|
+
}
|
|
1491
|
+
value->assign(buf, size);
|
|
1492
|
+
delete[] buf;
|
|
1493
|
+
return true;
|
|
1494
|
+
}
|
|
1495
|
+
};
|
|
1447
1496
|
</pre>
|
|
1448
1497
|
|
|
1449
|
-
<p>Here
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1498
|
+
<p>Here is the functor being used in code (error checking omitted):</p>
|
|
1499
|
+
<pre>
|
|
1500
|
+
dense_hash_set<string> myset = CreateSet();
|
|
1501
|
+
FILE* fp = fopen("hashtable.data", "w");
|
|
1502
|
+
myset.serialize(StringSerializer(), fp);
|
|
1503
|
+
fclose(fp);
|
|
1504
|
+
|
|
1505
|
+
dense_hash_set<string> myset2;
|
|
1506
|
+
FILE* fp_in = fopen("hashtable.data", "r");
|
|
1507
|
+
myset2.unserialize(StringSerializer(), fp_in);
|
|
1508
|
+
fclose(fp_in);
|
|
1509
|
+
assert(myset == myset2);
|
|
1510
|
+
</pre>
|
|
1511
|
+
|
|
1512
|
+
<p>Note that this example serializer can only serialize to a FILE*.
|
|
1513
|
+
If you want to also be able to use this serializer with C++ streams,
|
|
1514
|
+
you will need to write two more overloads of <tt>operator()</tt>'s,
|
|
1515
|
+
one that reads from an <tt>istream</tt>, and one that writes to an
|
|
1516
|
+
<tt>ostream</tt>. Likewise if you want to support serializing to a
|
|
1517
|
+
custom class.</p>
|
|
1518
|
+
|
|
1519
|
+
<p>If the key is "simple" enough, you can use the pre-supplied functor
|
|
1520
|
+
<tt>NopointerSerializer</tt>. This copies the hashtable data using
|
|
1521
|
+
the equivalent of a <tt>memcpy<></tt>. Native C data types can be
|
|
1522
|
+
serialized this way, as can structs of native C data types. Pointers
|
|
1523
|
+
and STL objects cannot.</p>
|
|
1524
|
+
|
|
1525
|
+
<p>Note that <tt>NopointerSerializer()</tt> does not do any endian
|
|
1526
|
+
conversion. Thus, it is only appropriate when you intend to read the
|
|
1527
|
+
data on the same endian architecture as you write the data.</p>
|
|
1528
|
+
|
|
1529
|
+
<p>If you wish to serialize to your own stream type, you can do so by
|
|
1530
|
+
creating an object which supports two methods:</p>
|
|
1453
1531
|
<pre>
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
int ctor_arg; // ComplicatedClass takes an int as its constructor arg
|
|
1457
|
-
fread(&ctor_arg, sizeof(int), 1, fp);
|
|
1458
|
-
new (const_cast<ComplicatedClass*>(&(*it))) ComplicatedClass(ctor_arg);
|
|
1459
|
-
}
|
|
1532
|
+
bool Write(const void* data, size_t length);
|
|
1533
|
+
bool Read(void* data, size_t length);
|
|
1460
1534
|
</pre>
|
|
1535
|
+
<p><tt>Write()</tt> writes <tt>length</tt> bytes of <tt>data</tt> to a
|
|
1536
|
+
stream (presumably a stream owned by the object), while
|
|
1537
|
+
<tt>Read()</tt> reads <tt>data</tt> bytes from the stream into
|
|
1538
|
+
<tt>data</tt>. Both return true on success or false on error.</p>
|
|
1539
|
+
|
|
1540
|
+
<p>To unserialize a hashtable from a stream, you wil typically create
|
|
1541
|
+
a new <tt>dense_hash_set</tt> object, then call <tt>unserialize()</tt>
|
|
1542
|
+
on it. <tt>unserialize()</tt> destroys the old contents of the
|
|
1543
|
+
object. You must pass in the appropriate <tt>ValueSerializer</tt> for
|
|
1544
|
+
the data being read in.</p>
|
|
1545
|
+
|
|
1546
|
+
<p>Both <tt>serialize()</tt> and <tt>unserialize()</tt> return
|
|
1547
|
+
<tt>true</tt> on success, or <tt>false</tt> if there was an error
|
|
1548
|
+
streaming the data.</p>
|
|
1549
|
+
|
|
1550
|
+
<p>Note that <tt>serialize()</tt> is not a const method, since it
|
|
1551
|
+
purges deleted elements before serializing. It is not safe to
|
|
1552
|
+
serialize from two threads at once, without synchronization.</p>
|
|
1553
|
+
|
|
1554
|
+
<p>NOTE: older versions of <tt>dense_hash_set</tt> provided a
|
|
1555
|
+
different API, consisting of <tt>read_metadata()</tt>,
|
|
1556
|
+
<tt>read_nopointer_data()</tt>, <tt>write_metadata()</tt>,
|
|
1557
|
+
<tt>write_nopointer_data()</tt>. These methods were never implemented
|
|
1558
|
+
and always did nothing but return <tt>false</tt>. You should
|
|
1559
|
+
exclusively use the new API for serialization.</p>
|
|
1461
1560
|
|
|
1462
1561
|
|
|
1463
1562
|
<h3><A NAME=iter>Validity of Iterators</A></h3>
|
|
File without changes
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
|
-
<title>Google Sparsehash
|
|
4
|
+
<title>Sparsehash Package (formerly Google Sparsehash)</title>
|
|
5
5
|
|
|
6
6
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
7
|
-
<link href="http://www.google.com/favicon.ico" type="image/x-icon"
|
|
8
|
-
rel="shortcut icon">
|
|
9
7
|
<link href="designstyle.css" type="text/css" rel="stylesheet">
|
|
10
8
|
<style>
|
|
11
9
|
<!--
|
|
@@ -26,10 +24,11 @@
|
|
|
26
24
|
</head>
|
|
27
25
|
<body>
|
|
28
26
|
|
|
29
|
-
<h1> <a name="
|
|
27
|
+
<h1> <a name="Sparsehash_Package"></a>Sparsehash Package (formerly
|
|
28
|
+
Google Sparsehash) </h1>
|
|
30
29
|
<br>
|
|
31
30
|
|
|
32
|
-
<p>The
|
|
31
|
+
<p>The sparsehash package consists of two hashtable
|
|
33
32
|
implementations: <i>sparse</i>, which is designed to be very space
|
|
34
33
|
efficient, and <i>dense</i>, which is designed to be very time
|
|
35
34
|
efficient. For each one, the package provides both a hash-map and a
|
|
@@ -67,7 +67,7 @@ memory used in map_grow 236.8081 Mbytes
|
|
|
67
67
|
|
|
68
68
|
<H2><A name="hashfn">A Note on Hash Functions</A></H2>
|
|
69
69
|
|
|
70
|
-
<p>For good performance, the
|
|
70
|
+
<p>For good performance, the sparsehash hash routines depend on a good
|
|
71
71
|
hash function: one that distributes data evenly. Many hashtable
|
|
72
72
|
implementations come with sub-optimal hash functions that can degrade
|
|
73
73
|
performance. For instance, the hash function given in Knuth's _Art of
|
|
@@ -87,7 +87,7 @@ details.)
|
|
|
87
87
|
|
|
88
88
|
<pre>
|
|
89
89
|
#include <iostream>
|
|
90
|
-
#include <
|
|
90
|
+
#include <sparsehash/sparse_hash_map>
|
|
91
91
|
|
|
92
92
|
using google::sparse_hash_map; // namespace where class lives by default
|
|
93
93
|
using std::cout;
|
|
@@ -1214,7 +1214,8 @@ key_type& k) </pre>
|
|
|
1214
1214
|
|
|
1215
1215
|
<TR>
|
|
1216
1216
|
<TD VAlign=top>
|
|
1217
|
-
<tt>
|
|
1217
|
+
<tt>template <ValueSerializer, OUTPUT>
|
|
1218
|
+
bool serialize(ValueSerializer serializer, OUTPUT *fp)</tt>
|
|
1218
1219
|
</TD>
|
|
1219
1220
|
<TD VAlign=top>
|
|
1220
1221
|
<tt>sparse_hash_map</tt>
|
|
@@ -1226,7 +1227,8 @@ key_type& k) </pre>
|
|
|
1226
1227
|
|
|
1227
1228
|
<TR>
|
|
1228
1229
|
<TD VAlign=top>
|
|
1229
|
-
<tt>
|
|
1230
|
+
<tt>template <ValueSerializer, INPUT>
|
|
1231
|
+
bool unserialize(ValueSerializer serializer, INPUT *fp)</tt>
|
|
1230
1232
|
</TD>
|
|
1231
1233
|
<TD VAlign=top>
|
|
1232
1234
|
<tt>sparse_hash_map</tt>
|
|
@@ -1238,7 +1240,7 @@ key_type& k) </pre>
|
|
|
1238
1240
|
|
|
1239
1241
|
<TR>
|
|
1240
1242
|
<TD VAlign=top>
|
|
1241
|
-
<tt>
|
|
1243
|
+
<tt>NopointerSerializer</tt>
|
|
1242
1244
|
</TD>
|
|
1243
1245
|
<TD VAlign=top>
|
|
1244
1246
|
<tt>sparse_hash_map</tt>
|
|
@@ -1248,6 +1250,42 @@ key_type& k) </pre>
|
|
|
1248
1250
|
</TD>
|
|
1249
1251
|
</TR>
|
|
1250
1252
|
|
|
1253
|
+
<TR>
|
|
1254
|
+
<TD VAlign=top>
|
|
1255
|
+
<tt>bool write_metadata(FILE *fp)</tt>
|
|
1256
|
+
</TD>
|
|
1257
|
+
<TD VAlign=top>
|
|
1258
|
+
<tt>sparse_hash_map</tt>
|
|
1259
|
+
</TD>
|
|
1260
|
+
<TD VAlign=top>
|
|
1261
|
+
DEPRECATED. <A HREF="#new">See below</A>.
|
|
1262
|
+
</TD>
|
|
1263
|
+
</TR>
|
|
1264
|
+
|
|
1265
|
+
<TR>
|
|
1266
|
+
<TD VAlign=top>
|
|
1267
|
+
<tt>bool read_metadata(FILE *fp)</tt>
|
|
1268
|
+
</TD>
|
|
1269
|
+
<TD VAlign=top>
|
|
1270
|
+
<tt>sparse_hash_map</tt>
|
|
1271
|
+
</TD>
|
|
1272
|
+
<TD VAlign=top>
|
|
1273
|
+
DEPRECATED. <A HREF="#new">See below</A>.
|
|
1274
|
+
</TD>
|
|
1275
|
+
</TR>
|
|
1276
|
+
|
|
1277
|
+
<TR>
|
|
1278
|
+
<TD VAlign=top>
|
|
1279
|
+
<tt>bool write_nopointer_data(FILE *fp)</tt>
|
|
1280
|
+
</TD>
|
|
1281
|
+
<TD VAlign=top>
|
|
1282
|
+
<tt>sparse_hash_map</tt>
|
|
1283
|
+
</TD>
|
|
1284
|
+
<TD VAlign=top>
|
|
1285
|
+
DEPRECATED. <A HREF="#new">See below</A>.
|
|
1286
|
+
</TD>
|
|
1287
|
+
</TR>
|
|
1288
|
+
|
|
1251
1289
|
<TR>
|
|
1252
1290
|
<TD VAlign=top>
|
|
1253
1291
|
<tt>bool read_nopointer_data(FILE *fp)</tt>
|
|
@@ -1256,7 +1294,7 @@ key_type& k) </pre>
|
|
|
1256
1294
|
<tt>sparse_hash_map</tt>
|
|
1257
1295
|
</TD>
|
|
1258
1296
|
<TD VAlign=top>
|
|
1259
|
-
<A HREF="#new">See below</A>.
|
|
1297
|
+
DEPRECATED. <A HREF="#new">See below</A>.
|
|
1260
1298
|
</TD>
|
|
1261
1299
|
</TR>
|
|
1262
1300
|
|
|
@@ -1340,12 +1378,35 @@ href="http://www.sgi.com/tech/stl/#3">[3]</A>
|
|
|
1340
1378
|
</TD>
|
|
1341
1379
|
</TR>
|
|
1342
1380
|
|
|
1381
|
+
<TR>
|
|
1382
|
+
<TD VAlign=top>
|
|
1383
|
+
<tt>template <ValueSerializer, OUTPUT>
|
|
1384
|
+
bool serialize(ValueSerializer serializer, OUTPUT *fp)</tt>
|
|
1385
|
+
</TD>
|
|
1386
|
+
<TD VAlign=top>
|
|
1387
|
+
Emit a serialization of the hash_map to a stream.
|
|
1388
|
+
See <A HREF="#io">below</A>.
|
|
1389
|
+
</TD>
|
|
1390
|
+
</TR>
|
|
1391
|
+
|
|
1392
|
+
<TR>
|
|
1393
|
+
<TD VAlign=top>
|
|
1394
|
+
<tt>template <ValueSerializer, INPUT>
|
|
1395
|
+
bool unserialize(ValueSerializer serializer, INPUT *fp)</tt>
|
|
1396
|
+
</TD>
|
|
1397
|
+
<TD VAlign=top>
|
|
1398
|
+
Read in a serialization of a hash_map from a stream, replacing the
|
|
1399
|
+
existing hash_map contents with the serialized contents.
|
|
1400
|
+
See <A HREF="#io">below</A>.
|
|
1401
|
+
</TD>
|
|
1402
|
+
</TR>
|
|
1403
|
+
|
|
1343
1404
|
<TR>
|
|
1344
1405
|
<TD VAlign=top>
|
|
1345
1406
|
<tt>bool write_metadata(FILE *fp)</tt>
|
|
1346
1407
|
</TD>
|
|
1347
1408
|
<TD VAlign=top>
|
|
1348
|
-
|
|
1409
|
+
This function is DEPRECATED. See <A HREF="#io">below</A>.
|
|
1349
1410
|
</TD>
|
|
1350
1411
|
</TR>
|
|
1351
1412
|
|
|
@@ -1354,7 +1415,7 @@ href="http://www.sgi.com/tech/stl/#3">[3]</A>
|
|
|
1354
1415
|
<tt>bool read_metadata(FILE *fp)</tt>
|
|
1355
1416
|
</TD>
|
|
1356
1417
|
<TD VAlign=top>
|
|
1357
|
-
|
|
1418
|
+
This function is DEPRECATED. See <A HREF="#io">below</A>.
|
|
1358
1419
|
</TD>
|
|
1359
1420
|
</TR>
|
|
1360
1421
|
|
|
@@ -1363,8 +1424,7 @@ href="http://www.sgi.com/tech/stl/#3">[3]</A>
|
|
|
1363
1424
|
<tt>bool write_nopointer_data(FILE *fp)</tt>
|
|
1364
1425
|
</TD>
|
|
1365
1426
|
<TD VAlign=top>
|
|
1366
|
-
|
|
1367
|
-
hashtable key and value are "plain" data. See <A HREF="#io">below</A>.
|
|
1427
|
+
This function is DEPRECATED. See <A HREF="#io">below</A>.
|
|
1368
1428
|
</TD>
|
|
1369
1429
|
</TR>
|
|
1370
1430
|
|
|
@@ -1373,8 +1433,7 @@ href="http://www.sgi.com/tech/stl/#3">[3]</A>
|
|
|
1373
1433
|
<tt>bool read_nopointer_data(FILE *fp)</tt>
|
|
1374
1434
|
</TD>
|
|
1375
1435
|
<TD VAlign=top>
|
|
1376
|
-
|
|
1377
|
-
hashtable key and value are "plain" data. See <A HREF="#io">below</A>.
|
|
1436
|
+
This function is DEPRECATED. See <A HREF="#io">below</A>.
|
|
1378
1437
|
</TD>
|
|
1379
1438
|
</TR>
|
|
1380
1439
|
|
|
@@ -1488,58 +1547,131 @@ constructor.
|
|
|
1488
1547
|
<h3><A NAME=io>Input/Output</A></h3>
|
|
1489
1548
|
|
|
1490
1549
|
<p>It is possible to save and restore <tt>sparse_hash_map</tt> objects
|
|
1491
|
-
to
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
<p>
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
<
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
<tt>
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
and
|
|
1505
|
-
|
|
1506
|
-
|
|
1550
|
+
to an arbitrary stream (such as a disk file) using the
|
|
1551
|
+
<tt>serialize()</tt> and <tt>unserialize()</tt> methods.</p>
|
|
1552
|
+
|
|
1553
|
+
<p>Each of these methods takes two arguments: a <i>serializer</i>,
|
|
1554
|
+
which says how to write hashtable items to disk, and a <i>stream</i>,
|
|
1555
|
+
which can be a C++ stream (<tt>istream</tt> or its subclasses for
|
|
1556
|
+
input, <tt>ostream</tt> or its subclasses for output), a
|
|
1557
|
+
<tt>FILE*</tt>, or a user-defined type (as described below).</p>
|
|
1558
|
+
|
|
1559
|
+
<p>The <it>serializer</i> is a functor that takes a stream and a
|
|
1560
|
+
single hashtable element (a <tt>value_type</tt>, which is a pair of
|
|
1561
|
+
the key and data) and copies the hashtable element to the stream (for
|
|
1562
|
+
<tt>serialize()</tt>) or fills the hashtable element contents from the
|
|
1563
|
+
stream (for <tt>unserialize()</tt>), and returns true on success or
|
|
1564
|
+
false on error. The copy-in and copy-out functions can be provided in
|
|
1565
|
+
a single functor. Here is a sample serializer that read/writes a hashtable
|
|
1566
|
+
element for an int-to-string hash_map to a <tt>FILE*</tt>:</p>
|
|
1567
|
+
|
|
1568
|
+
<pre>
|
|
1569
|
+
struct StringToIntSerializer {
|
|
1570
|
+
bool operator()(FILE* fp, const std::pair<const int, std::string>& value) const {
|
|
1571
|
+
// Write the key. We ignore endianness for this example.
|
|
1572
|
+
if (fwrite(&value.first, sizeof(value.first), 1, fp) != 1)
|
|
1573
|
+
return false;
|
|
1574
|
+
// Write the value.
|
|
1575
|
+
assert(value.second.length() <= 255); // we only support writing small strings
|
|
1576
|
+
const unsigned char size = value.second.length();
|
|
1577
|
+
if (fwrite(&size, 1, 1, fp) != 1)
|
|
1578
|
+
return false;
|
|
1579
|
+
if (fwrite(value.second.data(), size, 1, fp) != 1)
|
|
1580
|
+
return false;
|
|
1581
|
+
return true;
|
|
1582
|
+
}
|
|
1583
|
+
bool operator()(FILE* fp, std::pair<const int, std::string>* value) const {
|
|
1584
|
+
// Read the key. Note the need for const_cast to get around
|
|
1585
|
+
// the fact hash_map keys are always const.
|
|
1586
|
+
if (fread(const_cast<int*>(&value->first), sizeof(value->first), 1, fp) != 1)
|
|
1587
|
+
return false;
|
|
1588
|
+
// Read the value.
|
|
1589
|
+
unsigned char size; // all strings are <= 255 chars long
|
|
1590
|
+
if (fread(&size, 1, 1, fp) != 1)
|
|
1591
|
+
return false;
|
|
1592
|
+
char* buf = new char[size];
|
|
1593
|
+
if (fread(buf, size, 1, fp) != 1) {
|
|
1594
|
+
delete[] buf;
|
|
1595
|
+
return false;
|
|
1596
|
+
}
|
|
1597
|
+
new(&value->second) string(buf, size);
|
|
1598
|
+
delete[] buf;
|
|
1599
|
+
return true;
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1602
|
+
</pre>
|
|
1603
|
+
|
|
1604
|
+
<p>Here is the functor being used in code (error checking omitted):</p>
|
|
1605
|
+
<pre>
|
|
1606
|
+
sparse_hash_map<string, int> mymap = CreateMap();
|
|
1607
|
+
FILE* fp = fopen("hashtable.data", "w");
|
|
1608
|
+
mymap.serialize(StringToIntSerializer(), fp);
|
|
1609
|
+
fclose(fp);
|
|
1610
|
+
|
|
1611
|
+
sparse_hash_map<string, int> mymap2;
|
|
1612
|
+
FILE* fp_in = fopen("hashtable.data", "r");
|
|
1613
|
+
mymap2.unserialize(StringToIntSerializer(), fp_in);
|
|
1614
|
+
fclose(fp_in);
|
|
1615
|
+
assert(mymap == mymap2);
|
|
1616
|
+
</pre>
|
|
1617
|
+
|
|
1618
|
+
<p><b>Important note:</b> the code above uses placement-new to
|
|
1619
|
+
instantiate the <tt>string</tt>. This is <i>required</i> for any
|
|
1620
|
+
non-POD type (which is why we didn't need to worry about this to read
|
|
1621
|
+
in the integer key). The value_type passed in to the unserializer
|
|
1622
|
+
points to garbage memory, so it is not safe to assign to it directly
|
|
1623
|
+
if doing so causes a destructor to be called.</p>
|
|
1624
|
+
|
|
1625
|
+
<p>Also note that this example serializer can only serialize to a
|
|
1626
|
+
FILE*. If you want to also be able to use this serializer with C++
|
|
1627
|
+
streams, you will need to write two more overloads of
|
|
1628
|
+
<tt>operator()</tt>'s, one that reads from an <tt>istream</tt>, and
|
|
1629
|
+
one that writes to an <tt>ostream</tt>. Likewise if you want to
|
|
1630
|
+
support serializing to a custom class.</p>
|
|
1631
|
+
|
|
1632
|
+
<p>If both the key and data are "simple" enough, you can use the
|
|
1633
|
+
pre-supplied functor <tt>NopointerSerializer</tt>. This copies the
|
|
1634
|
+
hashtable data using the equivalent of a <tt>memcpy<></tt>. Native C
|
|
1635
|
+
data types can be serialized this way, as can structs of native C data
|
|
1636
|
+
types. Pointers and STL objects cannot.</p>
|
|
1637
|
+
|
|
1638
|
+
<p>Note that <tt>NopointerSerializer()</tt> does not do any endian
|
|
1507
1639
|
conversion. Thus, it is only appropriate when you intend to read the
|
|
1508
1640
|
data on the same endian architecture as you write the data.</p>
|
|
1509
1641
|
|
|
1510
|
-
<p>If you
|
|
1511
|
-
|
|
1512
|
-
<tt>sparse_hash_map</tt> with a <tt>const_iterator</tt> and writing
|
|
1513
|
-
the key and data in any manner you wish.</p>
|
|
1514
|
-
|
|
1515
|
-
<p>To read the hashtable information from disk, first you must create
|
|
1516
|
-
a <tt>sparse_hash_map</tt> object. Then open a file pointer to point
|
|
1517
|
-
to the saved hashtable, and call <tt>read_metadata()</tt>. If you
|
|
1518
|
-
saved the data via <tt>write_nopointer_data()</tt>, you can follow the
|
|
1519
|
-
<tt>read_metadata()</tt> call with a call to
|
|
1520
|
-
<tt>read_nopointer_data()</tt>. This is all that is needed.</p>
|
|
1521
|
-
|
|
1522
|
-
<p>If you saved the data through a custom write routine, you must call
|
|
1523
|
-
a custom read routine to read in the data. To do this, iterate over
|
|
1524
|
-
the <tt>sparse_hash_map</tt> with an <tt>iterator</tt>; this operation
|
|
1525
|
-
is sensical because the metadata has already been set up. For each
|
|
1526
|
-
iterator item, you can read the key and value from disk, and set it
|
|
1527
|
-
appropriately. You will need to do a <tt>const_cast</tt> on the
|
|
1528
|
-
iterator, since <tt>it->first</tt> is always <tt>const</tt>. You
|
|
1529
|
-
will also need to use placement-new if the key or value is a C++
|
|
1530
|
-
object. The code might look like this:</p>
|
|
1642
|
+
<p>If you wish to serialize to your own stream type, you can do so by
|
|
1643
|
+
creating an object which supports two methods:</p>
|
|
1531
1644
|
<pre>
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
// The key is stored in the sparse_hash_map as a pointer
|
|
1535
|
-
const_cast<int*>(it->first) = new int;
|
|
1536
|
-
fread(const_cast<int*>(it->first), sizeof(int), 1, fp);
|
|
1537
|
-
// The value is a complicated C++ class that takes an int to construct
|
|
1538
|
-
int ctor_arg;
|
|
1539
|
-
fread(&ctor_arg, sizeof(int), 1, fp);
|
|
1540
|
-
new (&it->second) ComplicatedClass(ctor_arg); // "placement new"
|
|
1541
|
-
}
|
|
1645
|
+
bool Write(const void* data, size_t length);
|
|
1646
|
+
bool Read(void* data, size_t length);
|
|
1542
1647
|
</pre>
|
|
1648
|
+
<p><tt>Write()</tt> writes <tt>length</tt> bytes of <tt>data</tt> to a
|
|
1649
|
+
stream (presumably a stream owned by the object), while
|
|
1650
|
+
<tt>Read()</tt> reads <tt>data</tt> bytes from the stream into
|
|
1651
|
+
<tt>data</tt>. Both return true on success or false on error.</p>
|
|
1652
|
+
|
|
1653
|
+
<p>To unserialize a hashtable from a stream, you wil typically create
|
|
1654
|
+
a new <tt>sparse_hash_map</tt> object, then call <tt>unserialize()</tt>
|
|
1655
|
+
on it. <tt>unserialize()</tt> destroys the old contents of the
|
|
1656
|
+
object. You must pass in the appropriate <tt>ValueSerializer</tt> for
|
|
1657
|
+
the data being read in.</p>
|
|
1658
|
+
|
|
1659
|
+
<p>Both <tt>serialize()</tt> and <tt>unserialize()</tt> return
|
|
1660
|
+
<tt>true</tt> on success, or <tt>false</tt> if there was an error
|
|
1661
|
+
streaming the data.</p>
|
|
1662
|
+
|
|
1663
|
+
<p>Note that <tt>serialize()</tt> is not a const method, since it
|
|
1664
|
+
purges deleted elements before serializing. It is not safe to
|
|
1665
|
+
serialize from two threads at once, without synchronization.</p>
|
|
1666
|
+
|
|
1667
|
+
<p>NOTE: older versions of <tt>sparse_hash_map</tt> provided a
|
|
1668
|
+
different API, consisting of <tt>read_metadata()</tt>,
|
|
1669
|
+
<tt>read_nopointer_data()</tt>, <tt>write_metadata()</tt>,
|
|
1670
|
+
<tt>write_nopointer_data()</tt>. Writing to disk consisted of a call
|
|
1671
|
+
to <tt>write_metadata()</tt> followed by
|
|
1672
|
+
<tt>write_nopointer_data()</tt> (if the hash data was POD) or a custom
|
|
1673
|
+
loop over the hashtable buckets to write the data (otherwise).
|
|
1674
|
+
Reading from disk was similar. Prefer the new API for new code.</p>
|
|
1543
1675
|
|
|
1544
1676
|
|
|
1545
1677
|
<h3><A NAME=iter>Validity of Iterators</A></h3>
|