snappy 0.0.14-java → 0.2.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/main.yml +34 -0
  3. data/.github/workflows/publish.yml +34 -0
  4. data/Gemfile +4 -0
  5. data/README.md +28 -4
  6. data/Rakefile +32 -29
  7. data/ext/api.c +6 -1
  8. data/ext/extconf.rb +21 -24
  9. data/lib/snappy.rb +6 -4
  10. data/lib/snappy/hadoop.rb +22 -0
  11. data/lib/snappy/hadoop/reader.rb +62 -0
  12. data/lib/snappy/hadoop/writer.rb +51 -0
  13. data/lib/snappy/reader.rb +19 -11
  14. data/lib/snappy/shim.rb +30 -0
  15. data/lib/snappy/version.rb +3 -1
  16. data/lib/snappy/writer.rb +8 -9
  17. data/snappy.gemspec +17 -37
  18. data/test/hadoop/snappy_hadoop_reader_test.rb +115 -0
  19. data/test/hadoop/snappy_hadoop_writer_test.rb +48 -0
  20. data/test/snappy_hadoop_test.rb +26 -0
  21. data/test/snappy_reader_test.rb +148 -0
  22. data/test/snappy_test.rb +95 -0
  23. data/test/snappy_writer_test.rb +55 -0
  24. data/test/test_helper.rb +7 -0
  25. data/vendor/snappy/CMakeLists.txt +297 -0
  26. data/vendor/snappy/CONTRIBUTING.md +26 -0
  27. data/vendor/snappy/COPYING +1 -1
  28. data/vendor/snappy/NEWS +60 -0
  29. data/vendor/snappy/{README → README.md} +29 -16
  30. data/vendor/snappy/cmake/SnappyConfig.cmake.in +33 -0
  31. data/vendor/snappy/cmake/config.h.in +62 -0
  32. data/vendor/snappy/docs/README.md +72 -0
  33. data/vendor/snappy/snappy-c.h +3 -3
  34. data/vendor/snappy/snappy-internal.h +113 -32
  35. data/vendor/snappy/snappy-sinksource.cc +33 -0
  36. data/vendor/snappy/snappy-sinksource.h +51 -6
  37. data/vendor/snappy/snappy-stubs-internal.cc +1 -1
  38. data/vendor/snappy/snappy-stubs-internal.h +160 -45
  39. data/vendor/snappy/snappy-stubs-public.h.in +23 -47
  40. data/vendor/snappy/snappy-test.cc +31 -24
  41. data/vendor/snappy/snappy-test.h +46 -103
  42. data/vendor/snappy/snappy.cc +786 -431
  43. data/vendor/snappy/snappy.h +37 -14
  44. data/vendor/snappy/snappy_compress_fuzzer.cc +59 -0
  45. data/vendor/snappy/snappy_uncompress_fuzzer.cc +57 -0
  46. data/vendor/snappy/snappy_unittest.cc +441 -290
  47. metadata +35 -75
  48. data/.travis.yml +0 -4
  49. data/test/test-snappy-reader.rb +0 -129
  50. data/test/test-snappy-writer.rb +0 -55
  51. data/test/test-snappy.rb +0 -58
  52. data/vendor/snappy/ChangeLog +0 -1916
  53. data/vendor/snappy/Makefile.am +0 -23
  54. data/vendor/snappy/autogen.sh +0 -7
  55. data/vendor/snappy/configure.ac +0 -133
  56. data/vendor/snappy/m4/gtest.m4 +0 -74
  57. data/vendor/snappy/testdata/alice29.txt +0 -3609
  58. data/vendor/snappy/testdata/asyoulik.txt +0 -4122
  59. data/vendor/snappy/testdata/baddata1.snappy +0 -0
  60. data/vendor/snappy/testdata/baddata2.snappy +0 -0
  61. data/vendor/snappy/testdata/baddata3.snappy +0 -0
  62. data/vendor/snappy/testdata/fireworks.jpeg +0 -0
  63. data/vendor/snappy/testdata/geo.protodata +0 -0
  64. data/vendor/snappy/testdata/html +0 -1
  65. data/vendor/snappy/testdata/html_x_4 +0 -1
  66. data/vendor/snappy/testdata/kppkn.gtb +0 -0
  67. data/vendor/snappy/testdata/lcet10.txt +0 -7519
  68. data/vendor/snappy/testdata/paper-100k.pdf +2 -600
  69. data/vendor/snappy/testdata/plrabn12.txt +0 -10699
  70. data/vendor/snappy/testdata/urls.10K +0 -10000
@@ -36,10 +36,10 @@
36
36
  // using BMDiff and then compressing the output of BMDiff with
37
37
  // Snappy.
38
38
 
39
- #ifndef UTIL_SNAPPY_SNAPPY_H__
40
- #define UTIL_SNAPPY_SNAPPY_H__
39
+ #ifndef THIRD_PARTY_SNAPPY_SNAPPY_H__
40
+ #define THIRD_PARTY_SNAPPY_SNAPPY_H__
41
41
 
42
- #include <stddef.h>
42
+ #include <cstddef>
43
43
  #include <string>
44
44
 
45
45
  #include "snappy-stubs-public.h"
@@ -69,11 +69,12 @@ namespace snappy {
69
69
  // Higher-level string based routines (should be sufficient for most users)
70
70
  // ------------------------------------------------------------------------
71
71
 
72
- // Sets "*output" to the compressed version of "input[0,input_length-1]".
73
- // Original contents of *output are lost.
72
+ // Sets "*compressed" to the compressed version of "input[0,input_length-1]".
73
+ // Original contents of *compressed are lost.
74
74
  //
75
- // REQUIRES: "input[]" is not an alias of "*output".
76
- size_t Compress(const char* input, size_t input_length, string* output);
75
+ // REQUIRES: "input[]" is not an alias of "*compressed".
76
+ size_t Compress(const char* input, size_t input_length,
77
+ std::string* compressed);
77
78
 
78
79
  // Decompresses "compressed[0,compressed_length-1]" to "*uncompressed".
79
80
  // Original contents of "*uncompressed" are lost.
@@ -82,8 +83,20 @@ namespace snappy {
82
83
  //
83
84
  // returns false if the message is corrupted and could not be decompressed
84
85
  bool Uncompress(const char* compressed, size_t compressed_length,
85
- string* uncompressed);
86
+ std::string* uncompressed);
86
87
 
88
+ // Decompresses "compressed" to "*uncompressed".
89
+ //
90
+ // returns false if the message is corrupted and could not be decompressed
91
+ bool Uncompress(Source* compressed, Sink* uncompressed);
92
+
93
+ // This routine uncompresses as much of the "compressed" as possible
94
+ // into sink. It returns the number of valid bytes added to sink
95
+ // (extra invalid bytes may have been added due to errors; the caller
96
+ // should ignore those). The emitted data typically has length
97
+ // GetUncompressedLength(), but may be shorter if an error is
98
+ // encountered.
99
+ size_t UncompressAsMuchAsPossible(Source* compressed, Sink* uncompressed);
87
100
 
88
101
  // ------------------------------------------------------------------------
89
102
  // Lower-level character array based routines. May be useful for
@@ -164,6 +177,14 @@ namespace snappy {
164
177
  bool IsValidCompressedBuffer(const char* compressed,
165
178
  size_t compressed_length);
166
179
 
180
+ // Returns true iff the contents of "compressed" can be uncompressed
181
+ // successfully. Does not return the uncompressed data. Takes
182
+ // time proportional to *compressed length, but is usually at least
183
+ // a factor of four faster than actual decompression.
184
+ // On success, consumes all of *compressed. On failure, consumes an
185
+ // unspecified prefix of *compressed.
186
+ bool IsValidCompressed(Source* compressed);
187
+
167
188
  // The size of a compression block. Note that many parts of the compression
168
189
  // code assumes that kBlockSize <= 65536; in particular, the hash table
169
190
  // can only store 16-bit offsets, and EmitCopy() also assumes the offset
@@ -173,12 +194,14 @@ namespace snappy {
173
194
  // Note that there might be older data around that is compressed with larger
174
195
  // block sizes, so the decompression code should not rely on the
175
196
  // non-existence of long backreferences.
176
- static const int kBlockLog = 16;
177
- static const size_t kBlockSize = 1 << kBlockLog;
197
+ static constexpr int kBlockLog = 16;
198
+ static constexpr size_t kBlockSize = 1 << kBlockLog;
178
199
 
179
- static const int kMaxHashTableBits = 14;
180
- static const size_t kMaxHashTableSize = 1 << kMaxHashTableBits;
181
- } // end namespace snappy
200
+ static constexpr int kMinHashTableBits = 8;
201
+ static constexpr size_t kMinHashTableSize = 1 << kMinHashTableBits;
182
202
 
203
+ static constexpr int kMaxHashTableBits = 14;
204
+ static constexpr size_t kMaxHashTableSize = 1 << kMaxHashTableBits;
205
+ } // end namespace snappy
183
206
 
184
- #endif // UTIL_SNAPPY_SNAPPY_H__
207
+ #endif // THIRD_PARTY_SNAPPY_SNAPPY_H__
@@ -0,0 +1,59 @@
1
+ // Copyright 2019 Google Inc. All Rights Reserved.
2
+ //
3
+ // Redistribution and use in source and binary forms, with or without
4
+ // modification, are permitted provided that the following conditions are
5
+ // met:
6
+ //
7
+ // * Redistributions of source code must retain the above copyright
8
+ // notice, this list of conditions and the following disclaimer.
9
+ // * Redistributions in binary form must reproduce the above
10
+ // copyright notice, this list of conditions and the following disclaimer
11
+ // in the documentation and/or other materials provided with the
12
+ // distribution.
13
+ // * Neither the name of Google Inc. nor the names of its
14
+ // contributors may be used to endorse or promote products derived from
15
+ // this software without specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // libFuzzer harness for fuzzing snappy compression code.
30
+
31
+ #include <cassert>
32
+ #include <cstddef>
33
+ #include <cstdint>
34
+ #include <string>
35
+
36
+ #include "snappy.h"
37
+
38
+ // Entry point for LibFuzzer.
39
+ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
40
+ std::string input(reinterpret_cast<const char*>(data), size);
41
+
42
+ std::string compressed;
43
+ size_t compressed_size =
44
+ snappy::Compress(input.data(), input.size(), &compressed);
45
+
46
+ (void)compressed_size; // Variable only used in debug builds.
47
+ assert(compressed_size == compressed.size());
48
+ assert(compressed.size() <= snappy::MaxCompressedLength(input.size()));
49
+ assert(snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
50
+
51
+ std::string uncompressed_after_compress;
52
+ bool uncompress_succeeded = snappy::Uncompress(
53
+ compressed.data(), compressed.size(), &uncompressed_after_compress);
54
+
55
+ (void)uncompress_succeeded; // Variable only used in debug builds.
56
+ assert(uncompress_succeeded);
57
+ assert(input == uncompressed_after_compress);
58
+ return 0;
59
+ }
@@ -0,0 +1,57 @@
1
+ // Copyright 2019 Google Inc. All Rights Reserved.
2
+ //
3
+ // Redistribution and use in source and binary forms, with or without
4
+ // modification, are permitted provided that the following conditions are
5
+ // met:
6
+ //
7
+ // * Redistributions of source code must retain the above copyright
8
+ // notice, this list of conditions and the following disclaimer.
9
+ // * Redistributions in binary form must reproduce the above
10
+ // copyright notice, this list of conditions and the following disclaimer
11
+ // in the documentation and/or other materials provided with the
12
+ // distribution.
13
+ // * Neither the name of Google Inc. nor the names of its
14
+ // contributors may be used to endorse or promote products derived from
15
+ // this software without specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // libFuzzer harness for fuzzing snappy's decompression code.
30
+
31
+ #include <cassert>
32
+ #include <cstddef>
33
+ #include <cstdint>
34
+ #include <string>
35
+
36
+ #include "snappy.h"
37
+
38
+ // Entry point for LibFuzzer.
39
+ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
40
+ std::string input(reinterpret_cast<const char*>(data), size);
41
+
42
+ // Avoid self-crafted decompression bombs.
43
+ size_t uncompressed_size;
44
+ constexpr size_t kMaxUncompressedSize = 1 << 20;
45
+ bool get_uncompressed_length_succeeded = snappy::GetUncompressedLength(
46
+ input.data(), input.size(), &uncompressed_size);
47
+ if (!get_uncompressed_length_succeeded ||
48
+ (uncompressed_size > kMaxUncompressedSize)) {
49
+ return 0;
50
+ }
51
+
52
+ std::string uncompressed;
53
+ // The return value of snappy::Uncompress() is ignored because decompression
54
+ // will fail on invalid inputs.
55
+ snappy::Uncompress(input.data(), input.size(), &uncompressed);
56
+ return 0;
57
+ }
@@ -29,9 +29,10 @@
29
29
  #include <math.h>
