google_hash 0.8.1 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/ChangeLog.txt +2 -0
  2. data/VERSION +1 -1
  3. data/ext/clean.bat +0 -0
  4. data/ext/clean.sh +4 -0
  5. data/ext/extconf.rb +4 -5
  6. data/ext/go.bat +0 -0
  7. data/ext/sparsehash-2.0.2/AUTHORS +2 -0
  8. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/COPYING +0 -0
  9. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/ChangeLog +60 -0
  10. data/ext/sparsehash-2.0.2/INSTALL +365 -0
  11. data/ext/sparsehash-2.0.2/Makefile +1336 -0
  12. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/Makefile.am +97 -40
  13. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/Makefile.in +538 -256
  14. data/ext/sparsehash-2.0.2/NEWS +188 -0
  15. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/README +4 -10
  16. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/README_windows.txt +3 -3
  17. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/TODO +0 -0
  18. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/aclocal.m4 +266 -166
  19. data/ext/sparsehash-2.0.2/allocator.patch +31 -0
  20. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/config.guess +235 -234
  21. data/ext/sparsehash-2.0.2/config.status +1238 -0
  22. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/config.sub +198 -64
  23. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/configure +1118 -1000
  24. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/configure.ac +4 -5
  25. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/depcomp +136 -36
  26. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/dense_hash_map.html +182 -67
  27. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/dense_hash_set.html +173 -74
  28. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/designstyle.css +0 -6
  29. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/implementation.html +0 -0
  30. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/index.html +4 -5
  31. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/performance.html +1 -1
  32. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/sparse_hash_map.html +190 -58
  33. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/sparse_hash_set.html +180 -65
  34. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/sparsetable.html +1 -1
  35. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/Makefile +0 -0
  36. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/README +0 -0
  37. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/example.c +1 -0
  38. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/libchash.c +1 -0
  39. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/libchash.h +1 -0
  40. data/ext/sparsehash-2.0.2/install-sh +520 -0
  41. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/acx_pthread.m4 +34 -0
  42. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/google_namespace.m4 +0 -0
  43. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/namespaces.m4 +0 -0
  44. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/stl_hash.m4 +0 -0
  45. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/stl_hash_fun.m4 +0 -0
  46. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/missing +60 -44
  47. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb.sh +0 -0
  48. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/README +0 -0
  49. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/changelog +42 -0
  50. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/compat +0 -0
  51. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/control +1 -1
  52. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/copyright +5 -4
  53. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/docs +0 -0
  54. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/rules +0 -0
  55. data/ext/sparsehash-2.0.2/packages/deb/sparsehash.dirs +5 -0
  56. data/ext/sparsehash-2.0.2/packages/deb/sparsehash.install +6 -0
  57. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/rpm.sh +1 -1
  58. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/rpm/rpm.spec +5 -3
  59. data/ext/{sparsehash-1.8.1/google-sparsehash.sln → sparsehash-2.0.2/sparsehash.sln} +0 -0
  60. data/ext/sparsehash-2.0.2/src/config.h +132 -0
  61. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/config.h.in +0 -3
  62. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/config.h.include +0 -1
  63. data/ext/sparsehash-2.0.2/src/google/dense_hash_map +34 -0
  64. data/ext/sparsehash-2.0.2/src/google/dense_hash_set +34 -0
  65. data/ext/sparsehash-2.0.2/src/google/sparse_hash_map +34 -0
  66. data/ext/sparsehash-2.0.2/src/google/sparse_hash_set +34 -0
  67. data/ext/sparsehash-2.0.2/src/google/sparsehash/densehashtable.h +34 -0
  68. data/ext/sparsehash-2.0.2/src/google/sparsehash/hashtable-common.h +34 -0
  69. data/ext/sparsehash-2.0.2/src/google/sparsehash/libc_allocator_with_realloc.h +34 -0
  70. data/ext/sparsehash-2.0.2/src/google/sparsehash/sparsehashtable.h +34 -0
  71. data/ext/sparsehash-2.0.2/src/google/sparsetable +34 -0
  72. data/ext/sparsehash-2.0.2/src/google/template_util.h +34 -0
  73. data/ext/sparsehash-2.0.2/src/google/type_traits.h +34 -0
  74. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/hash_test_interface.h +64 -37
  75. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/hashtable_test.cc +415 -141
  76. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/libc_allocator_with_realloc_test.cc +16 -23
  77. data/ext/sparsehash-2.0.2/src/simple_compat_test.cc +106 -0
  78. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/simple_test.cc +8 -5
  79. data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/dense_hash_map +80 -37
  80. data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/dense_hash_set +64 -34
  81. data/ext/{sparsehash-1.8.1/src/google/sparsehash → sparsehash-2.0.2/src/sparsehash/internal}/densehashtable.h +247 -173
  82. data/ext/sparsehash-2.0.2/src/sparsehash/internal/hashtable-common.h +381 -0
  83. data/ext/{sparsehash-1.8.1/src/google/sparsehash → sparsehash-2.0.2/src/sparsehash/internal}/libc_allocator_with_realloc.h +5 -7
  84. data/ext/{sparsehash-1.8.1/src/google/sparsehash → sparsehash-2.0.2/src/sparsehash/internal}/sparsehashtable.h +154 -93
  85. data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/sparse_hash_map +96 -36
  86. data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/sparse_hash_set +85 -32
  87. data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/sparsetable +520 -258
  88. data/ext/sparsehash-2.0.2/src/sparsehash/template_util.h +134 -0
  89. data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/type_traits.h +153 -35
  90. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/sparsetable_unittest.cc +108 -22
  91. data/ext/sparsehash-2.0.2/src/stamp-h1 +1 -0
  92. data/ext/sparsehash-2.0.2/src/template_util_unittest.cc +134 -0
  93. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/testutil.h +16 -1
  94. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/time_hash_map.cc +259 -94
  95. data/ext/sparsehash-2.0.2/src/type_traits_unittest.cc +636 -0
  96. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/windows/config.h +4 -4
  97. data/ext/sparsehash-2.0.2/src/windows/google/sparsehash/sparseconfig.h +49 -0
  98. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/windows/port.cc +1 -0
  99. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/windows/port.h +4 -13
  100. data/ext/sparsehash-2.0.2/src/windows/sparsehash/internal/sparseconfig.h +49 -0
  101. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/hashtable_test/hashtable_test.vcproj +11 -11
  102. data/ext/sparsehash-2.0.2/vsprojects/libc_allocator_with_realloc_test/libc_allocator_with_realloc_test.vcproj +161 -0
  103. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/simple_test/simple_test.vcproj +10 -10
  104. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj +4 -4
  105. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/time_hash_map/time_hash_map.vcproj +10 -10
  106. data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/type_traits_unittest/type_traits_unittest.vcproj +3 -3
  107. data/ext/spec.bat +0 -0
  108. data/ext/template/google_hash.cpp.erb +6 -5
  109. metadata +106 -86
  110. data/ext/sparsehash-1.8.1/AUTHORS +0 -2
  111. data/ext/sparsehash-1.8.1/INSTALL +0 -236
  112. data/ext/sparsehash-1.8.1/NEWS +0 -71
  113. data/ext/sparsehash-1.8.1/compile +0 -99
  114. data/ext/sparsehash-1.8.1/install-sh +0 -323
  115. data/ext/sparsehash-1.8.1/m4/stl_namespace.m4 +0 -25
  116. data/ext/sparsehash-1.8.1/mkinstalldirs +0 -158
  117. data/ext/sparsehash-1.8.1/packages/deb/sparsehash.dirs +0 -2
  118. data/ext/sparsehash-1.8.1/packages/deb/sparsehash.install +0 -2
  119. data/ext/sparsehash-1.8.1/src/google/sparsehash/hashtable-common.h +0 -178
  120. data/ext/sparsehash-1.8.1/src/type_traits_unittest.cc +0 -502
  121. 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 &lt;iostream&gt;
