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.
- checksums.yaml +5 -5
- data/.github/workflows/main.yml +34 -0
- data/.github/workflows/publish.yml +34 -0
- data/Gemfile +4 -0
- data/README.md +28 -4
- data/Rakefile +32 -29
- data/ext/api.c +6 -1
- data/ext/extconf.rb +21 -24
- data/lib/snappy.rb +6 -4
- data/lib/snappy/hadoop.rb +22 -0
- data/lib/snappy/hadoop/reader.rb +62 -0
- data/lib/snappy/hadoop/writer.rb +51 -0
- data/lib/snappy/reader.rb +19 -11
- data/lib/snappy/shim.rb +30 -0
- data/lib/snappy/version.rb +3 -1
- data/lib/snappy/writer.rb +8 -9
- data/snappy.gemspec +17 -37
- data/test/hadoop/snappy_hadoop_reader_test.rb +115 -0
- data/test/hadoop/snappy_hadoop_writer_test.rb +48 -0
- data/test/snappy_hadoop_test.rb +26 -0
- data/test/snappy_reader_test.rb +148 -0
- data/test/snappy_test.rb +95 -0
- data/test/snappy_writer_test.rb +55 -0
- data/test/test_helper.rb +7 -0
- data/vendor/snappy/CMakeLists.txt +297 -0
- data/vendor/snappy/CONTRIBUTING.md +26 -0
- data/vendor/snappy/COPYING +1 -1
- data/vendor/snappy/NEWS +60 -0
- data/vendor/snappy/{README → README.md} +29 -16
- data/vendor/snappy/cmake/SnappyConfig.cmake.in +33 -0
- data/vendor/snappy/cmake/config.h.in +62 -0
- data/vendor/snappy/docs/README.md +72 -0
- data/vendor/snappy/snappy-c.h +3 -3
- data/vendor/snappy/snappy-internal.h +113 -32
- data/vendor/snappy/snappy-sinksource.cc +33 -0
- data/vendor/snappy/snappy-sinksource.h +51 -6
- data/vendor/snappy/snappy-stubs-internal.cc +1 -1
- data/vendor/snappy/snappy-stubs-internal.h +160 -45
- data/vendor/snappy/snappy-stubs-public.h.in +23 -47
- data/vendor/snappy/snappy-test.cc +31 -24
- data/vendor/snappy/snappy-test.h +46 -103
- data/vendor/snappy/snappy.cc +786 -431
- data/vendor/snappy/snappy.h +37 -14
- data/vendor/snappy/snappy_compress_fuzzer.cc +59 -0
- data/vendor/snappy/snappy_uncompress_fuzzer.cc +57 -0
- data/vendor/snappy/snappy_unittest.cc +441 -290
- metadata +35 -75
- data/.travis.yml +0 -4
- data/test/test-snappy-reader.rb +0 -129
- data/test/test-snappy-writer.rb +0 -55
- data/test/test-snappy.rb +0 -58
- data/vendor/snappy/ChangeLog +0 -1916
- data/vendor/snappy/Makefile.am +0 -23
- data/vendor/snappy/autogen.sh +0 -7
- data/vendor/snappy/configure.ac +0 -133
- data/vendor/snappy/m4/gtest.m4 +0 -74
- data/vendor/snappy/testdata/alice29.txt +0 -3609
- data/vendor/snappy/testdata/asyoulik.txt +0 -4122
- data/vendor/snappy/testdata/baddata1.snappy +0 -0
- data/vendor/snappy/testdata/baddata2.snappy +0 -0
- data/vendor/snappy/testdata/baddata3.snappy +0 -0
- data/vendor/snappy/testdata/fireworks.jpeg +0 -0
- data/vendor/snappy/testdata/geo.protodata +0 -0
- data/vendor/snappy/testdata/html +0 -1
- data/vendor/snappy/testdata/html_x_4 +0 -1
- data/vendor/snappy/testdata/kppkn.gtb +0 -0
- data/vendor/snappy/testdata/lcet10.txt +0 -7519
- data/vendor/snappy/testdata/paper-100k.pdf +2 -600
- data/vendor/snappy/testdata/plrabn12.txt +0 -10699
- data/vendor/snappy/testdata/urls.10K +0 -10000
@@ -40,6 +40,21 @@ char* Sink::GetAppendBuffer(size_t length, char* scratch) {
|
|
40
40
|
return scratch;
|
41
41
|
}
|
42
42
|
|
43
|
+
char* Sink::GetAppendBufferVariable(
|
44
|
+
size_t min_size, size_t desired_size_hint, char* scratch,
|
45
|
+
size_t scratch_size, size_t* allocated_size) {
|
46
|
+
*allocated_size = scratch_size;
|
47
|
+
return scratch;
|
48
|
+
}
|
49
|
+
|
50
|
+
void Sink::AppendAndTakeOwnership(
|
51
|
+
char* bytes, size_t n,
|
52
|
+
void (*deleter)(void*, const char*, size_t),
|
53
|
+
void *deleter_arg) {
|
54
|
+
Append(bytes, n);
|
55
|
+
(*deleter)(deleter_arg, bytes, n);
|
56
|
+
}
|
57
|
+
|
43
58
|
ByteArraySource::~ByteArraySource() { }
|
44
59
|
|
45
60
|
size_t ByteArraySource::Available() const { return left_; }
|
@@ -68,4 +83,22 @@ char* UncheckedByteArraySink::GetAppendBuffer(size_t len, char* scratch) {
|
|
68
83
|
return dest_;
|
69
84
|
}
|
70
85
|
|
86
|
+
void UncheckedByteArraySink::AppendAndTakeOwnership(
|
87
|
+
char* data, size_t n,
|
88
|
+
void (*deleter)(void*, const char*, size_t),
|
89
|
+
void *deleter_arg) {
|
90
|
+
if (data != dest_) {
|
91
|
+
memcpy(dest_, data, n);
|
92
|
+
(*deleter)(deleter_arg, data, n);
|
93
|
+
}
|
94
|
+
dest_ += n;
|
95
|
+
}
|
96
|
+
|
97
|
+
char* UncheckedByteArraySink::GetAppendBufferVariable(
|
98
|
+
size_t min_size, size_t desired_size_hint, char* scratch,
|
99
|
+
size_t scratch_size, size_t* allocated_size) {
|
100
|
+
*allocated_size = desired_size_hint;
|
101
|
+
return dest_;
|
71
102
|
}
|
103
|
+
|
104
|
+
} // namespace snappy
|
@@ -26,12 +26,11 @@
|
|
26
26
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
27
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
28
|
|
29
|
-
#ifndef
|
30
|
-
#define
|
29
|
+
#ifndef THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_
|
30
|
+
#define THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_
|
31
31
|
|
32
32
|
#include <stddef.h>
|
33
33
|
|
34
|
-
|
35
34
|
namespace snappy {
|
36
35
|
|
37
36
|
// A Sink is an interface that consumes a sequence of bytes.
|
@@ -60,6 +59,47 @@ class Sink {
|
|
60
59
|
// The default implementation always returns the scratch buffer.
|
61
60
|
virtual char* GetAppendBuffer(size_t length, char* scratch);
|
62
61
|
|
62
|
+
// For higher performance, Sink implementations can provide custom
|
63
|
+
// AppendAndTakeOwnership() and GetAppendBufferVariable() methods.
|
64
|
+
// These methods can reduce the number of copies done during
|
65
|
+
// compression/decompression.
|
66
|
+
|
67
|
+
// Append "bytes[0,n-1] to the sink. Takes ownership of "bytes"
|
68
|
+
// and calls the deleter function as (*deleter)(deleter_arg, bytes, n)
|
69
|
+
// to free the buffer. deleter function must be non NULL.
|
70
|
+
//
|
71
|
+
// The default implementation just calls Append and frees "bytes".
|
72
|
+
// Other implementations may avoid a copy while appending the buffer.
|
73
|
+
virtual void AppendAndTakeOwnership(
|
74
|
+
char* bytes, size_t n, void (*deleter)(void*, const char*, size_t),
|
75
|
+
void *deleter_arg);
|
76
|
+
|
77
|
+
// Returns a writable buffer for appending and writes the buffer's capacity to
|
78
|
+
// *allocated_size. Guarantees *allocated_size >= min_size.
|
79
|
+
// May return a pointer to the caller-owned scratch buffer which must have
|
80
|
+
// scratch_size >= min_size.
|
81
|
+
//
|
82
|
+
// The returned buffer is only valid until the next operation
|
83
|
+
// on this ByteSink.
|
84
|
+
//
|
85
|
+
// After writing at most *allocated_size bytes, call Append() with the
|
86
|
+
// pointer returned from this function and the number of bytes written.
|
87
|
+
// Many Append() implementations will avoid copying bytes if this function
|
88
|
+
// returned an internal buffer.
|
89
|
+
//
|
90
|
+
// If the sink implementation allocates or reallocates an internal buffer,
|
91
|
+
// it should use the desired_size_hint if appropriate. If a caller cannot
|
92
|
+
// provide a reasonable guess at the desired capacity, it should set
|
93
|
+
// desired_size_hint = 0.
|
94
|
+
//
|
95
|
+
// If a non-scratch buffer is returned, the caller may only pass
|
96
|
+
// a prefix to it to Append(). That is, it is not correct to pass an
|
97
|
+
// interior pointer to Append().
|
98
|
+
//
|
99
|
+
// The default implementation always returns the scratch buffer.
|
100
|
+
virtual char* GetAppendBufferVariable(
|
101
|
+
size_t min_size, size_t desired_size_hint, char* scratch,
|
102
|
+
size_t scratch_size, size_t* allocated_size);
|
63
103
|
|
64
104
|
private:
|
65
105
|
// No copying
|
@@ -122,6 +162,12 @@ class UncheckedByteArraySink : public Sink {
|
|
122
162
|
virtual ~UncheckedByteArraySink();
|
123
163
|
virtual void Append(const char* data, size_t n);
|
124
164
|
virtual char* GetAppendBuffer(size_t len, char* scratch);
|
165
|
+
virtual char* GetAppendBufferVariable(
|
166
|
+
size_t min_size, size_t desired_size_hint, char* scratch,
|
167
|
+
size_t scratch_size, size_t* allocated_size);
|
168
|
+
virtual void AppendAndTakeOwnership(
|
169
|
+
char* bytes, size_t n, void (*deleter)(void*, const char*, size_t),
|
170
|
+
void *deleter_arg);
|
125
171
|
|
126
172
|
// Return the current output pointer so that a caller can see how
|
127
173
|
// many bytes were produced.
|
@@ -131,7 +177,6 @@ class UncheckedByteArraySink : public Sink {
|
|
131
177
|
char* dest_;
|
132
178
|
};
|
133
179
|
|
180
|
+
} // namespace snappy
|
134
181
|
|
135
|
-
|
136
|
-
|
137
|
-
#endif // UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_
|
182
|
+
#endif // THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_
|
@@ -28,8 +28,8 @@
|
|
28
28
|
//
|
29
29
|
// Various stubs for the open-source version of Snappy.
|
30
30
|
|
31
|
-
#ifndef
|
32
|
-
#define
|
31
|
+
#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
|
32
|
+
#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
|
33
33
|
|
34
34
|
#ifdef HAVE_CONFIG_H
|
35
35
|
#include "config.h"
|
@@ -45,6 +45,26 @@
|
|
45
45
|
#include <sys/mman.h>
|
46
46
|
#endif
|
47
47
|
|
48
|
+
#ifdef HAVE_UNISTD_H
|
49
|
+
#include <unistd.h>
|
50
|
+
#endif
|
51
|
+
|
52
|
+
#if defined(_MSC_VER)
|
53
|
+
#include <intrin.h>
|
54
|
+
#endif // defined(_MSC_VER)
|
55
|
+
|
56
|
+
#ifndef __has_feature
|
57
|
+
#define __has_feature(x) 0
|
58
|
+
#endif
|
59
|
+
|
60
|
+
#if __has_feature(memory_sanitizer)
|
61
|
+
#include <sanitizer/msan_interface.h>
|
62
|
+
#define SNAPPY_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
|
63
|
+
__msan_unpoison((address), (size))
|
64
|
+
#else
|
65
|
+
#define SNAPPY_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) /* empty */
|
66
|
+
#endif // __has_feature(memory_sanitizer)
|
67
|
+
|
48
68
|
#include "snappy-stubs-public.h"
|
49
69
|
|
50
70
|
#if defined(__x86_64__)
|
@@ -52,6 +72,14 @@
|
|
52
72
|
// Enable 64-bit optimized versions of some routines.
|
53
73
|
#define ARCH_K8 1
|
54
74
|
|
75
|
+
#elif defined(__ppc64__)
|
76
|
+
|
77
|
+
#define ARCH_PPC 1
|
78
|
+
|
79
|
+
#elif defined(__aarch64__)
|
80
|
+
|
81
|
+
#define ARCH_ARM 1
|
82
|
+
|
55
83
|
#endif
|
56
84
|
|
57
85
|
// Needed by OS X, among others.
|
@@ -59,10 +87,6 @@
|
|
59
87
|
#define MAP_ANONYMOUS MAP_ANON
|
60
88
|
#endif
|
61
89
|
|
62
|
-
// Pull in std::min, std::ostream, and the likes. This is safe because this
|
63
|
-
// header file is never used from any public header files.
|
64
|
-
using namespace std;
|
65
|
-
|
66
90
|
// The size of an array, if known at compile-time.
|
67
91
|
// Will give unexpected results if used on a pointer.
|
68
92
|
// We undefine it first, since some compilers already have a definition.
|
@@ -73,11 +97,11 @@ using namespace std;
|
|
73
97
|
|
74
98
|
// Static prediction hints.
|
75
99
|
#ifdef HAVE_BUILTIN_EXPECT
|
76
|
-
#define
|
77
|
-
#define
|
100
|
+
#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
|
101
|
+
#define SNAPPY_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
|
78
102
|
#else
|
79
|
-
#define
|
80
|
-
#define
|
103
|
+
#define SNAPPY_PREDICT_FALSE(x) x
|
104
|
+
#define SNAPPY_PREDICT_TRUE(x) x
|
81
105
|
#endif
|
82
106
|
|
83
107
|
// This is only used for recomputing the tag byte table used during
|
@@ -96,9 +120,10 @@ static const int64 kint64max = static_cast<int64>(0x7FFFFFFFFFFFFFFFLL);
|
|
96
120
|
|
97
121
|
// Potentially unaligned loads and stores.
|
98
122
|
|
99
|
-
// x86 and
|
123
|
+
// x86, PowerPC, and ARM64 can simply do these loads and stores native.
|
100
124
|
|
101
|
-
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__)
|
125
|
+
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \
|
126
|
+
defined(__aarch64__)
|
102
127
|
|
103
128
|
#define UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p))
|
104
129
|
#define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))
|
@@ -116,6 +141,15 @@ static const int64 kint64max = static_cast<int64>(0x7FFFFFFFFFFFFFFFLL);
|
|
116
141
|
// sub-architectures.
|
117
142
|
//
|
118
143
|
// This is a mess, but there's not much we can do about it.
|
144
|
+
//
|
145
|
+
// To further complicate matters, only LDR instructions (single reads) are
|
146
|
+
// allowed to be unaligned, not LDRD (two reads) or LDM (many reads). Unless we
|
147
|
+
// explicitly tell the compiler that these accesses can be unaligned, it can and
|
148
|
+
// will combine accesses. On armcc, the way to signal this is done by accessing
|
149
|
+
// through the type (uint32 __packed *), but GCC has no such attribute
|
150
|
+
// (it ignores __attribute__((packed)) on individual variables). However,
|
151
|
+
// we can tell it that a _struct_ is unaligned, which has the same effect,
|
152
|
+
// so we do that.
|
119
153
|
|
120
154
|
#elif defined(__arm__) && \
|
121
155
|
!defined(__ARM_ARCH_4__) && \
|
@@ -131,13 +165,41 @@ static const int64 kint64max = static_cast<int64>(0x7FFFFFFFFFFFFFFFLL);
|
|
131
165
|
!defined(__ARM_ARCH_6ZK__) && \
|
132
166
|
!defined(__ARM_ARCH_6T2__)
|
133
167
|
|
134
|
-
#
|
135
|
-
#define
|
168
|
+
#if __GNUC__
|
169
|
+
#define ATTRIBUTE_PACKED __attribute__((__packed__))
|
170
|
+
#else
|
171
|
+
#define ATTRIBUTE_PACKED
|
172
|
+
#endif
|
136
173
|
|
137
|
-
|
138
|
-
|
174
|
+
namespace base {
|
175
|
+
namespace internal {
|
176
|
+
|
177
|
+
struct Unaligned16Struct {
|
178
|
+
uint16 value;
|
179
|
+
uint8 dummy; // To make the size non-power-of-two.
|
180
|
+
} ATTRIBUTE_PACKED;
|
139
181
|
|
140
|
-
|
182
|
+
struct Unaligned32Struct {
|
183
|
+
uint32 value;
|
184
|
+
uint8 dummy; // To make the size non-power-of-two.
|
185
|
+
} ATTRIBUTE_PACKED;
|
186
|
+
|
187
|
+
} // namespace internal
|
188
|
+
} // namespace base
|
189
|
+
|
190
|
+
#define UNALIGNED_LOAD16(_p) \
|
191
|
+
((reinterpret_cast<const ::snappy::base::internal::Unaligned16Struct *>(_p))->value)
|
192
|
+
#define UNALIGNED_LOAD32(_p) \
|
193
|
+
((reinterpret_cast<const ::snappy::base::internal::Unaligned32Struct *>(_p))->value)
|
194
|
+
|
195
|
+
#define UNALIGNED_STORE16(_p, _val) \
|
196
|
+
((reinterpret_cast< ::snappy::base::internal::Unaligned16Struct *>(_p))->value = \
|
197
|
+
(_val))
|
198
|
+
#define UNALIGNED_STORE32(_p, _val) \
|
199
|
+
((reinterpret_cast< ::snappy::base::internal::Unaligned32Struct *>(_p))->value = \
|
200
|
+
(_val))
|
201
|
+
|
202
|
+
// TODO: NEON supports unaligned 64-bit loads and stores.
|
141
203
|
// See if that would be more efficient on platforms supporting it,
|
142
204
|
// at least for copies.
|
143
205
|
|
@@ -188,22 +250,8 @@ inline void UNALIGNED_STORE64(void *p, uint64 v) {
|
|
188
250
|
|
189
251
|
#endif
|
190
252
|
|
191
|
-
// This can be more efficient than UNALIGNED_LOAD64 + UNALIGNED_STORE64
|
192
|
-
// on some platforms, in particular ARM.
|
193
|
-
inline void UnalignedCopy64(const void *src, void *dst) {
|
194
|
-
if (sizeof(void *) == 8) {
|
195
|
-
UNALIGNED_STORE64(dst, UNALIGNED_LOAD64(src));
|
196
|
-
} else {
|
197
|
-
const char *src_char = reinterpret_cast<const char *>(src);
|
198
|
-
char *dst_char = reinterpret_cast<char *>(dst);
|
199
|
-
|
200
|
-
UNALIGNED_STORE32(dst_char, UNALIGNED_LOAD32(src_char));
|
201
|
-
UNALIGNED_STORE32(dst_char + 4, UNALIGNED_LOAD32(src_char + 4));
|
202
|
-
}
|
203
|
-
}
|
204
|
-
|
205
253
|
// The following guarantees declaration of the byte swap functions.
|
206
|
-
#
|
254
|
+
#if defined(SNAPPY_IS_BIG_ENDIAN)
|
207
255
|
|
208
256
|
#ifdef HAVE_SYS_BYTEORDER_H
|
209
257
|
#include <sys/byteorder.h>
|
@@ -260,7 +308,7 @@ inline uint64 bswap_64(uint64 x) {
|
|
260
308
|
|
261
309
|
#endif
|
262
310
|
|
263
|
-
#endif //
|
311
|
+
#endif // defined(SNAPPY_IS_BIG_ENDIAN)
|
264
312
|
|
265
313
|
// Convert to little-endian storage, opposite of network format.
|
266
314
|
// Convert x from host to little endian: x = LittleEndian.FromHost(x);
|
@@ -274,7 +322,7 @@ inline uint64 bswap_64(uint64 x) {
|
|
274
322
|
class LittleEndian {
|
275
323
|
public:
|
276
324
|
// Conversion functions.
|
277
|
-
#
|
325
|
+
#if defined(SNAPPY_IS_BIG_ENDIAN)
|
278
326
|
|
279
327
|
static uint16 FromHost16(uint16 x) { return bswap_16(x); }
|
280
328
|
static uint16 ToHost16(uint16 x) { return bswap_16(x); }
|
@@ -284,7 +332,7 @@ class LittleEndian {
|
|
284
332
|
|
285
333
|
static bool IsLittleEndian() { return false; }
|
286
334
|
|
287
|
-
#else // !defined(
|
335
|
+
#else // !defined(SNAPPY_IS_BIG_ENDIAN)
|
288
336
|
|
289
337
|
static uint16 FromHost16(uint16 x) { return x; }
|
290
338
|
static uint16 ToHost16(uint16 x) { return x; }
|
@@ -294,7 +342,7 @@ class LittleEndian {
|
|
294
342
|
|
295
343
|
static bool IsLittleEndian() { return true; }
|
296
344
|
|
297
|
-
#endif // !defined(
|
345
|
+
#endif // !defined(SNAPPY_IS_BIG_ENDIAN)
|
298
346
|
|
299
347
|
// Functions to do unaligned loads and stores in little-endian order.
|
300
348
|
static uint16 Load16(const void *p) {
|
@@ -317,6 +365,9 @@ class LittleEndian {
|
|
317
365
|
// Some bit-manipulation functions.
|
318
366
|
class Bits {
|
319
367
|
public:
|
368
|
+
// Return floor(log2(n)) for positive integer n.
|
369
|
+
static int Log2FloorNonZero(uint32 n);
|
370
|
+
|
320
371
|
// Return floor(log2(n)) for positive integer n. Returns -1 iff n == 0.
|
321
372
|
static int Log2Floor(uint32 n);
|
322
373
|
|
@@ -324,31 +375,85 @@ class Bits {
|
|
324
375
|
// undefined value if n == 0. FindLSBSetNonZero() is similar to ffs() except
|
325
376
|
// that it's 0-indexed.
|
326
377
|
static int FindLSBSetNonZero(uint32 n);
|
378
|
+
|
379
|
+
#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
327
380
|
static int FindLSBSetNonZero64(uint64 n);
|
381
|
+
#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
328
382
|
|
329
383
|
private:
|
330
|
-
|
384
|
+
// No copying
|
385
|
+
Bits(const Bits&);
|
386
|
+
void operator=(const Bits&);
|
331
387
|
};
|
332
388
|
|
333
389
|
#ifdef HAVE_BUILTIN_CTZ
|
334
390
|
|
391
|
+
inline int Bits::Log2FloorNonZero(uint32 n) {
|
392
|
+
assert(n != 0);
|
393
|
+
// (31 ^ x) is equivalent to (31 - x) for x in [0, 31]. An easy proof
|
394
|
+
// represents subtraction in base 2 and observes that there's no carry.
|
395
|
+
//
|
396
|
+
// GCC and Clang represent __builtin_clz on x86 as 31 ^ _bit_scan_reverse(x).
|
397
|
+
// Using "31 ^" here instead of "31 -" allows the optimizer to strip the
|
398
|
+
// function body down to _bit_scan_reverse(x).
|
399
|
+
return 31 ^ __builtin_clz(n);
|
400
|
+
}
|
401
|
+
|
335
402
|
inline int Bits::Log2Floor(uint32 n) {
|
336
|
-
return n == 0 ? -1 :
|
403
|
+
return (n == 0) ? -1 : Bits::Log2FloorNonZero(n);
|
337
404
|
}
|
338
405
|
|
339
406
|
inline int Bits::FindLSBSetNonZero(uint32 n) {
|
407
|
+
assert(n != 0);
|
340
408
|
return __builtin_ctz(n);
|
341
409
|
}
|
342
410
|
|
411
|
+
#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
343
412
|
inline int Bits::FindLSBSetNonZero64(uint64 n) {
|
413
|
+
assert(n != 0);
|
344
414
|
return __builtin_ctzll(n);
|
345
415
|
}
|
416
|
+
#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
346
417
|
|
347
|
-
#
|
418
|
+
#elif defined(_MSC_VER)
|
419
|
+
|
420
|
+
inline int Bits::Log2FloorNonZero(uint32 n) {
|
421
|
+
assert(n != 0);
|
422
|
+
unsigned long where;
|
423
|
+
_BitScanReverse(&where, n);
|
424
|
+
return static_cast<int>(where);
|
425
|
+
}
|
348
426
|
|
349
427
|
inline int Bits::Log2Floor(uint32 n) {
|
350
|
-
|
351
|
-
|
428
|
+
unsigned long where;
|
429
|
+
if (_BitScanReverse(&where, n))
|
430
|
+
return static_cast<int>(where);
|
431
|
+
return -1;
|
432
|
+
}
|
433
|
+
|
434
|
+
inline int Bits::FindLSBSetNonZero(uint32 n) {
|
435
|
+
assert(n != 0);
|
436
|
+
unsigned long where;
|
437
|
+
if (_BitScanForward(&where, n))
|
438
|
+
return static_cast<int>(where);
|
439
|
+
return 32;
|
440
|
+
}
|
441
|
+
|
442
|
+
#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
443
|
+
inline int Bits::FindLSBSetNonZero64(uint64 n) {
|
444
|
+
assert(n != 0);
|
445
|
+
unsigned long where;
|
446
|
+
if (_BitScanForward64(&where, n))
|
447
|
+
return static_cast<int>(where);
|
448
|
+
return 64;
|
449
|
+
}
|
450
|
+
#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
451
|
+
|
452
|
+
#else // Portable versions.
|
453
|
+
|
454
|
+
inline int Bits::Log2FloorNonZero(uint32 n) {
|
455
|
+
assert(n != 0);
|
456
|
+
|
352
457
|
int log = 0;
|
353
458
|
uint32 value = n;
|
354
459
|
for (int i = 4; i >= 0; --i) {
|
@@ -363,7 +468,13 @@ inline int Bits::Log2Floor(uint32 n) {
|
|
363
468
|
return log;
|
364
469
|
}
|
365
470
|
|
471
|
+
inline int Bits::Log2Floor(uint32 n) {
|
472
|
+
return (n == 0) ? -1 : Bits::Log2FloorNonZero(n);
|
473
|
+
}
|
474
|
+
|
366
475
|
inline int Bits::FindLSBSetNonZero(uint32 n) {
|
476
|
+
assert(n != 0);
|
477
|
+
|
367
478
|
int rc = 31;
|
368
479
|
for (int i = 4, shift = 1 << 4; i >= 0; --i) {
|
369
480
|
const uint32 x = n << shift;
|
@@ -376,8 +487,11 @@ inline int Bits::FindLSBSetNonZero(uint32 n) {
|
|
376
487
|
return rc;
|
377
488
|
}
|
378
489
|
|
490
|
+
#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
379
491
|
// FindLSBSetNonZero64() is defined in terms of FindLSBSetNonZero().
|
380
492
|
inline int Bits::FindLSBSetNonZero64(uint64 n) {
|
493
|
+
assert(n != 0);
|
494
|
+
|
381
495
|
const uint32 bottombits = static_cast<uint32>(n);
|
382
496
|
if (bottombits == 0) {
|
383
497
|
// Bottom bits are zero, so scan in top bits
|
@@ -386,6 +500,7 @@ inline int Bits::FindLSBSetNonZero64(uint64 n) {
|
|
386
500
|
return FindLSBSetNonZero(bottombits);
|
387
501
|
}
|
388
502
|
}
|
503
|
+
#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
389
504
|
|
390
505
|
#endif // End portable versions.
|
391
506
|
|
@@ -409,7 +524,7 @@ class Varint {
|
|
409
524
|
static char* Encode32(char* ptr, uint32 v);
|
410
525
|
|
411
526
|
// EFFECTS Appends the varint representation of "value" to "*s".
|
412
|
-
static void Append32(string* s, uint32 value);
|
527
|
+
static void Append32(std::string* s, uint32 value);
|
413
528
|
};
|
414
529
|
|
415
530
|
inline const char* Varint::Parse32WithLimit(const char* p,
|
@@ -466,7 +581,7 @@ inline char* Varint::Encode32(char* sptr, uint32 v) {
|
|
466
581
|
// replace this function with one that resizes the string without
|
467
582
|
// filling the new space with zeros (if applicable) --
|
468
583
|
// it will be non-portable but faster.
|
469
|
-
inline void STLStringResizeUninitialized(string* s, size_t new_size) {
|
584
|
+
inline void STLStringResizeUninitialized(std::string* s, size_t new_size) {
|
470
585
|
s->resize(new_size);
|
471
586
|
}
|
472
587
|
|
@@ -482,10 +597,10 @@ inline void STLStringResizeUninitialized(string* s, size_t new_size) {
|
|
482
597
|
// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-defects.html#530)
|
483
598
|
// proposes this as the method. It will officially be part of the standard
|
484
599
|
// for C++0x. This should already work on all current implementations.
|
485
|
-
inline char* string_as_array(string* str) {
|
600
|
+
inline char* string_as_array(std::string* str) {
|
486
601
|
return str->empty() ? NULL : &*str->begin();
|
487
602
|
}
|
488
603
|
|
489
604
|
} // namespace snappy
|
490
605
|
|
491
|
-
#endif //
|
606
|
+
#endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
|