30
30
  #include <stdlib.h>
31
31
 
32
-
33
32
  #include <algorithm>
33
+ #include <random>
34
34
  #include <string>
35
+ #include <utility>
35
36
  #include <vector>
36
37
 
37
38
  #include "snappy.h"
@@ -50,25 +51,19 @@ DEFINE_bool(zlib, false,
50
51
  "Run zlib compression (http://www.zlib.net)");
51
52
  DEFINE_bool(lzo, false,
52
53
  "Run LZO compression (http://www.oberhumer.com/opensource/lzo/)");
53
- DEFINE_bool(quicklz, false,
54
- "Run quickLZ compression (http://www.quicklz.com/)");
55
- DEFINE_bool(liblzf, false,
56
- "Run libLZF compression "
57
- "(http://www.goof.com/pcg/marc/liblzf.html)");
58
- DEFINE_bool(fastlz, false,
59
- "Run FastLZ compression (http://www.fastlz.org/");
60
54
  DEFINE_bool(snappy, true, "Run snappy compression");
61
55
 
62
-
63
56
  DEFINE_bool(write_compressed, false,
64
57
  "Write compressed versions of each file to <file>.comp");
65
58
  DEFINE_bool(write_uncompressed, false,
66
59
  "Write uncompressed versions of each file to <file>.uncomp");
67
60
 