91
- #include &lt;google/dense_hash_set&gt;
91
+ #include &lt;sparsehash/dense_hash_set&gt;
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 map, returns the index of the bucket
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>dense_hash_map</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&amp; k) const</pre>
1146
1146
 
1147
1147
  <TR>
1148
1148
  <TD VAlign=top>
1149
- <tt>bool write_metadata(FILE *fp)</tt>
1149
+ <tt>template &lt;ValueSerializer, OUTPUT&gt;
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&amp; k) const</pre>
1158
1159
 
1159
1160
  <TR>
1160
1161
  <TD VAlign=top>
1161
- <tt>bool read_metadata(FILE *fp)</tt>
1162
+ <tt>template &lt;ValueSerializer, INPUT&gt;
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&amp; k) const</pre>
1170
1172
 
1171
1173
  <TR>
1172
1174
  <TD VAlign=top>
1173
- <tt>bool write_nopointer_data(FILE *fp)</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&amp; 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&amp; 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 &lt;ValueSerializer, OUTPUT&gt;
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 &lt;ValueSerializer, INPUT&gt;
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
- Write hashtable metadata to <tt>fp</tt>. See <A HREF="#io">below</A>.
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
- Read hashtable metadata from <tt>fp</tt>. See <A HREF="#io">below</A>.
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
- Write hashtable contents to <tt>fp</tt>. This is valid only if the
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
- Read hashtable contents to <tt>fp</tt>. This is valid only if the
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 disk. Storage takes place in two steps. The first writes the
1403
- hashtable metadata. The second writes the actual data.</p>
1404
-
1405
- <p>To write a hashtable to disk, first call <tt>write_metadata()</tt>
1406
- on an open file pointer. This saves the hashtable information in a
1407
- byte-order-independent format.</p>
1408
-
1409
- <p>After the metadata has been written to disk, you must write the
1410
- actual data stored in the hash-set to disk. If both the key and data
1411
- are "simple" enough, you can do this by calling
1412
- <tt>write_nopointer_data()</tt>. "Simple" data is data that can be
1413
- safely copied to disk via <tt>fwrite()</tt>. Native C data types fall
1414
- into this category, as do structs of native C data types. Pointers
1415
- and STL objects do not.</p>
1416
-
1417
- <p>Note that <tt>write_nopointer_data()</tt> does not do any endian
1418
- conversion. Thus, it is only appropriate when you intend to read the
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
- for (dense_hash_set&lt;int*&gt;::iterator it = ht.begin();
1443
- it != ht.end(); ++it) {
1444
- const_cast&lt;int*&gt;(*it) = new int;
1445
- fread(const_cast&lt;int*&gt;(*it), sizeof(int), 1, fp);
1446
- }
1472
+ struct StringSerializer {
1473
+ bool operator()(FILE* fp, const std::string&amp; value) const {
1474
+ assert(value.length() &lt;= 255); // we only support writing small strings
1475
+ const unsigned char size = value.length();
1476
+ if (fwrite(&amp;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 &lt;= 255 chars long
1484
+ if (fread(&amp;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-&gt;assign(buf, size);
1492
+ delete[] buf;
1493
+ return true;
1494
+ }
1495
+ };
1447
1496
  </pre>
1448
1497
 
1449
- <p>Here's another example, where the item stored in the hash-set is
1450
- a C++ object with a non-trivial constructor. In this case, you must
1451
- use "placement new" to construct the object at the correct memory
1452
- location.</p>
1498
+ <p>Here is the functor being used in code (error checking omitted):</p>
1499
+ <pre>
1500
+ dense_hash_set&lt;string&gt; myset = CreateSet();
1501
+ FILE* fp = fopen("hashtable.data", "w");
1502
+ myset.serialize(StringSerializer(), fp);
1503
+ fclose(fp);
1504
+
1505
+ dense_hash_set&lt;string&gt; 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
- for (dense_hash_set&lt;ComplicatedClass&gt;::iterator it = ht.begin();
1455
- it != ht.end(); ++it) {
1456
- int ctor_arg; // ComplicatedClass takes an int as its constructor arg
1457
- fread(&ctor_arg, sizeof(int), 1, fp);
1458
- new (const_cast&lt;ComplicatedClass*&gt;(&(*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>
@@ -71,12 +71,6 @@ UL.nobullets {
71
71
  margin-left: -1em;
72
72
  }
73
73
 
74
- /*
75
- body:after {
76
- content: "Google Confidential";
77
- }
78
- */
79
-
80
74
  /* pretty printing styles. See prettify.js */
81
75
  .str { color: #080; }
82
76
  .kwd { color: #008; }
@@ -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 Package</title>
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="Google_Sparsehash_Package"></a>Google Sparsehash Package </h1>
27
+ <h1> <a name="Sparsehash_Package"></a>Sparsehash Package (formerly
28
+ Google Sparsehash) </h1>
30
29
  <br>
31
30
 
32
- <p>The Google sparsehash package consists of two hashtable
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 Google hash routines depend on a good
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 &lt;iostream&gt;
90
- #include &lt;google/sparse_hash_map&gt;
90
+ #include &lt;sparsehash/sparse_hash_map&gt;
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&amp; k) </pre>
1214
1214
 
1215
1215
  <TR>
1216
1216
  <TD VAlign=top>
1217
- <tt>bool write_metadata(FILE *fp)</tt>
1217
+ <tt>template &lt;ValueSerializer, OUTPUT&gt;
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&amp; k) </pre>
1226
1227
 
1227
1228
  <TR>
1228
1229
  <TD VAlign=top>
1229
- <tt>bool read_metadata(FILE *fp)</tt>
1230
+ <tt>template &lt;ValueSerializer, INPUT&gt;
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&amp; k) </pre>
1238
1240
 
1239
1241
  <TR>
1240
1242
  <TD VAlign=top>
1241
- <tt>bool write_nopointer_data(FILE *fp)</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&amp; 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&amp; 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 &lt;ValueSerializer, OUTPUT&gt;
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 &lt;ValueSerializer, INPUT&gt;
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
- Write hashtable metadata to <tt>fp</tt>. See <A HREF="#io">below</A>.
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
- Read hashtable metadata from <tt>fp</tt>. See <A HREF="#io">below</A>.
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
- Write hashtable contents to <tt>fp</tt>. This is valid only if the
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
- Read hashtable contents to <tt>fp</tt>. This is valid only if the
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 disk. Storage takes place in two steps. The first writes the
1492
- hashtable metadata. The second writes the actual data.</p>
1493
-
1494
- <p>To write a hashtable to disk, first call <tt>write_metadata()</tt>
1495
- on an open file pointer. This saves the hashtable information in a
1496
- byte-order-independent format.</p>
1497
-
1498
- <p>After the metadata has been written to disk, you must write the
1499
- actual data stored in the hash-map to disk. If both the key and data
1500
- are "simple" enough, you can do this by calling
1501
- <tt>write_nopointer_data()</tt>. "Simple" data is data that can be
1502
- safely copied to disk via <tt>fwrite()</tt>. Native C data types fall
1503
- into this category, as do structs of native C data types. Pointers
1504
- and STL objects do not.</p>
1505
-
1506
- <p>Note that <tt>write_nopointer_data()</tt> does not do any endian
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&lt;const int, std::string&gt;&amp; value) const {
1571
+ // Write the key. We ignore endianness for this example.
1572
+ if (fwrite(&amp;value.first, sizeof(value.first), 1, fp) != 1)
1573
+ return false;
1574
+ // Write the value.
1575
+ assert(value.second.length() &lt;= 255); // we only support writing small strings
1576
+ const unsigned char size = value.second.length();
1577
+ if (fwrite(&amp;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&lt;const int, std::string&gt;* 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&lt;int*&gt;(&amp;value-&gt;first), sizeof(value-&gt;first), 1, fp) != 1)
1587
+ return false;
1588
+ // Read the value.
1589
+ unsigned char size; // all strings are &lt;= 255 chars long
1590
+ if (fread(&amp;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-&gt;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&lt;string, int&gt; mymap = CreateMap();
1607
+ FILE* fp = fopen("hashtable.data", "w");
1608
+ mymap.serialize(StringToIntSerializer(), fp);
1609
+ fclose(fp);
1610
+
1611
+ sparse_hash_map&lt;string, int&gt; 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 cannot use <tt>write_nopointer_data()</tt> for any reason,
1511
- you can write the data yourself by iterating over the
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-&gt;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
- for (sparse_hash_map&lt;int*, ComplicatedClass&gt;::iterator it = ht.begin();
1533
- it != ht.end(); ++it) {
1534
- // The key is stored in the sparse_hash_map as a pointer
1535
- const_cast&lt;int*&gt;(it-&gt;first) = new int;
1536
- fread(const_cast&lt;int*&gt;(it-&gt;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-&gt;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>