68
- namespace snappy {
61
+ DEFINE_bool(snappy_dump_decompression_table, false,
62
+ "If true, we print the decompression table during tests.");
69
63
 
64
+ namespace snappy {
70
65
 
71
- #ifdef HAVE_FUNC_MMAP
66
+ #if defined(HAVE_FUNC_MMAP) && defined(HAVE_FUNC_SYSCONF)
72
67
 
73
68
  // To test against code that reads beyond its input, this class copies a
74
69
  // string to a newly allocated group of pages, the last of which
@@ -78,8 +73,8 @@ namespace snappy {
78
73
  // be able to read previously allocated memory while doing heap allocations.
79
74
  class DataEndingAtUnreadablePage {
80
75
  public:
81
- explicit DataEndingAtUnreadablePage(const string& s) {
82
- const size_t page_size = getpagesize();
76
+ explicit DataEndingAtUnreadablePage(const std::string& s) {
77
+ const size_t page_size = sysconf(_SC_PAGESIZE);
83
78
  const size_t size = s.size();
84
79
  // Round up space for string to a multiple of page_size.
85
80
  size_t space_for_string = (size + page_size - 1) & ~(page_size - 1);
@@ -97,8 +92,9 @@ class DataEndingAtUnreadablePage {
97
92
  }
98
93
 
99
94
  ~DataEndingAtUnreadablePage() {
95
+ const size_t page_size = sysconf(_SC_PAGESIZE);
100
96
  // Undo the mprotect.
101
- CHECK_EQ(0, mprotect(protected_page_, getpagesize(), PROT_READ|PROT_WRITE));
97
+ CHECK_EQ(0, mprotect(protected_page_, page_size, PROT_READ|PROT_WRITE));
102
98
  CHECK_EQ(0, munmap(mem_, alloc_size_));
103
99
  }
104
100
 
@@ -113,19 +109,19 @@ class DataEndingAtUnreadablePage {
113
109
  size_t size_;
114
110
  };
115
111
 
116
- #else // HAVE_FUNC_MMAP
112
+ #else // defined(HAVE_FUNC_MMAP) && defined(HAVE_FUNC_SYSCONF)
117
113
 
118
114
  // Fallback for systems without mmap.
119
- typedef string DataEndingAtUnreadablePage;
115
+ using DataEndingAtUnreadablePage = std::string;
120
116
 
121
117
  #endif
122
118
 
123
119
  enum CompressorType {
124
- ZLIB, LZO, LIBLZF, QUICKLZ, FASTLZ, SNAPPY
120
+ ZLIB, LZO, SNAPPY
125
121
  };
126
122
 
127
123
  const char* names[] = {
128
- "ZLIB", "LZO", "LIBLZF", "QUICKLZ", "FASTLZ", "SNAPPY"
124
+ "ZLIB", "LZO", "SNAPPY"
129
125
  };
130
126
 
131
127
  static size_t MinimumRequiredOutputSpace(size_t input_size,
@@ -141,26 +137,12 @@ static size_t MinimumRequiredOutputSpace(size_t input_size,
141
137
  return input_size + input_size/64 + 16 + 3;
142
138
  #endif // LZO_VERSION
143
139
 
144
- #ifdef LZF_VERSION
145
- case LIBLZF:
146
- return input_size;
147
- #endif // LZF_VERSION
148
-
149
- #ifdef QLZ_VERSION_MAJOR
150
- case QUICKLZ:
151
- return input_size + 36000; // 36000 is used for scratch.
152
- #endif // QLZ_VERSION_MAJOR
153
-
154
- #ifdef FASTLZ_VERSION
155
- case FASTLZ:
156
- return max(static_cast<int>(ceil(input_size * 1.05)), 66);
157
- #endif // FASTLZ_VERSION
158
-
159
140
  case SNAPPY:
160
141
  return snappy::MaxCompressedLength(input_size);
161
142
 
162
143
  default:
163
144
  LOG(FATAL) << "Unknown compression type number " << comp;
145
+ return 0;
164
146
  }
165
147
  }
166
148
 
@@ -172,7 +154,7 @@ static size_t MinimumRequiredOutputSpace(size_t input_size,
172
154
  // "compressed" must be preinitialized to at least MinCompressbufSize(comp)
173
155
  // number of bytes, and may contain junk bytes at the end after return.
174
156
  static bool Compress(const char* input, size_t input_size, CompressorType comp,
175
- string* compressed, bool compressed_is_preallocated) {
157
+ std::string* compressed, bool compressed_is_preallocated) {
176
158
  if (!compressed_is_preallocated) {
177
159
  compressed->resize(MinimumRequiredOutputSpace(input_size, comp));
178
160
  }
@@ -214,58 +196,6 @@ static bool Compress(const char* input, size_t input_size, CompressorType comp,
214
196
  }
215
197
  #endif // LZO_VERSION
216
198
 
217
- #ifdef LZF_VERSION
218
- case LIBLZF: {
219
- int destlen = lzf_compress(input,
220
- input_size,
221
- string_as_array(compressed),
222
- input_size);
223
- if (destlen == 0) {
224
- // lzf *can* cause lots of blowup when compressing, so they
225
- // recommend to limit outsize to insize, and just not compress
226
- // if it's bigger. Ideally, we'd just swap input and output.
227
- compressed->assign(input, input_size);
228
- destlen = input_size;
229
- }
230
- if (!compressed_is_preallocated) {
231
- compressed->resize(destlen);
232
- }
233
- break;
234
- }
235
- #endif // LZF_VERSION
236
-
237
- #ifdef QLZ_VERSION_MAJOR
238
- case QUICKLZ: {
239
- qlz_state_compress *state_compress = new qlz_state_compress;
240
- int destlen = qlz_compress(input,
241
- string_as_array(compressed),
242
- input_size,
243
- state_compress);
244
- delete state_compress;
245
- CHECK_NE(0, destlen);
246
- if (!compressed_is_preallocated) {
247
- compressed->resize(destlen);
248
- }
249
- break;
250
- }
251
- #endif // QLZ_VERSION_MAJOR
252
-
253
- #ifdef FASTLZ_VERSION
254
- case FASTLZ: {
255
- // Use level 1 compression since we mostly care about speed.
256
- int destlen = fastlz_compress_level(
257
- 1,
258
- input,
259
- input_size,
260
- string_as_array(compressed));
261
- if (!compressed_is_preallocated) {
262
- compressed->resize(destlen);
263
- }
264
- CHECK_NE(destlen, 0);
265
- break;
266
- }
267
- #endif // FASTLZ_VERSION
268
-
269
199
  case SNAPPY: {
270
200
  size_t destlen;
271
201
  snappy::RawCompress(input, input_size,
@@ -278,7 +208,6 @@ static bool Compress(const char* input, size_t input_size, CompressorType comp,
278
208
  break;
279
209
  }
280
210
 
281
-
282
211
  default: {
283
212
  return false; // the asked-for library wasn't compiled in
284
213
  }
@@ -286,8 +215,8 @@ static bool Compress(const char* input, size_t input_size, CompressorType comp,
286
215
  return true;
287
216
  }
288
217
 
289
- static bool Uncompress(const string& compressed, CompressorType comp,
290
- int size, string* output) {
218
+ static bool Uncompress(const std::string& compressed, CompressorType comp,
219
+ int size, std::string* output) {
291
220
  switch (comp) {
292
221
  #ifdef ZLIB_VERSION
293
222
  case ZLIB: {
@@ -321,56 +250,12 @@ static bool Uncompress(const string& compressed, CompressorType comp,
321
250
  }
322
251
  #endif // LZO_VERSION
323
252
 
324
- #ifdef LZF_VERSION
325
- case LIBLZF: {
326
- output->resize(size);
327
- int destlen = lzf_decompress(compressed.data(),
328
- compressed.size(),
329
- string_as_array(output),
330
- output->size());
331
- if (destlen == 0) {
332
- // This error probably means we had decided not to compress,
333
- // and thus have stored input in output directly.
334
- output->assign(compressed.data(), compressed.size());
335
- destlen = compressed.size();
336
- }
337
- CHECK_EQ(destlen, size);
338
- break;
339
- }
340
- #endif // LZF_VERSION
341
-
342
- #ifdef QLZ_VERSION_MAJOR
343
- case QUICKLZ: {
344
- output->resize(size);
345
- qlz_state_decompress *state_decompress = new qlz_state_decompress;
346
- int destlen = qlz_decompress(compressed.data(),
347
- string_as_array(output),
348
- state_decompress);
349
- delete state_decompress;
350
- CHECK_EQ(destlen, size);
351
- break;
352
- }
353
- #endif // QLZ_VERSION_MAJOR
354
-
355
- #ifdef FASTLZ_VERSION
356
- case FASTLZ: {
357
- output->resize(size);
358
- int destlen = fastlz_decompress(compressed.data(),
359
- compressed.length(),
360
- string_as_array(output),
361
- size);
362
- CHECK_EQ(destlen, size);
363
- break;
364
- }
365
- #endif // FASTLZ_VERSION
366
-
367
253
  case SNAPPY: {
368
254
  snappy::RawUncompress(compressed.data(), compressed.size(),
369
255
  string_as_array(output));
370
256
  break;
371
257
  }
372
258
 
373
-
374
259
  default: {
375
260
  return false; // the asked-for library wasn't compiled in
376
261
  }
@@ -392,13 +277,13 @@ static void Measure(const char* data,
392
277
  {
393
278
  // Chop the input into blocks
394
279
  int num_blocks = (length + block_size - 1) / block_size;
395
- vector<const char*> input(num_blocks);
396
- vector<size_t> input_length(num_blocks);
397
- vector<string> compressed(num_blocks);
398
- vector<string> output(num_blocks);
280
+ std::vector<const char*> input(num_blocks);
281
+ std::vector<size_t> input_length(num_blocks);
282
+ std::vector<std::string> compressed(num_blocks);
283
+ std::vector<std::string> output(num_blocks);
399
284
  for (int b = 0; b < num_blocks; b++) {
400
285
  int input_start = b * block_size;
401
- int input_limit = min<int>((b+1)*block_size, length);
286
+ int input_limit = std::min<int>((b+1)*block_size, length);
402
287
  input[b] = data+input_start;
403
288
  input_length[b] = input_limit-input_start;
404
289
 
@@ -448,35 +333,33 @@ static void Measure(const char* data,
448
333
  }
449
334
 
450
335
  compressed_size = 0;
451
- for (int i = 0; i < compressed.size(); i++) {
336
+ for (size_t i = 0; i < compressed.size(); i++) {
452
337
  compressed_size += compressed[i].size();
453
338
  }
454
339
  }
455
340
 
456
- sort(ctime, ctime + kRuns);
457
- sort(utime, utime + kRuns);
341
+ std::sort(ctime, ctime + kRuns);
342
+ std::sort(utime, utime + kRuns);
458
343
  const int med = kRuns/2;
459
344
 
460
345
  float comp_rate = (length / ctime[med]) * repeats / 1048576.0;
461
346
  float uncomp_rate = (length / utime[med]) * repeats / 1048576.0;
462
- string x = names[comp];
347
+ std::string x = names[comp];
463
348
  x += ":";
464
- string urate = (uncomp_rate >= 0)
465
- ? StringPrintf("%.1f", uncomp_rate)
466
- : string("?");
349
+ std::string urate = (uncomp_rate >= 0) ? StrFormat("%.1f", uncomp_rate)
350
+ : std::string("?");
467
351
  printf("%-7s [b %dM] bytes %6d -> %6d %4.1f%% "
468
352
  "comp %5.1f MB/s uncomp %5s MB/s\n",
469
353
  x.c_str(),
470
354
  block_size/(1<<20),
471
355
  static_cast<int>(length), static_cast<uint32>(compressed_size),
472
- (compressed_size * 100.0) / max<int>(1, length),
356
+ (compressed_size * 100.0) / std::max<int>(1, length),
473
357
  comp_rate,
474
358
  urate.c_str());
475
359
  }
476
360
 
477
-
478
- static int VerifyString(const string& input) {
479
- string compressed;
361
+ static int VerifyString(const std::string& input) {
362
+ std::string compressed;
480
363
  DataEndingAtUnreadablePage i(input);
481
364
  const size_t written = snappy::Compress(i.data(), i.size(), &compressed);
482
365
  CHECK_EQ(written, compressed.size());
@@ -484,16 +367,33 @@ static int VerifyString(const string& input) {
484
367
  snappy::MaxCompressedLength(input.size()));
485
368
  CHECK(snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
486
369
 
487
- string uncompressed;
370
+ std::string uncompressed;
488
371
  DataEndingAtUnreadablePage c(compressed);
489
372
  CHECK(snappy::Uncompress(c.data(), c.size(), &uncompressed));
490
373
  CHECK_EQ(uncompressed, input);
491
374
  return uncompressed.size();
492
375
  }
493
376
 
377
+ static void VerifyStringSink(const std::string& input) {
378
+ std::string compressed;
379
+ DataEndingAtUnreadablePage i(input);
380
+ const size_t written = snappy::Compress(i.data(), i.size(), &compressed);
381
+ CHECK_EQ(written, compressed.size());
382
+ CHECK_LE(compressed.size(),
383
+ snappy::MaxCompressedLength(input.size()));
384
+ CHECK(snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
494
385
 
495
- static void VerifyIOVec(const string& input) {
496
- string compressed;
386
+ std::string uncompressed;
387
+ uncompressed.resize(input.size());
388
+ snappy::UncheckedByteArraySink sink(string_as_array(&uncompressed));
389
+ DataEndingAtUnreadablePage c(compressed);
390
+ snappy::ByteArraySource source(c.data(), c.size());
391
+ CHECK(snappy::Uncompress(&source, &sink));
392
+ CHECK_EQ(uncompressed, input);
393
+ }
394
+
395
+ static void VerifyIOVec(const std::string& input) {
396
+ std::string compressed;
497
397
  DataEndingAtUnreadablePage i(input);
498
398
  const size_t written = snappy::Compress(i.data(), i.size(), &compressed);
499
399
  CHECK_EQ(written, compressed.size());
@@ -504,23 +404,28 @@ static void VerifyIOVec(const string& input) {
504
404
  // Try uncompressing into an iovec containing a random number of entries
505
405
  // ranging from 1 to 10.
506
406
  char* buf = new char[input.size()];
507
- ACMRandom rnd(input.size());
508
- int num = rnd.Next() % 10 + 1;
407
+ std::minstd_rand0 rng(input.size());
408
+ std::uniform_int_distribution<size_t> uniform_1_to_10(1, 10);
409
+ size_t num = uniform_1_to_10(rng);
509
410
  if (input.size() < num) {
510
411
  num = input.size();
511
412
  }
512
413
  struct iovec* iov = new iovec[num];
513
414
  int used_so_far = 0;
514
- for (int i = 0; i < num; ++i) {
415
+ std::bernoulli_distribution one_in_five(1.0 / 5);
416
+ for (size_t i = 0; i < num; ++i) {
417
+ assert(used_so_far < input.size());
515
418
  iov[i].iov_base = buf + used_so_far;
516
419
  if (i == num - 1) {
517
420
  iov[i].iov_len = input.size() - used_so_far;
518
421
  } else {
519
422
  // Randomly choose to insert a 0 byte entry.
520
- if (rnd.OneIn(5)) {
423
+ if (one_in_five(rng)) {
521
424
  iov[i].iov_len = 0;
522
425
  } else {
523
- iov[i].iov_len = rnd.Uniform(input.size());
426
+ std::uniform_int_distribution<size_t> uniform_not_used_so_far(
427
+ 0, input.size() - used_so_far - 1);
428
+ iov[i].iov_len = uniform_not_used_so_far(rng);
524
429
  }
525
430
  }
526
431
  used_so_far += iov[i].iov_len;
@@ -534,22 +439,22 @@ static void VerifyIOVec(const string& input) {
534
439
 
535
440
  // Test that data compressed by a compressor that does not
536
441
  // obey block sizes is uncompressed properly.
537
- static void VerifyNonBlockedCompression(const string& input) {
442
+ static void VerifyNonBlockedCompression(const std::string& input) {
538
443
  if (input.length() > snappy::kBlockSize) {
539
444
  // We cannot test larger blocks than the maximum block size, obviously.
540
445
  return;
541
446
  }
542
447
 
543
- string prefix;
448
+ std::string prefix;
544
449
  Varint::Append32(&prefix, input.size());
545
450
 
546
451
  // Setup compression table
547
- snappy::internal::WorkingMemory wmem;
452
+ snappy::internal::WorkingMemory wmem(input.size());
548
453
  int table_size;
549
454
  uint16* table = wmem.GetHashTable(input.size(), &table_size);
550
455
 
551
456
  // Compress entire input in one shot
552
- string compressed;
457
+ std::string compressed;
553
458
  compressed += prefix;
554
459
  compressed.resize(prefix.size()+snappy::MaxCompressedLength(input.size()));
555
460
  char* dest = string_as_array(&compressed) + prefix.size();
@@ -557,57 +462,79 @@ static void VerifyNonBlockedCompression(const string& input) {
557
462
  dest, table, table_size);
558
463
  compressed.resize(end - compressed.data());
559
464
 
560
- // Uncompress into string
561
- string uncomp_str;
465
+ // Uncompress into std::string
466
+ std::string uncomp_str;
562
467
  CHECK(snappy::Uncompress(compressed.data(), compressed.size(), &uncomp_str));
563
468
  CHECK_EQ(uncomp_str, input);
564
469
 
470
+ // Uncompress using source/sink
471
+ std::string uncomp_str2;
472
+ uncomp_str2.resize(input.size());
473
+ snappy::UncheckedByteArraySink sink(string_as_array(&uncomp_str2));
474
+ snappy::ByteArraySource source(compressed.data(), compressed.size());
475
+ CHECK(snappy::Uncompress(&source, &sink));
476
+ CHECK_EQ(uncomp_str2, input);
477
+
478
+ // Uncompress into iovec
479
+ {
480
+ static const int kNumBlocks = 10;
481
+ struct iovec vec[kNumBlocks];
482
+ const int block_size = 1 + input.size() / kNumBlocks;
483
+ std::string iovec_data(block_size * kNumBlocks, 'x');
484
+ for (int i = 0; i < kNumBlocks; i++) {
485
+ vec[i].iov_base = string_as_array(&iovec_data) + i * block_size;
486
+ vec[i].iov_len = block_size;
487
+ }
488
+ CHECK(snappy::RawUncompressToIOVec(compressed.data(), compressed.size(),
489
+ vec, kNumBlocks));
490
+ CHECK_EQ(std::string(iovec_data.data(), input.size()), input);
491
+ }
565
492
  }
566
493
 
567
494
  // Expand the input so that it is at least K times as big as block size
568
- static string Expand(const string& input) {
495
+ static std::string Expand(const std::string& input) {
569
496
  static const int K = 3;
570
- string data = input;
497
+ std::string data = input;
571
498
  while (data.size() < K * snappy::kBlockSize) {
572
499
  data += input;
573
500
  }
574
501
  return data;
575
502
  }
576
503
 
577
- static int Verify(const string& input) {
504
+ static int Verify(const std::string& input) {
578
505
  VLOG(1) << "Verifying input of size " << input.size();
579
506
 
580
507
  // Compress using string based routines
581
508
  const int result = VerifyString(input);
582
509
 
510
+ // Verify using sink based routines
511
+ VerifyStringSink(input);
583
512
 
584
513
  VerifyNonBlockedCompression(input);
585
514
  VerifyIOVec(input);
586
515
  if (!input.empty()) {
587
- const string expanded = Expand(input);
516
+ const std::string expanded = Expand(input);
588
517
  VerifyNonBlockedCompression(expanded);
589
518
  VerifyIOVec(input);
590
519
  }
591
520
 
592
-
593
521
  return result;
594
522
  }
595
523
 
596
- // This test checks to ensure that snappy doesn't coredump if it gets
597
- // corrupted data.
598
-
599
- static bool IsValidCompressedBuffer(const string& c) {
524
+ static bool IsValidCompressedBuffer(const std::string& c) {
600
525
  return snappy::IsValidCompressedBuffer(c.data(), c.size());
601
526
  }
602
- static bool Uncompress(const string& c, string* u) {
527
+ static bool Uncompress(const std::string& c, std::string* u) {
603
528
  return snappy::Uncompress(c.data(), c.size(), u);
604
529
  }
605
530
 
606
- TYPED_TEST(CorruptedTest, VerifyCorrupted) {
607
- string source = "making sure we don't crash with corrupted input";
531
+ // This test checks to ensure that snappy doesn't coredump if it gets
532
+ // corrupted data.
533
+ TEST(CorruptedTest, VerifyCorrupted) {
534
+ std::string source = "making sure we don't crash with corrupted input";
608
535
  VLOG(1) << source;
609
- string dest;
610
- TypeParam uncmp;
536
+ std::string dest;
537
+ std::string uncmp;
611
538
  snappy::Compress(source.data(), source.size(), &dest);
612
539
 
613
540
  // Mess around with the data. It's hard to simulate all possible
@@ -616,19 +543,19 @@ TYPED_TEST(CorruptedTest, VerifyCorrupted) {
616
543
  dest[1]--;
617
544
  dest[3]++;
618
545
  // this really ought to fail.
619
- CHECK(!IsValidCompressedBuffer(TypeParam(dest)));
620
- CHECK(!Uncompress(TypeParam(dest), &uncmp));
546
+ CHECK(!IsValidCompressedBuffer(dest));
547
+ CHECK(!Uncompress(dest, &uncmp));
621
548
 
622
549
  // This is testing for a security bug - a buffer that decompresses to 100k
623
550
  // but we lie in the snappy header and only reserve 0 bytes of memory :)
624
551
  source.resize(100000);
625
- for (int i = 0; i < source.length(); ++i) {
552
+ for (size_t i = 0; i < source.length(); ++i) {
626
553
  source[i] = 'A';
627
554
  }
628
555
  snappy::Compress(source.data(), source.size(), &dest);
629
556
  dest[0] = dest[1] = dest[2] = dest[3] = 0;
630
- CHECK(!IsValidCompressedBuffer(TypeParam(dest)));
631
- CHECK(!Uncompress(TypeParam(dest), &uncmp));
557
+ CHECK(!IsValidCompressedBuffer(dest));
558
+ CHECK(!Uncompress(dest, &uncmp));
632
559
 
633
560
  if (sizeof(void *) == 4) {
634
561
  // Another security check; check a crazy big length can't DoS us with an
@@ -637,26 +564,26 @@ TYPED_TEST(CorruptedTest, VerifyCorrupted) {
637
564
  // where 3 GB might be an acceptable allocation size, Uncompress()
638
565
  // attempts to decompress, and sometimes causes the test to run out of
639
566
  // memory.
640
- dest[0] = dest[1] = dest[2] = dest[3] = 0xff;
567
+ dest[0] = dest[1] = dest[2] = dest[3] = '\xff';
641
568
  // This decodes to a really large size, i.e., about 3 GB.
642
569
  dest[4] = 'k';
643
- CHECK(!IsValidCompressedBuffer(TypeParam(dest)));
644
- CHECK(!Uncompress(TypeParam(dest), &uncmp));
570
+ CHECK(!IsValidCompressedBuffer(dest));
571
+ CHECK(!Uncompress(dest, &uncmp));
645
572
  } else {
646
573
  LOG(WARNING) << "Crazy decompression lengths not checked on 64-bit build";
647
574
  }
648
575
 
649
576
  // This decodes to about 2 MB; much smaller, but should still fail.
650
- dest[0] = dest[1] = dest[2] = 0xff;
577
+ dest[0] = dest[1] = dest[2] = '\xff';
651
578
  dest[3] = 0x00;
652
- CHECK(!IsValidCompressedBuffer(TypeParam(dest)));
653
- CHECK(!Uncompress(TypeParam(dest), &uncmp));
579
+ CHECK(!IsValidCompressedBuffer(dest));
580
+ CHECK(!Uncompress(dest, &uncmp));
654
581
 
655
582
  // try reading stuff in from a bad file.
656
583
  for (int i = 1; i <= 3; ++i) {
657
- string data = ReadTestDataFile(StringPrintf("baddata%d.snappy", i).c_str(),
658
- 0);
659
- string uncmp;
584
+ std::string data =
585
+ ReadTestDataFile(StrFormat("baddata%d.snappy", i).c_str(), 0);
586
+ std::string uncmp;
660
587
  // check that we don't return a crazy length
661
588
  size_t ulen;
662
589
  CHECK(!snappy::GetUncompressedLength(data.data(), data.size(), &ulen)
@@ -665,8 +592,8 @@ TYPED_TEST(CorruptedTest, VerifyCorrupted) {
665
592
  snappy::ByteArraySource source(data.data(), data.size());
666
593
  CHECK(!snappy::GetUncompressedLength(&source, &ulen2) ||
667
594
  (ulen2 < (1<<20)));
668
- CHECK(!IsValidCompressedBuffer(TypeParam(data)));
669
- CHECK(!Uncompress(TypeParam(data), &uncmp));
595
+ CHECK(!IsValidCompressedBuffer(data));
596
+ CHECK(!Uncompress(data, &uncmp));
670
597
  }
671
598
  }
672
599
 
@@ -674,7 +601,7 @@ TYPED_TEST(CorruptedTest, VerifyCorrupted) {
674
601
  // These mirror the compression code in snappy.cc, but are copied
675
602
  // here so that we can bypass some limitations in the how snappy.cc
676
603
  // invokes these routines.
677
- static void AppendLiteral(string* dst, const string& literal) {
604
+ static void AppendLiteral(std::string* dst, const std::string& literal) {
678
605
  if (literal.empty()) return;
679
606
  int n = literal.size() - 1;
680
607
  if (n < 60) {
@@ -689,12 +616,12 @@ static void AppendLiteral(string* dst, const string& literal) {
689
616
  n >>= 8;
690
617
  }
691
618
  dst->push_back(0 | ((59+count) << 2));
692
- *dst += string(number, count);
619
+ *dst += std::string(number, count);
693
620
  }
694
621
  *dst += literal;
695
622
  }
696
623
 
697
- static void AppendCopy(string* dst, int offset, int length) {
624
+ static void AppendCopy(std::string* dst, int offset, int length) {
698
625
  while (length > 0) {
699
626
  // Figure out how much to copy in one shot
700
627
  int to_copy;
@@ -731,51 +658,67 @@ TEST(Snappy, SimpleTests) {
731
658
  Verify("ab");
732
659
  Verify("abc");
733
660
 
734
- Verify("aaaaaaa" + string(16, 'b') + string("aaaaa") + "abc");
735
- Verify("aaaaaaa" + string(256, 'b') + string("aaaaa") + "abc");
736
- Verify("aaaaaaa" + string(2047, 'b') + string("aaaaa") + "abc");
737
- Verify("aaaaaaa" + string(65536, 'b') + string("aaaaa") + "abc");
738
- Verify("abcaaaaaaa" + string(65536, 'b') + string("aaaaa") + "abc");
661
+ Verify("aaaaaaa" + std::string(16, 'b') + std::string("aaaaa") + "abc");
662
+ Verify("aaaaaaa" + std::string(256, 'b') + std::string("aaaaa") + "abc");
663
+ Verify("aaaaaaa" + std::string(2047, 'b') + std::string("aaaaa") + "abc");
664
+ Verify("aaaaaaa" + std::string(65536, 'b') + std::string("aaaaa") + "abc");
665
+ Verify("abcaaaaaaa" + std::string(65536, 'b') + std::string("aaaaa") + "abc");
739
666
  }
740
667
 
741
668
  // Verify max blowup (lots of four-byte copies)
742
669
  TEST(Snappy, MaxBlowup) {
743
- string input;
744
- for (int i = 0; i < 20000; i++) {
745
- ACMRandom rnd(i);
746
- uint32 bytes = static_cast<uint32>(rnd.Next());
747
- input.append(reinterpret_cast<char*>(&bytes), sizeof(bytes));
748
- }
749
- for (int i = 19999; i >= 0; i--) {
750
- ACMRandom rnd(i);
751
- uint32 bytes = static_cast<uint32>(rnd.Next());
752
- input.append(reinterpret_cast<char*>(&bytes), sizeof(bytes));
670
+ std::mt19937 rng;
671
+ std::uniform_int_distribution<int> uniform_byte(0, 255);
672
+ std::string input;
673
+ for (int i = 0; i < 80000; ++i)
674
+ input.push_back(static_cast<char>(uniform_byte(rng)));
675
+
676
+ for (int i = 0; i < 80000; i += 4) {
677
+ std::string four_bytes(input.end() - i - 4, input.end() - i);
678
+ input.append(four_bytes);
753
679
  }
754
680
  Verify(input);
755
681
  }
756
682
 
757
683
  TEST(Snappy, RandomData) {
758
- ACMRandom rnd(FLAGS_test_random_seed);
759
-
760
- const int num_ops = 20000;
684
+ std::minstd_rand0 rng(FLAGS_test_random_seed);
685
+ std::uniform_int_distribution<int> uniform_0_to_3(0, 3);
686
+ std::uniform_int_distribution<int> uniform_0_to_8(0, 8);
687
+ std::uniform_int_distribution<int> uniform_byte(0, 255);
688
+ std::uniform_int_distribution<size_t> uniform_4k(0, 4095);
689
+ std::uniform_int_distribution<size_t> uniform_64k(0, 65535);
690
+ std::bernoulli_distribution one_in_ten(1.0 / 10);
691
+
692
+ constexpr int num_ops = 20000;
761
693
  for (int i = 0; i < num_ops; i++) {
762
694
  if ((i % 1000) == 0) {
763
695
  VLOG(0) << "Random op " << i << " of " << num_ops;
764
696
  }
765
697
 
766
- string x;
767
- int len = rnd.Uniform(4096);
698
+ std::string x;
699
+ size_t len = uniform_4k(rng);
768
700
  if (i < 100) {
769
- len = 65536 + rnd.Uniform(65536);
701
+ len = 65536 + uniform_64k(rng);
770
702
  }
771
703
  while (x.size() < len) {
772
704
  int run_len = 1;
773
- if (rnd.OneIn(10)) {
774
- run_len = rnd.Skewed(8);
705
+ if (one_in_ten(rng)) {
706
+ int skewed_bits = uniform_0_to_8(rng);
707
+ // int is guaranteed to hold at least 16 bits, this uses at most 8 bits.
708
+ std::uniform_int_distribution<int> skewed_low(0,
709
+ (1 << skewed_bits) - 1);
710
+ run_len = skewed_low(rng);
711
+ }
712
+ char c = static_cast<char>(uniform_byte(rng));
713
+ if (i >= 100) {
714
+ int skewed_bits = uniform_0_to_3(rng);
715
+ // int is guaranteed to hold at least 16 bits, this uses at most 3 bits.
716
+ std::uniform_int_distribution<int> skewed_low(0,
717
+ (1 << skewed_bits) - 1);
718
+ c = static_cast<char>(skewed_low(rng));
775
719
  }
776
- char c = (i < 100) ? rnd.Uniform(256) : rnd.Skewed(3);
777
720
  while (run_len-- > 0 && x.size() < len) {
778
- x += c;
721
+ x.push_back(c);
779
722
  }
780
723
  }
781
724
 
@@ -789,19 +732,19 @@ TEST(Snappy, FourByteOffset) {
789
732
  // copy manually.
790
733
 
791
734
  // The two fragments that make up the input string.
792
- string fragment1 = "012345689abcdefghijklmnopqrstuvwxyz";
793
- string fragment2 = "some other string";
735
+ std::string fragment1 = "012345689abcdefghijklmnopqrstuvwxyz";
736
+ std::string fragment2 = "some other string";
794
737
 
795
738
  // How many times each fragment is emitted.
796
739
  const int n1 = 2;
797
740
  const int n2 = 100000 / fragment2.size();
798
741
  const int length = n1 * fragment1.size() + n2 * fragment2.size();
799
742
 
800
- string compressed;
743
+ std::string compressed;
801
744
  Varint::Append32(&compressed, length);
802
745
 
803
746
  AppendLiteral(&compressed, fragment1);
804
- string src = fragment1;
747
+ std::string src = fragment1;
805
748
  for (int i = 0; i < n2; i++) {
806
749
  AppendLiteral(&compressed, fragment2);
807
750
  src += fragment2;
@@ -810,7 +753,7 @@ TEST(Snappy, FourByteOffset) {
810
753
  src += fragment1;
811
754
  CHECK_EQ(length, src.size());
812
755
 
813
- string uncompressed;
756
+ std::string uncompressed;
814
757
  CHECK(snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
815
758
  CHECK(snappy::Uncompress(compressed.data(), compressed.size(),
816
759
  &uncompressed));
@@ -832,7 +775,7 @@ TEST(Snappy, IOVecEdgeCases) {
832
775
  iov[i].iov_len = kLengths[i];
833
776
  }
834
777
 
835
- string compressed;
778
+ std::string compressed;
836
779
  Varint::Append32(&compressed, 22);
837
780
 
838
781
  // A literal whose output crosses three blocks.
@@ -893,7 +836,7 @@ TEST(Snappy, IOVecLiteralOverflow) {
893
836
  iov[i].iov_len = kLengths[i];
894
837
  }
895
838
 
896
- string compressed;
839
+ std::string compressed;
897
840
  Varint::Append32(&compressed, 8);
898
841
 
899
842
  AppendLiteral(&compressed, "12345678");
@@ -915,7 +858,7 @@ TEST(Snappy, IOVecCopyOverflow) {
915
858
  iov[i].iov_len = kLengths[i];
916
859
  }
917
860
 
918
- string compressed;
861
+ std::string compressed;
919
862
  Varint::Append32(&compressed, 8);
920
863
 
921
864
  AppendLiteral(&compressed, "123");
@@ -929,8 +872,7 @@ TEST(Snappy, IOVecCopyOverflow) {
929
872
  }
930
873
  }
931
874
 
932
-
933
- static bool CheckUncompressedLength(const string& compressed,
875
+ static bool CheckUncompressedLength(const std::string& compressed,
934
876
  size_t* ulength) {
935
877
  const bool result1 = snappy::GetUncompressedLength(compressed.data(),
936
878
  compressed.size(),
@@ -944,7 +886,7 @@ static bool CheckUncompressedLength(const string& compressed,
944
886
  }
945
887
 
946
888
  TEST(SnappyCorruption, TruncatedVarint) {
947
- string compressed, uncompressed;
889
+ std::string compressed, uncompressed;
948
890
  size_t ulength;
949
891
  compressed.push_back('\xf0');
950
892
  CHECK(!CheckUncompressedLength(compressed, &ulength));
@@ -954,13 +896,13 @@ TEST(SnappyCorruption, TruncatedVarint) {
954
896
  }
955
897
 
956
898
  TEST(SnappyCorruption, UnterminatedVarint) {
957
- string compressed, uncompressed;
899
+ std::string compressed, uncompressed;
958
900
  size_t ulength;
959
- compressed.push_back(128);
960
- compressed.push_back(128);
961
- compressed.push_back(128);
962
- compressed.push_back(128);
963
- compressed.push_back(128);
901
+ compressed.push_back('\x80');
902
+ compressed.push_back('\x80');
903
+ compressed.push_back('\x80');
904
+ compressed.push_back('\x80');
905
+ compressed.push_back('\x80');
964
906
  compressed.push_back(10);
965
907
  CHECK(!CheckUncompressedLength(compressed, &ulength));
966
908
  CHECK(!snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
@@ -968,18 +910,32 @@ TEST(SnappyCorruption, UnterminatedVarint) {
968
910
  &uncompressed));
969
911
  }
970
912
 
913
+ TEST(SnappyCorruption, OverflowingVarint) {
914
+ std::string compressed, uncompressed;
915
+ size_t ulength;
916
+ compressed.push_back('\xfb');
917
+ compressed.push_back('\xff');
918
+ compressed.push_back('\xff');
919
+ compressed.push_back('\xff');
920
+ compressed.push_back('\x7f');
921
+ CHECK(!CheckUncompressedLength(compressed, &ulength));
922
+ CHECK(!snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
923
+ CHECK(!snappy::Uncompress(compressed.data(), compressed.size(),
924
+ &uncompressed));
925
+ }
926
+
971
927
  TEST(Snappy, ReadPastEndOfBuffer) {
972
928
  // Check that we do not read past end of input
973
929
 
974
930
  // Make a compressed string that ends with a single-byte literal
975
- string compressed;
931
+ std::string compressed;
976
932
  Varint::Append32(&compressed, 1);
977
933
  AppendLiteral(&compressed, "x");
978
934
 
979
- string uncompressed;
935
+ std::string uncompressed;
980
936
  DataEndingAtUnreadablePage c(compressed);
981
937
  CHECK(snappy::Uncompress(c.data(), c.size(), &uncompressed));
982
- CHECK_EQ(uncompressed, string("x"));
938
+ CHECK_EQ(uncompressed, std::string("x"));
983
939
  }
984
940
 
985
941
  // Check for an infinite loop caused by a copy with offset==0
@@ -998,11 +954,13 @@ TEST(Snappy, ZeroOffsetCopyValidation) {
998
954
  EXPECT_FALSE(snappy::IsValidCompressedBuffer(compressed, 4));
999
955
  }
1000
956
 
1001
-
1002
957
  namespace {
1003
958
 
1004
959
  int TestFindMatchLength(const char* s1, const char *s2, unsigned length) {
1005
- return snappy::internal::FindMatchLength(s1, s2, s2 + length);
960
+ std::pair<size_t, bool> p =
961
+ snappy::internal::FindMatchLength(s1, s2, s2 + length);
962
+ CHECK_EQ(p.first < 8, p.second);
963
+ return p.first;
1006
964
  }
1007
965
 
1008
966
  } // namespace
@@ -1098,22 +1056,24 @@ TEST(Snappy, FindMatchLength) {
1098
1056
  }
1099
1057
 
1100
1058
  TEST(Snappy, FindMatchLengthRandom) {
1101
- const int kNumTrials = 10000;
1102
- const int kTypicalLength = 10;
1103
- ACMRandom rnd(FLAGS_test_random_seed);
1059
+ constexpr int kNumTrials = 10000;
1060
+ constexpr int kTypicalLength = 10;
1061
+ std::minstd_rand0 rng(FLAGS_test_random_seed);
1062
+ std::uniform_int_distribution<int> uniform_byte(0, 255);
1063
+ std::bernoulli_distribution one_in_two(1.0 / 2);
1064
+ std::bernoulli_distribution one_in_typical_length(1.0 / kTypicalLength);
1104
1065
 
1105
1066
  for (int i = 0; i < kNumTrials; i++) {
1106
- string s, t;
1107
- char a = rnd.Rand8();
1108
- char b = rnd.Rand8();
1109
- while (!rnd.OneIn(kTypicalLength)) {
1110
- s.push_back(rnd.OneIn(2) ? a : b);
1111
- t.push_back(rnd.OneIn(2) ? a : b);
1067
+ std::string s, t;
1068
+ char a = static_cast<char>(uniform_byte(rng));
1069
+ char b = static_cast<char>(uniform_byte(rng));
1070
+ while (!one_in_typical_length(rng)) {
1071
+ s.push_back(one_in_two(rng) ? a : b);
1072
+ t.push_back(one_in_two(rng) ? a : b);
1112
1073
  }
1113
1074
  DataEndingAtUnreadablePage u(s);
1114
1075
  DataEndingAtUnreadablePage v(t);
1115
- int matched = snappy::internal::FindMatchLength(
1116
- u.data(), v.data(), v.data() + t.size());
1076
+ int matched = TestFindMatchLength(u.data(), v.data(), t.size());
1117
1077
  if (matched == t.size()) {
1118
1078
  EXPECT_EQ(s, t);
1119
1079
  } else {
@@ -1125,51 +1085,140 @@ TEST(Snappy, FindMatchLengthRandom) {
1125
1085
  }
1126
1086
  }
1127
1087
 
1088
+ static uint16 MakeEntry(unsigned int extra,
1089
+ unsigned int len,
1090
+ unsigned int copy_offset) {
1091
+ // Check that all of the fields fit within the allocated space
1092
+ assert(extra == (extra & 0x7)); // At most 3 bits
1093
+ assert(copy_offset == (copy_offset & 0x7)); // At most 3 bits
1094
+ assert(len == (len & 0x7f)); // At most 7 bits
1095
+ return len | (copy_offset << 8) | (extra << 11);
1096
+ }
1097
+
1098
+ // Check that the decompression table is correct, and optionally print out
1099
+ // the computed one.
1100
+ TEST(Snappy, VerifyCharTable) {
1101
+ using snappy::internal::LITERAL;
1102
+ using snappy::internal::COPY_1_BYTE_OFFSET;
1103
+ using snappy::internal::COPY_2_BYTE_OFFSET;
1104
+ using snappy::internal::COPY_4_BYTE_OFFSET;
1105
+ using snappy::internal::char_table;
1106
+
1107
+ uint16 dst[256];
1108
+
1109
+ // Place invalid entries in all places to detect missing initialization
1110
+ int assigned = 0;
1111
+ for (int i = 0; i < 256; i++) {
1112
+ dst[i] = 0xffff;
1113
+ }
1114
+
1115
+ // Small LITERAL entries. We store (len-1) in the top 6 bits.
1116
+ for (unsigned int len = 1; len <= 60; len++) {
1117
+ dst[LITERAL | ((len-1) << 2)] = MakeEntry(0, len, 0);
1118
+ assigned++;
1119
+ }
1120
+
1121
+ // Large LITERAL entries. We use 60..63 in the high 6 bits to
1122
+ // encode the number of bytes of length info that follow the opcode.
1123
+ for (unsigned int extra_bytes = 1; extra_bytes <= 4; extra_bytes++) {
1124
+ // We set the length field in the lookup table to 1 because extra
1125
+ // bytes encode len-1.
1126
+ dst[LITERAL | ((extra_bytes+59) << 2)] = MakeEntry(extra_bytes, 1, 0);
1127
+ assigned++;
1128
+ }
1129
+
1130
+ // COPY_1_BYTE_OFFSET.
1131
+ //
1132
+ // The tag byte in the compressed data stores len-4 in 3 bits, and
1133
+ // offset/256 in 5 bits. offset%256 is stored in the next byte.
1134
+ //
1135
+ // This format is used for length in range [4..11] and offset in
1136
+ // range [0..2047]
1137
+ for (unsigned int len = 4; len < 12; len++) {
1138
+ for (unsigned int offset = 0; offset < 2048; offset += 256) {
1139
+ dst[COPY_1_BYTE_OFFSET | ((len-4)<<2) | ((offset>>8)<<5)] =
1140
+ MakeEntry(1, len, offset>>8);
1141
+ assigned++;
1142
+ }
1143
+ }
1144
+
1145
+ // COPY_2_BYTE_OFFSET.
1146
+ // Tag contains len-1 in top 6 bits, and offset in next two bytes.
1147
+ for (unsigned int len = 1; len <= 64; len++) {
1148
+ dst[COPY_2_BYTE_OFFSET | ((len-1)<<2)] = MakeEntry(2, len, 0);
1149
+ assigned++;
1150
+ }
1151
+
1152
+ // COPY_4_BYTE_OFFSET.
1153
+ // Tag contents len-1 in top 6 bits, and offset in next four bytes.
1154
+ for (unsigned int len = 1; len <= 64; len++) {
1155
+ dst[COPY_4_BYTE_OFFSET | ((len-1)<<2)] = MakeEntry(4, len, 0);
1156
+ assigned++;
1157
+ }
1158
+
1159
+ // Check that each entry was initialized exactly once.
1160
+ EXPECT_EQ(256, assigned) << "Assigned only " << assigned << " of 256";
1161
+ for (int i = 0; i < 256; i++) {
1162
+ EXPECT_NE(0xffff, dst[i]) << "Did not assign byte " << i;
1163
+ }
1164
+
1165
+ if (FLAGS_snappy_dump_decompression_table) {
1166
+ printf("static const uint16 char_table[256] = {\n ");
1167
+ for (int i = 0; i < 256; i++) {
1168
+ printf("0x%04x%s",
1169
+ dst[i],
1170
+ ((i == 255) ? "\n" : (((i%8) == 7) ? ",\n " : ", ")));
1171
+ }
1172
+ printf("};\n");
1173
+ }
1174
+
1175
+ // Check that computed table matched recorded table.
1176
+ for (int i = 0; i < 256; i++) {
1177
+ EXPECT_EQ(dst[i], char_table[i]) << "Mismatch in byte " << i;
1178
+ }
1179
+ }
1128
1180
 
1129
1181
  static void CompressFile(const char* fname) {
1130
- string fullinput;
1131
- file::GetContents(fname, &fullinput, file::Defaults()).CheckSuccess();
1182
+ std::string fullinput;
1183
+ CHECK_OK(file::GetContents(fname, &fullinput, file::Defaults()));
1132
1184
 
1133
- string compressed;
1185
+ std::string compressed;
1134
1186
  Compress(fullinput.data(), fullinput.size(), SNAPPY, &compressed, false);
1135
1187
 
1136
- file::SetContents(string(fname).append(".comp"), compressed, file::Defaults())
1137
- .CheckSuccess();
1188
+ CHECK_OK(file::SetContents(std::string(fname).append(".comp"), compressed,
1189
+ file::Defaults()));
1138
1190
  }
1139
1191
 
1140
1192
  static void UncompressFile(const char* fname) {
1141
- string fullinput;
1142
- file::GetContents(fname, &fullinput, file::Defaults()).CheckSuccess();
1193
+ std::string fullinput;
1194
+ CHECK_OK(file::GetContents(fname, &fullinput, file::Defaults()));
1143
1195
 
1144
1196
  size_t uncompLength;
1145
1197
  CHECK(CheckUncompressedLength(fullinput, &uncompLength));
1146
1198
 
1147
- string uncompressed;
1199
+ std::string uncompressed;
1148
1200
  uncompressed.resize(uncompLength);
1149
1201
  CHECK(snappy::Uncompress(fullinput.data(), fullinput.size(), &uncompressed));
1150
1202
 
1151
- file::SetContents(string(fname).append(".uncomp"), uncompressed,
1152
- file::Defaults()).CheckSuccess();
1203
+ CHECK_OK(file::SetContents(std::string(fname).append(".uncomp"), uncompressed,
1204
+ file::Defaults()));
1153
1205
  }
1154
1206
 
1155
1207
  static void MeasureFile(const char* fname) {
1156
- string fullinput;
1157
- file::GetContents(fname, &fullinput, file::Defaults()).CheckSuccess();
1208
+ std::string fullinput;
1209
+ CHECK_OK(file::GetContents(fname, &fullinput, file::Defaults()));
1158
1210
  printf("%-40s :\n", fname);
1159
1211
 
1160
1212
  int start_len = (FLAGS_start_len < 0) ? fullinput.size() : FLAGS_start_len;
1161
1213
  int end_len = fullinput.size();
1162
1214
  if (FLAGS_end_len >= 0) {
1163
- end_len = min<int>(fullinput.size(), FLAGS_end_len);
1215
+ end_len = std::min<int>(fullinput.size(), FLAGS_end_len);
1164
1216
  }
1165
1217
  for (int len = start_len; len <= end_len; len++) {
1166
1218
  const char* const input = fullinput.data();
1167
1219
  int repeats = (FLAGS_bytes + len) / (len + 1);
1168
1220
  if (FLAGS_zlib) Measure(input, len, ZLIB, repeats, 1024<<10);
1169
1221
  if (FLAGS_lzo) Measure(input, len, LZO, repeats, 1024<<10);
1170
- if (FLAGS_liblzf) Measure(input, len, LIBLZF, repeats, 1024<<10);
1171
- if (FLAGS_quicklz) Measure(input, len, QUICKLZ, repeats, 1024<<10);
1172
- if (FLAGS_fastlz) Measure(input, len, FASTLZ, repeats, 1024<<10);
1173
1222
  if (FLAGS_snappy) Measure(input, len, SNAPPY, repeats, 4096<<10);
1174
1223
 
1175
1224
  // For block-size based measurements
@@ -1209,10 +1258,10 @@ static void BM_UFlat(int iters, int arg) {
1209
1258
  // Pick file to process based on "arg"
1210
1259
  CHECK_GE(arg, 0);
1211
1260
  CHECK_LT(arg, ARRAYSIZE(files));
1212
- string contents = ReadTestDataFile(files[arg].filename,
1213
- files[arg].size_limit);
1261
+ std::string contents =
1262
+ ReadTestDataFile(files[arg].filename, files[arg].size_limit);
1214
1263
 
1215
- string zcontents;
1264
+ std::string zcontents;
1216
1265
  snappy::Compress(contents.data(), contents.size(), &zcontents);
1217
1266
  char* dst = new char[contents.size()];
1218
1267
 
@@ -1235,10 +1284,10 @@ static void BM_UValidate(int iters, int arg) {
1235
1284
  // Pick file to process based on "arg"
1236
1285
  CHECK_GE(arg, 0);
1237
1286
  CHECK_LT(arg, ARRAYSIZE(files));
1238
- string contents = ReadTestDataFile(files[arg].filename,
1239
- files[arg].size_limit);
1287
+ std::string contents =
1288
+ ReadTestDataFile(files[arg].filename, files[arg].size_limit);
1240
1289
 
1241
- string zcontents;
1290
+ std::string zcontents;
1242
1291
  snappy::Compress(contents.data(), contents.size(), &zcontents);
1243
1292
 
1244
1293
  SetBenchmarkBytesProcessed(static_cast<int64>(iters) *
@@ -1258,10 +1307,10 @@ static void BM_UIOVec(int iters, int arg) {
1258
1307
  // Pick file to process based on "arg"
1259
1308
  CHECK_GE(arg, 0);
1260
1309
  CHECK_LT(arg, ARRAYSIZE(files));
1261
- string contents = ReadTestDataFile(files[arg].filename,
1262
- files[arg].size_limit);
1310
+ std::string contents =
1311
+ ReadTestDataFile(files[arg].filename, files[arg].size_limit);
1263
1312
 
1264
- string zcontents;
1313
+ std::string zcontents;
1265
1314
  snappy::Compress(contents.data(), contents.size(), &zcontents);
1266
1315
 
1267
1316
  // Uncompress into an iovec containing ten entries.
@@ -1298,6 +1347,37 @@ static void BM_UIOVec(int iters, int arg) {
1298
1347
  }
1299
1348
  BENCHMARK(BM_UIOVec)->DenseRange(0, 4);
1300
1349
 
1350
+ static void BM_UFlatSink(int iters, int arg) {
1351
+ StopBenchmarkTiming();
1352
+
1353
+ // Pick file to process based on "arg"
1354
+ CHECK_GE(arg, 0);
1355
+ CHECK_LT(arg, ARRAYSIZE(files));
1356
+ std::string contents =
1357
+ ReadTestDataFile(files[arg].filename, files[arg].size_limit);
1358
+
1359
+ std::string zcontents;
1360
+ snappy::Compress(contents.data(), contents.size(), &zcontents);
1361
+ char* dst = new char[contents.size()];
1362
+
1363
+ SetBenchmarkBytesProcessed(static_cast<int64>(iters) *
1364
+ static_cast<int64>(contents.size()));
1365
+ SetBenchmarkLabel(files[arg].label);
1366
+ StartBenchmarkTiming();
1367
+ while (iters-- > 0) {
1368
+ snappy::ByteArraySource source(zcontents.data(), zcontents.size());
1369
+ snappy::UncheckedByteArraySink sink(dst);
1370
+ CHECK(snappy::Uncompress(&source, &sink));
1371
+ }
1372
+ StopBenchmarkTiming();
1373
+
1374
+ std::string s(dst, contents.size());
1375
+ CHECK_EQ(contents, s);
1376
+
1377
+ delete[] dst;
1378
+ }
1379
+
1380
+ BENCHMARK(BM_UFlatSink)->DenseRange(0, ARRAYSIZE(files) - 1);
1301
1381
 
1302
1382
  static void BM_ZFlat(int iters, int arg) {
1303
1383
  StopBenchmarkTiming();
@@ -1305,8 +1385,8 @@ static void BM_ZFlat(int iters, int arg) {
1305
1385
  // Pick file to process based on "arg"
1306
1386
  CHECK_GE(arg, 0);
1307
1387
  CHECK_LT(arg, ARRAYSIZE(files));
1308
- string contents = ReadTestDataFile(files[arg].filename,
1309
- files[arg].size_limit);
1388
+ std::string contents =
1389
+ ReadTestDataFile(files[arg].filename, files[arg].size_limit);
1310
1390
 
1311
1391
  char* dst = new char[snappy::MaxCompressedLength(contents.size())];
1312
1392
 
@@ -1321,31 +1401,102 @@ static void BM_ZFlat(int iters, int arg) {
1321
1401
  StopBenchmarkTiming();
1322
1402
  const double compression_ratio =
1323
1403
  static_cast<double>(zsize) / std::max<size_t>(1, contents.size());
1324
- SetBenchmarkLabel(StringPrintf("%s (%.2f %%)",
1325
- files[arg].label, 100.0 * compression_ratio));
1326
- VLOG(0) << StringPrintf("compression for %s: %zd -> %zd bytes",
1327
- files[arg].label, contents.size(), zsize);
1404
+ SetBenchmarkLabel(StrFormat("%s (%.2f %%)", files[arg].label,
1405
+ 100.0 * compression_ratio));
1406
+ VLOG(0) << StrFormat("compression for %s: %zd -> %zd bytes",
1407
+ files[arg].label, static_cast<int>(contents.size()),
1408
+ static_cast<int>(zsize));
1328
1409
  delete[] dst;
1329
1410
  }
1330
1411
  BENCHMARK(BM_ZFlat)->DenseRange(0, ARRAYSIZE(files) - 1);
1331
1412
 
1413
+ static void BM_ZFlatAll(int iters, int arg) {
1414
+ StopBenchmarkTiming();
1332
1415
 
1333
- } // namespace snappy
1416
+ CHECK_EQ(arg, 0);
1417
+ const int num_files = ARRAYSIZE(files);
1334
1418
 
1419
+ std::vector<std::string> contents(num_files);
1420
+ std::vector<char*> dst(num_files);
1421
+
1422
+ int64 total_contents_size = 0;
1423
+ for (int i = 0; i < num_files; ++i) {
1424
+ contents[i] = ReadTestDataFile(files[i].filename, files[i].size_limit);
1425
+ dst[i] = new char[snappy::MaxCompressedLength(contents[i].size())];
1426
+ total_contents_size += contents[i].size();
1427
+ }
1428
+
1429
+ SetBenchmarkBytesProcessed(static_cast<int64>(iters) * total_contents_size);
1430
+ StartBenchmarkTiming();
1431
+
1432
+ size_t zsize = 0;
1433
+ while (iters-- > 0) {
1434
+ for (int i = 0; i < num_files; ++i) {
1435
+ snappy::RawCompress(contents[i].data(), contents[i].size(), dst[i],
1436
+ &zsize);
1437
+ }
1438
+ }
1439
+ StopBenchmarkTiming();
1440
+
1441
+ for (int i = 0; i < num_files; ++i) {
1442
+ delete[] dst[i];
1443
+ }
1444
+ SetBenchmarkLabel(StrFormat("%d files", num_files));
1445
+ }
1446
+ BENCHMARK(BM_ZFlatAll)->DenseRange(0, 0);
1447
+
1448
+ static void BM_ZFlatIncreasingTableSize(int iters, int arg) {
1449
+ StopBenchmarkTiming();
1450
+
1451
+ CHECK_EQ(arg, 0);
1452
+ CHECK_GT(ARRAYSIZE(files), 0);
1453
+ const std::string base_content =
1454
+ ReadTestDataFile(files[0].filename, files[0].size_limit);
1455
+
1456
+ std::vector<std::string> contents;
1457
+ std::vector<char*> dst;
1458
+ int64 total_contents_size = 0;
1459
+ for (int table_bits = kMinHashTableBits; table_bits <= kMaxHashTableBits;
1460
+ ++table_bits) {
1461
+ std::string content = base_content;
1462
+ content.resize(1 << table_bits);
1463
+ dst.push_back(new char[snappy::MaxCompressedLength(content.size())]);
1464
+ total_contents_size += content.size();
1465
+ contents.push_back(std::move(content));
1466
+ }
1467
+
1468
+ size_t zsize = 0;
1469
+ SetBenchmarkBytesProcessed(static_cast<int64>(iters) * total_contents_size);
1470
+ StartBenchmarkTiming();
1471
+ while (iters-- > 0) {
1472
+ for (int i = 0; i < contents.size(); ++i) {
1473
+ snappy::RawCompress(contents[i].data(), contents[i].size(), dst[i],
1474
+ &zsize);
1475
+ }
1476
+ }
1477
+ StopBenchmarkTiming();
1478
+
1479
+ for (int i = 0; i < dst.size(); ++i) {
1480
+ delete[] dst[i];
1481
+ }
1482
+ SetBenchmarkLabel(StrFormat("%zd tables", contents.size()));
1483
+ }
1484
+ BENCHMARK(BM_ZFlatIncreasingTableSize)->DenseRange(0, 0);
1485
+
1486
+ } // namespace snappy
1335
1487
 
1336
1488
  int main(int argc, char** argv) {
1337
1489
  InitGoogle(argv[0], &argc, &argv, true);
1338
1490
  RunSpecifiedBenchmarks();
1339
1491
 
1340
-
1341
1492
  if (argc >= 2) {
1342
1493
  for (int arg = 1; arg < argc; arg++) {
1343
1494
  if (FLAGS_write_compressed) {
1344
- CompressFile(argv[arg]);
1495
+ snappy::CompressFile(argv[arg]);
1345
1496
  } else if (FLAGS_write_uncompressed) {
1346
- UncompressFile(argv[arg]);
1497
+ snappy::UncompressFile(argv[arg]);
1347
1498
  } else {
1348
- MeasureFile(argv[arg]);
1499
+ snappy::MeasureFile(argv[arg]);
1349
1500
  }
1350
1501
  }
1351
1502
  return 0;