mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #13423 from unknownbrackets/snappy
SaveState: Update to latest Snappy v1.1.8
This commit is contained in:
commit
5295d45d50
16 changed files with 1366 additions and 608 deletions
|
@ -359,6 +359,8 @@
|
|||
<ClCompile Include="..\ext\disarm.cpp" />
|
||||
<ClCompile Include="..\ext\sfmt19937\SFMT.c" />
|
||||
<ClCompile Include="..\ext\snappy\snappy-c.cpp" />
|
||||
<ClCompile Include="..\ext\snappy\snappy-sinksource.cpp" />
|
||||
<ClCompile Include="..\ext\snappy\snappy-stubs-internal.cpp" />
|
||||
<ClCompile Include="..\ext\snappy\snappy.cpp" />
|
||||
<ClCompile Include="..\git-version.cpp" />
|
||||
<ClCompile Include="..\ext\udis86\decode.c" />
|
||||
|
|
|
@ -761,6 +761,12 @@
|
|||
<ClCompile Include="HLE\Plugins.cpp">
|
||||
<Filter>HLE</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\snappy\snappy-stubs-internal.cpp">
|
||||
<Filter>Ext\Snappy</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\snappy\snappy-sinksource.cpp">
|
||||
<Filter>Ext\Snappy</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ELF\ElfReader.h">
|
||||
|
|
|
@ -836,6 +836,8 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\..\ext\snappy\snappy-c.cpp" />
|
||||
<ClCompile Include="..\..\ext\snappy\snappy.cpp" />
|
||||
<ClCompile Include="..\..\ext\snappy\snappy-sinksource.cpp" />
|
||||
<ClCompile Include="..\..\ext\snappy\snappy-stubs-internal.cpp" />
|
||||
<ClCompile Include="..\..\ext\udis86\decode.c">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
|
|
|
@ -563,6 +563,12 @@
|
|||
<ClCompile Include="..\..\ext\snappy\snappy-c.cpp">
|
||||
<Filter>Ext\snappy</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\ext\snappy\snappy-sinksource.cpp">
|
||||
<Filter>Ext\snappy</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\ext\snappy\snappy-stubs-internal.cpp">
|
||||
<Filter>Ext\snappy</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\ext\udis86\decode.c">
|
||||
<Filter>Ext\udis86</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -193,6 +193,8 @@ EXEC_AND_LIB_FILES := \
|
|||
$(SRC)/ext/libkirk/kirk_engine.c \
|
||||
$(SRC)/ext/sfmt19937/SFMT.c \
|
||||
$(SRC)/ext/snappy/snappy-c.cpp \
|
||||
$(SRC)/ext/snappy/snappy-sinksource.cpp \
|
||||
$(SRC)/ext/snappy/snappy-stubs-internal.cpp \
|
||||
$(SRC)/ext/snappy/snappy.cpp \
|
||||
$(SRC)/ext/udis86/decode.c \
|
||||
$(SRC)/ext/udis86/itab.c \
|
||||
|
|
|
@ -9,7 +9,9 @@ else()
|
|||
snappy-c.cpp
|
||||
snappy-c.h
|
||||
snappy-internal.h
|
||||
snappy-sinksource.cpp
|
||||
snappy-sinksource.h
|
||||
snappy-stubs-internal.cpp
|
||||
snappy-stubs-internal.h
|
||||
snappy-stubs-public.h
|
||||
snappy.cpp
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
* Plain C interface (a wrapper around the C++ implementation).
|
||||
*/
|
||||
|
||||
#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_
|
||||
#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_
|
||||
#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_C_H_
|
||||
#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_C_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -135,4 +135,4 @@ snappy_status snappy_validate_compressed_buffer(const char* compressed,
|
|||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_ */
|
||||
#endif /* THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_C_H_ */
|
||||
|
|
|
@ -28,29 +28,38 @@
|
|||
//
|
||||
// Internals shared between the Snappy implementation and its unittest.
|
||||
|
||||
#ifndef UTIL_SNAPPY_SNAPPY_INTERNAL_H_
|
||||
#define UTIL_SNAPPY_SNAPPY_INTERNAL_H_
|
||||
#ifndef THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_
|
||||
#define THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_
|
||||
|
||||
#include "snappy-stubs-internal.h"
|
||||
|
||||
namespace snappy {
|
||||
namespace internal {
|
||||
|
||||
// Working memory performs a single allocation to hold all scratch space
|
||||
// required for compression.
|
||||
class WorkingMemory {
|
||||
public:
|
||||
WorkingMemory() : large_table_(NULL) { }
|
||||
~WorkingMemory() { delete[] large_table_; }
|
||||
explicit WorkingMemory(size_t input_size);
|
||||
~WorkingMemory();
|
||||
|
||||
// Allocates and clears a hash table using memory in "*this",
|
||||
// stores the number of buckets in "*table_size" and returns a pointer to
|
||||
// the base of the hash table.
|
||||
uint16* GetHashTable(size_t input_size, int* table_size);
|
||||
uint16* GetHashTable(size_t fragment_size, int* table_size) const;
|
||||
char* GetScratchInput() const { return input_; }
|
||||
char* GetScratchOutput() const { return output_; }
|
||||
|
||||
private:
|
||||
uint16 small_table_[1<<10]; // 2KB
|
||||
uint16* large_table_; // Allocated only when needed
|
||||
char* mem_; // the allocated memory, never nullptr
|
||||
size_t size_; // the size of the allocated memory, never 0
|
||||
uint16* table_; // the pointer to the hashtable
|
||||
char* input_; // the pointer to the input scratch buffer
|
||||
char* output_; // the pointer to the output scratch buffer
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WorkingMemory);
|
||||
// No copying
|
||||
WorkingMemory(const WorkingMemory&);
|
||||
void operator=(const WorkingMemory&);
|
||||
};
|
||||
|
||||
// Flat array compression that does not emit the "uncompressed length"
|
||||
|
@ -70,57 +79,72 @@ char* CompressFragment(const char* input,
|
|||
uint16* table,
|
||||
const int table_size);
|
||||
|
||||
// Return the largest n such that
|
||||
// Find the largest n such that
|
||||
//
|
||||
// s1[0,n-1] == s2[0,n-1]
|
||||
// and n <= (s2_limit - s2).
|
||||
//
|
||||
// Return make_pair(n, n < 8).
|
||||
// Does not read *s2_limit or beyond.
|
||||
// Does not read *(s1 + (s2_limit - s2)) or beyond.
|
||||
// Requires that s2_limit >= s2.
|
||||
//
|
||||
// Separate implementation for x86_64, for speed. Uses the fact that
|
||||
// x86_64 is little endian.
|
||||
#if defined(ARCH_K8)
|
||||
static inline int FindMatchLength(const char* s1,
|
||||
const char* s2,
|
||||
const char* s2_limit) {
|
||||
// Separate implementation for 64-bit, little-endian cpus.
|
||||
#if !defined(SNAPPY_IS_BIG_ENDIAN) && \
|
||||
(defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM))
|
||||
static inline std::pair<size_t, bool> FindMatchLength(const char* s1,
|
||||
const char* s2,
|
||||
const char* s2_limit) {
|
||||
assert(s2_limit >= s2);
|
||||
int matched = 0;
|
||||
size_t matched = 0;
|
||||
|
||||
// This block isn't necessary for correctness; we could just start looping
|
||||
// immediately. As an optimization though, it is useful. It creates some not
|
||||
// uncommon code paths that determine, without extra effort, whether the match
|
||||
// length is less than 8. In short, we are hoping to avoid a conditional
|
||||
// branch, and perhaps get better code layout from the C++ compiler.
|
||||
if (SNAPPY_PREDICT_TRUE(s2 <= s2_limit - 8)) {
|
||||
uint64 a1 = UNALIGNED_LOAD64(s1);
|
||||
uint64 a2 = UNALIGNED_LOAD64(s2);
|
||||
if (a1 != a2) {
|
||||
return std::pair<size_t, bool>(Bits::FindLSBSetNonZero64(a1 ^ a2) >> 3,
|
||||
true);
|
||||
} else {
|
||||
matched = 8;
|
||||
s2 += 8;
|
||||
}
|
||||
}
|
||||
|
||||
// Find out how long the match is. We loop over the data 64 bits at a
|
||||
// time until we find a 64-bit block that doesn't match; then we find
|
||||
// the first non-matching bit and use that to calculate the total
|
||||
// length of the match.
|
||||
while (PREDICT_TRUE(s2 <= s2_limit - 8)) {
|
||||
if (PREDICT_FALSE(UNALIGNED_LOAD64(s2) == UNALIGNED_LOAD64(s1 + matched))) {
|
||||
while (SNAPPY_PREDICT_TRUE(s2 <= s2_limit - 8)) {
|
||||
if (UNALIGNED_LOAD64(s2) == UNALIGNED_LOAD64(s1 + matched)) {
|
||||
s2 += 8;
|
||||
matched += 8;
|
||||
} else {
|
||||
// On current (mid-2008) Opteron models there is a 3% more
|
||||
// efficient code sequence to find the first non-matching byte.
|
||||
// However, what follows is ~10% better on Intel Core 2 and newer,
|
||||
// and we expect AMD's bsf instruction to improve.
|
||||
uint64 x = UNALIGNED_LOAD64(s2) ^ UNALIGNED_LOAD64(s1 + matched);
|
||||
int matching_bits = Bits::FindLSBSetNonZero64(x);
|
||||
matched += matching_bits >> 3;
|
||||
return matched;
|
||||
assert(matched >= 8);
|
||||
return std::pair<size_t, bool>(matched, false);
|
||||
}
|
||||
}
|
||||
while (PREDICT_TRUE(s2 < s2_limit)) {
|
||||
if (PREDICT_TRUE(s1[matched] == *s2)) {
|
||||
while (SNAPPY_PREDICT_TRUE(s2 < s2_limit)) {
|
||||
if (s1[matched] == *s2) {
|
||||
++s2;
|
||||
++matched;
|
||||
} else {
|
||||
return matched;
|
||||
return std::pair<size_t, bool>(matched, matched < 8);
|
||||
}
|
||||
}
|
||||
return matched;
|
||||
return std::pair<size_t, bool>(matched, matched < 8);
|
||||
}
|
||||
#else
|
||||
static inline int FindMatchLength(const char* s1,
|
||||
const char* s2,
|
||||
const char* s2_limit) {
|
||||
static inline std::pair<size_t, bool> FindMatchLength(const char* s1,
|
||||
const char* s2,
|
||||
const char* s2_limit) {
|
||||
// Implementation based on the x86-64 version, above.
|
||||
assert(s2_limit >= s2);
|
||||
int matched = 0;
|
||||
|
@ -140,11 +164,68 @@ static inline int FindMatchLength(const char* s1,
|
|||
++matched;
|
||||
}
|
||||
}
|
||||
return matched;
|
||||
return std::pair<size_t, bool>(matched, matched < 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Lookup tables for decompression code. Give --snappy_dump_decompression_table
|
||||
// to the unit test to recompute char_table.
|
||||
|
||||
enum {
|
||||
LITERAL = 0,
|
||||
COPY_1_BYTE_OFFSET = 1, // 3 bit length + 3 bits of offset in opcode
|
||||
COPY_2_BYTE_OFFSET = 2,
|
||||
COPY_4_BYTE_OFFSET = 3
|
||||
};
|
||||
static const int kMaximumTagLength = 5; // COPY_4_BYTE_OFFSET plus the actual offset.
|
||||
|
||||
// Data stored per entry in lookup table:
|
||||
// Range Bits-used Description
|
||||
// ------------------------------------
|
||||
// 1..64 0..7 Literal/copy length encoded in opcode byte
|
||||
// 0..7 8..10 Copy offset encoded in opcode byte / 256
|
||||
// 0..4 11..13 Extra bytes after opcode
|
||||
//
|
||||
// We use eight bits for the length even though 7 would have sufficed
|
||||
// because of efficiency reasons:
|
||||
// (1) Extracting a byte is faster than a bit-field
|
||||
// (2) It properly aligns copy offset so we do not need a <<8
|
||||
static const uint16 char_table[256] = {
|
||||
0x0001, 0x0804, 0x1001, 0x2001, 0x0002, 0x0805, 0x1002, 0x2002,
|
||||
0x0003, 0x0806, 0x1003, 0x2003, 0x0004, 0x0807, 0x1004, 0x2004,
|
||||
0x0005, 0x0808, 0x1005, 0x2005, 0x0006, 0x0809, 0x1006, 0x2006,
|
||||
0x0007, 0x080a, 0x1007, 0x2007, 0x0008, 0x080b, 0x1008, 0x2008,
|
||||
0x0009, 0x0904, 0x1009, 0x2009, 0x000a, 0x0905, 0x100a, 0x200a,
|
||||
0x000b, 0x0906, 0x100b, 0x200b, 0x000c, 0x0907, 0x100c, 0x200c,
|
||||
0x000d, 0x0908, 0x100d, 0x200d, 0x000e, 0x0909, 0x100e, 0x200e,
|
||||
0x000f, 0x090a, 0x100f, 0x200f, 0x0010, 0x090b, 0x1010, 0x2010,
|
||||
0x0011, 0x0a04, 0x1011, 0x2011, 0x0012, 0x0a05, 0x1012, 0x2012,
|
||||
0x0013, 0x0a06, 0x1013, 0x2013, 0x0014, 0x0a07, 0x1014, 0x2014,
|
||||
0x0015, 0x0a08, 0x1015, 0x2015, 0x0016, 0x0a09, 0x1016, 0x2016,
|
||||
0x0017, 0x0a0a, 0x1017, 0x2017, 0x0018, 0x0a0b, 0x1018, 0x2018,
|
||||
0x0019, 0x0b04, 0x1019, 0x2019, 0x001a, 0x0b05, 0x101a, 0x201a,
|
||||
0x001b, 0x0b06, 0x101b, 0x201b, 0x001c, 0x0b07, 0x101c, 0x201c,
|
||||
0x001d, 0x0b08, 0x101d, 0x201d, 0x001e, 0x0b09, 0x101e, 0x201e,
|
||||
0x001f, 0x0b0a, 0x101f, 0x201f, 0x0020, 0x0b0b, 0x1020, 0x2020,
|
||||
0x0021, 0x0c04, 0x1021, 0x2021, 0x0022, 0x0c05, 0x1022, 0x2022,
|
||||
0x0023, 0x0c06, 0x1023, 0x2023, 0x0024, 0x0c07, 0x1024, 0x2024,
|
||||
0x0025, 0x0c08, 0x1025, 0x2025, 0x0026, 0x0c09, 0x1026, 0x2026,
|
||||
0x0027, 0x0c0a, 0x1027, 0x2027, 0x0028, 0x0c0b, 0x1028, 0x2028,
|
||||
0x0029, 0x0d04, 0x1029, 0x2029, 0x002a, 0x0d05, 0x102a, 0x202a,
|
||||
0x002b, 0x0d06, 0x102b, 0x202b, 0x002c, 0x0d07, 0x102c, 0x202c,
|
||||
0x002d, 0x0d08, 0x102d, 0x202d, 0x002e, 0x0d09, 0x102e, 0x202e,
|
||||
0x002f, 0x0d0a, 0x102f, 0x202f, 0x0030, 0x0d0b, 0x1030, 0x2030,
|
||||
0x0031, 0x0e04, 0x1031, 0x2031, 0x0032, 0x0e05, 0x1032, 0x2032,
|
||||
0x0033, 0x0e06, 0x1033, 0x2033, 0x0034, 0x0e07, 0x1034, 0x2034,
|
||||
0x0035, 0x0e08, 0x1035, 0x2035, 0x0036, 0x0e09, 0x1036, 0x2036,
|
||||
0x0037, 0x0e0a, 0x1037, 0x2037, 0x0038, 0x0e0b, 0x1038, 0x2038,
|
||||
0x0039, 0x0f04, 0x1039, 0x2039, 0x003a, 0x0f05, 0x103a, 0x203a,
|
||||
0x003b, 0x0f06, 0x103b, 0x203b, 0x003c, 0x0f07, 0x103c, 0x203c,
|
||||
0x0801, 0x0f08, 0x103d, 0x203d, 0x1001, 0x0f09, 0x103e, 0x203e,
|
||||
0x1801, 0x0f0a, 0x103f, 0x203f, 0x2001, 0x0f0b, 0x1040, 0x2040
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace snappy
|
||||
|
||||
#endif // UTIL_SNAPPY_SNAPPY_INTERNAL_H_
|
||||
#endif // THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_
|
||||
|
|
104
ext/snappy/snappy-sinksource.cpp
Normal file
104
ext/snappy/snappy-sinksource.cpp
Normal file
|
@ -0,0 +1,104 @@
|
|||
// Copyright 2011 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "snappy-sinksource.h"
|
||||
|
||||
namespace snappy {
|
||||
|
||||
Source::~Source() { }
|
||||
|
||||
Sink::~Sink() { }
|
||||
|
||||
char* Sink::GetAppendBuffer(size_t length, char* scratch) {
|
||||
return scratch;
|
||||
}
|
||||
|
||||
char* Sink::GetAppendBufferVariable(
|
||||
size_t min_size, size_t desired_size_hint, char* scratch,
|
||||
size_t scratch_size, size_t* allocated_size) {
|
||||
*allocated_size = scratch_size;
|
||||
return scratch;
|
||||
}
|
||||
|
||||
void Sink::AppendAndTakeOwnership(
|
||||
char* bytes, size_t n,
|
||||
void (*deleter)(void*, const char*, size_t),
|
||||
void *deleter_arg) {
|
||||
Append(bytes, n);
|
||||
(*deleter)(deleter_arg, bytes, n);
|
||||
}
|
||||
|
||||
ByteArraySource::~ByteArraySource() { }
|
||||
|
||||
size_t ByteArraySource::Available() const { return left_; }
|
||||
|
||||
const char* ByteArraySource::Peek(size_t* len) {
|
||||
*len = left_;
|
||||
return ptr_;
|
||||
}
|
||||
|
||||
void ByteArraySource::Skip(size_t n) {
|
||||
left_ -= n;
|
||||
ptr_ += n;
|
||||
}
|
||||
|
||||
UncheckedByteArraySink::~UncheckedByteArraySink() { }
|
||||
|
||||
void UncheckedByteArraySink::Append(const char* data, size_t n) {
|
||||
// Do no copying if the caller filled in the result of GetAppendBuffer()
|
||||
if (data != dest_) {
|
||||
memcpy(dest_, data, n);
|
||||
}
|
||||
dest_ += n;
|
||||
}
|
||||
|
||||
char* UncheckedByteArraySink::GetAppendBuffer(size_t len, char* scratch) {
|
||||
return dest_;
|
||||
}
|
||||
|
||||
void UncheckedByteArraySink::AppendAndTakeOwnership(
|
||||
char* data, size_t n,
|
||||
void (*deleter)(void*, const char*, size_t),
|
||||
void *deleter_arg) {
|
||||
if (data != dest_) {
|
||||
memcpy(dest_, data, n);
|
||||
(*deleter)(deleter_arg, data, n);
|
||||
}
|
||||
dest_ += n;
|
||||
}
|
||||
|
||||
char* UncheckedByteArraySink::GetAppendBufferVariable(
|
||||
size_t min_size, size_t desired_size_hint, char* scratch,
|
||||
size_t scratch_size, size_t* allocated_size) {
|
||||
*allocated_size = desired_size_hint;
|
||||
return dest_;
|
||||
}
|
||||
|
||||
} // namespace snappy
|
|
@ -26,12 +26,11 @@
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_
|
||||
#define UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_
|
||||
#ifndef THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_
|
||||
#define THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
namespace snappy {
|
||||
|
||||
// A Sink is an interface that consumes a sequence of bytes.
|
||||
|
@ -60,6 +59,47 @@ class Sink {
|
|||
// The default implementation always returns the scratch buffer.
|
||||
virtual char* GetAppendBuffer(size_t length, char* scratch);
|
||||
|
||||
// For higher performance, Sink implementations can provide custom
|
||||
// AppendAndTakeOwnership() and GetAppendBufferVariable() methods.
|
||||
// These methods can reduce the number of copies done during
|
||||
// compression/decompression.
|
||||
|
||||
// Append "bytes[0,n-1] to the sink. Takes ownership of "bytes"
|
||||
// and calls the deleter function as (*deleter)(deleter_arg, bytes, n)
|
||||
// to free the buffer. deleter function must be non NULL.
|
||||
//
|
||||
// The default implementation just calls Append and frees "bytes".
|
||||
// Other implementations may avoid a copy while appending the buffer.
|
||||
virtual void AppendAndTakeOwnership(
|
||||
char* bytes, size_t n, void (*deleter)(void*, const char*, size_t),
|
||||
void *deleter_arg);
|
||||
|
||||
// Returns a writable buffer for appending and writes the buffer's capacity to
|
||||
// *allocated_size. Guarantees *allocated_size >= min_size.
|
||||
// May return a pointer to the caller-owned scratch buffer which must have
|
||||
// scratch_size >= min_size.
|
||||
//
|
||||
// The returned buffer is only valid until the next operation
|
||||
// on this ByteSink.
|
||||
//
|
||||
// After writing at most *allocated_size bytes, call Append() with the
|
||||
// pointer returned from this function and the number of bytes written.
|
||||
// Many Append() implementations will avoid copying bytes if this function
|
||||
// returned an internal buffer.
|
||||
//
|
||||
// If the sink implementation allocates or reallocates an internal buffer,
|
||||
// it should use the desired_size_hint if appropriate. If a caller cannot
|
||||
// provide a reasonable guess at the desired capacity, it should set
|
||||
// desired_size_hint = 0.
|
||||
//
|
||||
// If a non-scratch buffer is returned, the caller may only pass
|
||||
// a prefix to it to Append(). That is, it is not correct to pass an
|
||||
// interior pointer to Append().
|
||||
//
|
||||
// The default implementation always returns the scratch buffer.
|
||||
virtual char* GetAppendBufferVariable(
|
||||
size_t min_size, size_t desired_size_hint, char* scratch,
|
||||
size_t scratch_size, size_t* allocated_size);
|
||||
|
||||
private:
|
||||
// No copying
|
||||
|
@ -122,6 +162,12 @@ class UncheckedByteArraySink : public Sink {
|
|||
virtual ~UncheckedByteArraySink();
|
||||
virtual void Append(const char* data, size_t n);
|
||||
virtual char* GetAppendBuffer(size_t len, char* scratch);
|
||||
virtual char* GetAppendBufferVariable(
|
||||
size_t min_size, size_t desired_size_hint, char* scratch,
|
||||
size_t scratch_size, size_t* allocated_size);
|
||||
virtual void AppendAndTakeOwnership(
|
||||
char* bytes, size_t n, void (*deleter)(void*, const char*, size_t),
|
||||
void *deleter_arg);
|
||||
|
||||
// Return the current output pointer so that a caller can see how
|
||||
// many bytes were produced.
|
||||
|
@ -131,7 +177,6 @@ class UncheckedByteArraySink : public Sink {
|
|||
char* dest_;
|
||||
};
|
||||
|
||||
} // namespace snappy
|
||||
|
||||
}
|
||||
|
||||
#endif // UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_
|
||||
#endif // THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_
|
||||
|
|
42
ext/snappy/snappy-stubs-internal.cpp
Normal file
42
ext/snappy/snappy-stubs-internal.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2011 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "snappy-stubs-internal.h"
|
||||
|
||||
namespace snappy {
|
||||
|
||||
void Varint::Append32(std::string* s, uint32 value) {
|
||||
char buf[Varint::kMax32];
|
||||
const char* p = Varint::Encode32(buf, value);
|
||||
s->append(buf, p - buf);
|
||||
}
|
||||
|
||||
} // namespace snappy
|
|
@ -28,8 +28,8 @@
|
|||
//
|
||||
// Various stubs for the open-source version of Snappy.
|
||||
|
||||
#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
|
||||
#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
|
||||
#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
|
||||
#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
|
@ -45,13 +45,41 @@
|
|||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
#if __has_feature(memory_sanitizer)
|
||||
#include <sanitizer/msan_interface.h>
|
||||
#define SNAPPY_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
|
||||
__msan_unpoison((address), (size))
|
||||
#else
|
||||
#define SNAPPY_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) /* empty */
|
||||
#endif // __has_feature(memory_sanitizer)
|
||||
|
||||
#include "snappy-stubs-public.h"
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
#if defined(__x86_64__)
|
||||
|
||||
// Enable 64-bit optimized versions of some routines.
|
||||
#define ARCH_K8 1
|
||||
|
||||
#elif defined(__ppc64__)
|
||||
|
||||
#define ARCH_PPC 1
|
||||
|
||||
#elif defined(__aarch64__)
|
||||
|
||||
#define ARCH_ARM 1
|
||||
|
||||
#endif
|
||||
|
||||
// Needed by OS X, among others.
|
||||
|
@ -59,10 +87,6 @@
|
|||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
// Pull in std::min, std::ostream, and the likes. This is safe because this
|
||||
// header file is never used from any public header files.
|
||||
using namespace std;
|
||||
|
||||
// The size of an array, if known at compile-time.
|
||||
// Will give unexpected results if used on a pointer.
|
||||
// We undefine it first, since some compilers already have a definition.
|
||||
|
@ -73,11 +97,11 @@ using namespace std;
|
|||
|
||||
// Static prediction hints.
|
||||
#ifdef HAVE_BUILTIN_EXPECT
|
||||
#define PREDICT_FALSE(x) (__builtin_expect(x, 0))
|
||||
#define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
|
||||
#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0))
|
||||
#define SNAPPY_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
|
||||
#else
|
||||
#define PREDICT_FALSE(x) x
|
||||
#define PREDICT_TRUE(x) x
|
||||
#define SNAPPY_PREDICT_FALSE(x) x
|
||||
#define SNAPPY_PREDICT_TRUE(x) x
|
||||
#endif
|
||||
|
||||
// This is only used for recomputing the tag byte table used during
|
||||
|
@ -96,13 +120,10 @@ static const int64 kint64max = static_cast<int64>(0x7FFFFFFFFFFFFFFFLL);
|
|||
|
||||
// Potentially unaligned loads and stores.
|
||||
|
||||
// x86 and PowerPC can simply do these loads and stores native.
|
||||
// x86, PowerPC, and ARM64 can simply do these loads and stores native.
|
||||
|
||||
#if defined(_M_IX86) && defined(_MSC_VER) && !defined(ARM) && !defined(MIPS) && !defined(__i386__)
|
||||
#define __i386__ 1
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(_M_X64)
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \
|
||||
defined(__aarch64__)
|
||||
|
||||
#define UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p))
|
||||
#define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))
|
||||
|
@ -120,6 +141,15 @@ static const int64 kint64max = static_cast<int64>(0x7FFFFFFFFFFFFFFFLL);
|
|||
// sub-architectures.
|
||||
//
|
||||
// This is a mess, but there's not much we can do about it.
|
||||
//
|
||||
// To further complicate matters, only LDR instructions (single reads) are
|
||||
// allowed to be unaligned, not LDRD (two reads) or LDM (many reads). Unless we
|
||||
// explicitly tell the compiler that these accesses can be unaligned, it can and
|
||||
// will combine accesses. On armcc, the way to signal this is done by accessing
|
||||
// through the type (uint32 __packed *), but GCC has no such attribute
|
||||
// (it ignores __attribute__((packed)) on individual variables). However,
|
||||
// we can tell it that a _struct_ is unaligned, which has the same effect,
|
||||
// so we do that.
|
||||
|
||||
#elif defined(__arm__) && \
|
||||
!defined(__ARM_ARCH_4__) && \
|
||||
|
@ -135,13 +165,41 @@ static const int64 kint64max = static_cast<int64>(0x7FFFFFFFFFFFFFFFLL);
|
|||
!defined(__ARM_ARCH_6ZK__) && \
|
||||
!defined(__ARM_ARCH_6T2__)
|
||||
|
||||
#define UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p))
|
||||
#define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))
|
||||
#if __GNUC__
|
||||
#define ATTRIBUTE_PACKED __attribute__((__packed__))
|
||||
#else
|
||||
#define ATTRIBUTE_PACKED
|
||||
#endif
|
||||
|
||||
#define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16 *>(_p) = (_val))
|
||||
#define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32 *>(_p) = (_val))
|
||||
namespace base {
|
||||
namespace internal {
|
||||
|
||||
// TODO(user): NEON supports unaligned 64-bit loads and stores.
|
||||
struct Unaligned16Struct {
|
||||
uint16 value;
|
||||
uint8 dummy; // To make the size non-power-of-two.
|
||||
} ATTRIBUTE_PACKED;
|
||||
|
||||
struct Unaligned32Struct {
|
||||
uint32 value;
|
||||
uint8 dummy; // To make the size non-power-of-two.
|
||||
} ATTRIBUTE_PACKED;
|
||||
|
||||
} // namespace internal
|
||||
} // namespace base
|
||||
|
||||
#define UNALIGNED_LOAD16(_p) \
|
||||
((reinterpret_cast<const ::snappy::base::internal::Unaligned16Struct *>(_p))->value)
|
||||
#define UNALIGNED_LOAD32(_p) \
|
||||
((reinterpret_cast<const ::snappy::base::internal::Unaligned32Struct *>(_p))->value)
|
||||
|
||||
#define UNALIGNED_STORE16(_p, _val) \
|
||||
((reinterpret_cast< ::snappy::base::internal::Unaligned16Struct *>(_p))->value = \
|
||||
(_val))
|
||||
#define UNALIGNED_STORE32(_p, _val) \
|
||||
((reinterpret_cast< ::snappy::base::internal::Unaligned32Struct *>(_p))->value = \
|
||||
(_val))
|
||||
|
||||
// TODO: NEON supports unaligned 64-bit loads and stores.
|
||||
// See if that would be more efficient on platforms supporting it,
|
||||
// at least for copies.
|
||||
|
||||
|
@ -192,22 +250,8 @@ inline void UNALIGNED_STORE64(void *p, uint64 v) {
|
|||
|
||||
#endif
|
||||
|
||||
// This can be more efficient than UNALIGNED_LOAD64 + UNALIGNED_STORE64
|
||||
// on some platforms, in particular ARM.
|
||||
inline void UnalignedCopy64(const void *src, void *dst) {
|
||||
if (sizeof(void *) == 8) {
|
||||
UNALIGNED_STORE64(dst, UNALIGNED_LOAD64(src));
|
||||
} else {
|
||||
const char *src_char = reinterpret_cast<const char *>(src);
|
||||
char *dst_char = reinterpret_cast<char *>(dst);
|
||||
|
||||
UNALIGNED_STORE32(dst_char, UNALIGNED_LOAD32(src_char));
|
||||
UNALIGNED_STORE32(dst_char + 4, UNALIGNED_LOAD32(src_char + 4));
|
||||
}
|
||||
}
|
||||
|
||||
// The following guarantees declaration of the byte swap functions.
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#if defined(SNAPPY_IS_BIG_ENDIAN)
|
||||
|
||||
#ifdef HAVE_SYS_BYTEORDER_H
|
||||
#include <sys/byteorder.h>
|
||||
|
@ -264,7 +308,7 @@ inline uint64 bswap_64(uint64 x) {
|
|||
|
||||
#endif
|
||||
|
||||
#endif // WORDS_BIGENDIAN
|
||||
#endif // defined(SNAPPY_IS_BIG_ENDIAN)
|
||||
|
||||
// Convert to little-endian storage, opposite of network format.
|
||||
// Convert x from host to little endian: x = LittleEndian.FromHost(x);
|
||||
|
@ -278,7 +322,7 @@ inline uint64 bswap_64(uint64 x) {
|
|||
class LittleEndian {
|
||||
public:
|
||||
// Conversion functions.
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#if defined(SNAPPY_IS_BIG_ENDIAN)
|
||||
|
||||
static uint16 FromHost16(uint16 x) { return bswap_16(x); }
|
||||
static uint16 ToHost16(uint16 x) { return bswap_16(x); }
|
||||
|
@ -288,7 +332,7 @@ class LittleEndian {
|
|||
|
||||
static bool IsLittleEndian() { return false; }
|
||||
|
||||
#else // !defined(WORDS_BIGENDIAN)
|
||||
#else // !defined(SNAPPY_IS_BIG_ENDIAN)
|
||||
|
||||
static uint16 FromHost16(uint16 x) { return x; }
|
||||
static uint16 ToHost16(uint16 x) { return x; }
|
||||
|
@ -298,7 +342,7 @@ class LittleEndian {
|
|||
|
||||
static bool IsLittleEndian() { return true; }
|
||||
|
||||
#endif // !defined(WORDS_BIGENDIAN)
|
||||
#endif // !defined(SNAPPY_IS_BIG_ENDIAN)
|
||||
|
||||
// Functions to do unaligned loads and stores in little-endian order.
|
||||
static uint16 Load16(const void *p) {
|
||||
|
@ -321,6 +365,9 @@ class LittleEndian {
|
|||
// Some bit-manipulation functions.
|
||||
class Bits {
|
||||
public:
|
||||
// Return floor(log2(n)) for positive integer n.
|
||||
static int Log2FloorNonZero(uint32 n);
|
||||
|
||||
// Return floor(log2(n)) for positive integer n. Returns -1 iff n == 0.
|
||||
static int Log2Floor(uint32 n);
|
||||
|
||||
|
@ -328,31 +375,85 @@ class Bits {
|
|||
// undefined value if n == 0. FindLSBSetNonZero() is similar to ffs() except
|
||||
// that it's 0-indexed.
|
||||
static int FindLSBSetNonZero(uint32 n);
|
||||
|
||||
#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
||||
static int FindLSBSetNonZero64(uint64 n);
|
||||
#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Bits);
|
||||
// No copying
|
||||
Bits(const Bits&);
|
||||
void operator=(const Bits&);
|
||||
};
|
||||
|
||||
#ifdef HAVE_BUILTIN_CTZ
|
||||
|
||||
inline int Bits::Log2FloorNonZero(uint32 n) {
|
||||
assert(n != 0);
|
||||
// (31 ^ x) is equivalent to (31 - x) for x in [0, 31]. An easy proof
|
||||
// represents subtraction in base 2 and observes that there's no carry.
|
||||
//
|
||||
// GCC and Clang represent __builtin_clz on x86 as 31 ^ _bit_scan_reverse(x).
|
||||
// Using "31 ^" here instead of "31 -" allows the optimizer to strip the
|
||||
// function body down to _bit_scan_reverse(x).
|
||||
return 31 ^ __builtin_clz(n);
|
||||
}
|
||||
|
||||
inline int Bits::Log2Floor(uint32 n) {
|
||||
return n == 0 ? -1 : 31 ^ __builtin_clz(n);
|
||||
return (n == 0) ? -1 : Bits::Log2FloorNonZero(n);
|
||||
}
|
||||
|
||||
inline int Bits::FindLSBSetNonZero(uint32 n) {
|
||||
assert(n != 0);
|
||||
return __builtin_ctz(n);
|
||||
}
|
||||
|
||||
#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
||||
inline int Bits::FindLSBSetNonZero64(uint64 n) {
|
||||
assert(n != 0);
|
||||
return __builtin_ctzll(n);
|
||||
}
|
||||
#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
inline int Bits::Log2FloorNonZero(uint32 n) {
|
||||
assert(n != 0);
|
||||
unsigned long where;
|
||||
_BitScanReverse(&where, n);
|
||||
return static_cast<int>(where);
|
||||
}
|
||||
|
||||
inline int Bits::Log2Floor(uint32 n) {
|
||||
unsigned long where;
|
||||
if (_BitScanReverse(&where, n))
|
||||
return static_cast<int>(where);
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline int Bits::FindLSBSetNonZero(uint32 n) {
|
||||
assert(n != 0);
|
||||
unsigned long where;
|
||||
if (_BitScanForward(&where, n))
|
||||
return static_cast<int>(where);
|
||||
return 32;
|
||||
}
|
||||
|
||||
#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
||||
inline int Bits::FindLSBSetNonZero64(uint64 n) {
|
||||
assert(n != 0);
|
||||
unsigned long where;
|
||||
if (_BitScanForward64(&where, n))
|
||||
return static_cast<int>(where);
|
||||
return 64;
|
||||
}
|
||||
#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
||||
|
||||
#else // Portable versions.
|
||||
|
||||
inline int Bits::Log2Floor(uint32 n) {
|
||||
if (n == 0)
|
||||
return -1;
|
||||
inline int Bits::Log2FloorNonZero(uint32 n) {
|
||||
assert(n != 0);
|
||||
|
||||
int log = 0;
|
||||
uint32 value = n;
|
||||
for (int i = 4; i >= 0; --i) {
|
||||
|
@ -367,7 +468,13 @@ inline int Bits::Log2Floor(uint32 n) {
|
|||
return log;
|
||||
}
|
||||
|
||||
inline int Bits::Log2Floor(uint32 n) {
|
||||
return (n == 0) ? -1 : Bits::Log2FloorNonZero(n);
|
||||
}
|
||||
|
||||
inline int Bits::FindLSBSetNonZero(uint32 n) {
|
||||
assert(n != 0);
|
||||
|
||||
int rc = 31;
|
||||
for (int i = 4, shift = 1 << 4; i >= 0; --i) {
|
||||
const uint32 x = n << shift;
|
||||
|
@ -380,8 +487,11 @@ inline int Bits::FindLSBSetNonZero(uint32 n) {
|
|||
return rc;
|
||||
}
|
||||
|
||||
#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
||||
// FindLSBSetNonZero64() is defined in terms of FindLSBSetNonZero().
|
||||
inline int Bits::FindLSBSetNonZero64(uint64 n) {
|
||||
assert(n != 0);
|
||||
|
||||
const uint32 bottombits = static_cast<uint32>(n);
|
||||
if (bottombits == 0) {
|
||||
// Bottom bits are zero, so scan in top bits
|
||||
|
@ -390,6 +500,7 @@ inline int Bits::FindLSBSetNonZero64(uint64 n) {
|
|||
return FindLSBSetNonZero(bottombits);
|
||||
}
|
||||
}
|
||||
#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)
|
||||
|
||||
#endif // End portable versions.
|
||||
|
||||
|
@ -413,7 +524,7 @@ class Varint {
|
|||
static char* Encode32(char* ptr, uint32 v);
|
||||
|
||||
// EFFECTS Appends the varint representation of "value" to "*s".
|
||||
static void Append32(string* s, uint32 value);
|
||||
static void Append32(std::string* s, uint32 value);
|
||||
};
|
||||
|
||||
inline const char* Varint::Parse32WithLimit(const char* p,
|
||||
|
@ -470,7 +581,7 @@ inline char* Varint::Encode32(char* sptr, uint32 v) {
|
|||
// replace this function with one that resizes the string without
|
||||
// filling the new space with zeros (if applicable) --
|
||||
// it will be non-portable but faster.
|
||||
inline void STLStringResizeUninitialized(string* s, size_t new_size) {
|
||||
inline void STLStringResizeUninitialized(std::string* s, size_t new_size) {
|
||||
s->resize(new_size);
|
||||
}
|
||||
|
||||
|
@ -486,10 +597,10 @@ inline void STLStringResizeUninitialized(string* s, size_t new_size) {
|
|||
// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-defects.html#530)
|
||||
// proposes this as the method. It will officially be part of the standard
|
||||
// for C++0x. This should already work on all current implementations.
|
||||
inline char* string_as_array(string* str) {
|
||||
inline char* string_as_array(std::string* str) {
|
||||
return str->empty() ? NULL : &*str->begin();
|
||||
}
|
||||
|
||||
} // namespace snappy
|
||||
|
||||
#endif // UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
|
||||
#endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// Copyright 2011 Google Inc. All Rights Reserved.
|
||||
// Author: sesse@google.com (Steinar H. Gunderson)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
|
@ -33,8 +32,8 @@
|
|||
// which is a public header. Instead, snappy-stubs-public.h is generated by
|
||||
// from snappy-stubs-public.h.in at configure time.
|
||||
|
||||
#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
|
||||
#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
|
||||
#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
|
||||
#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include <string>
|
||||
|
@ -65,4 +64,4 @@ struct iovec {
|
|||
|
||||
} // namespace snappy
|
||||
|
||||
#endif // UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
|
||||
#endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -36,10 +36,10 @@
|
|||
// using BMDiff and then compressing the output of BMDiff with
|
||||
// Snappy.
|
||||
|
||||
#ifndef UTIL_SNAPPY_SNAPPY_H__
|
||||
#define UTIL_SNAPPY_SNAPPY_H__
|
||||
#ifndef THIRD_PARTY_SNAPPY_SNAPPY_H__
|
||||
#define THIRD_PARTY_SNAPPY_SNAPPY_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include "snappy-stubs-public.h"
|
||||
|
@ -69,11 +69,12 @@ namespace snappy {
|
|||
// Higher-level string based routines (should be sufficient for most users)
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// Sets "*output" to the compressed version of "input[0,input_length-1]".
|
||||
// Original contents of *output are lost.
|
||||
// Sets "*compressed" to the compressed version of "input[0,input_length-1]".
|
||||
// Original contents of *compressed are lost.
|
||||
//
|
||||
// REQUIRES: "input[]" is not an alias of "*output".
|
||||
size_t Compress(const char* input, size_t input_length, string* output);
|
||||
// REQUIRES: "input[]" is not an alias of "*compressed".
|
||||
size_t Compress(const char* input, size_t input_length,
|
||||
std::string* compressed);
|
||||
|
||||
// Decompresses "compressed[0,compressed_length-1]" to "*uncompressed".
|
||||
// Original contents of "*uncompressed" are lost.
|
||||
|
@ -82,8 +83,20 @@ namespace snappy {
|
|||
//
|
||||
// returns false if the message is corrupted and could not be decompressed
|
||||
bool Uncompress(const char* compressed, size_t compressed_length,
|
||||
string* uncompressed);
|
||||
std::string* uncompressed);
|
||||
|
||||
// Decompresses "compressed" to "*uncompressed".
|
||||
//
|
||||
// returns false if the message is corrupted and could not be decompressed
|
||||
bool Uncompress(Source* compressed, Sink* uncompressed);
|
||||
|
||||
// This routine uncompresses as much of the "compressed" as possible
|
||||
// into sink. It returns the number of valid bytes added to sink
|
||||
// (extra invalid bytes may have been added due to errors; the caller
|
||||
// should ignore those). The emitted data typically has length
|
||||
// GetUncompressedLength(), but may be shorter if an error is
|
||||
// encountered.
|
||||
size_t UncompressAsMuchAsPossible(Source* compressed, Sink* uncompressed);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Lower-level character array based routines. May be useful for
|
||||
|
@ -124,6 +137,28 @@ namespace snappy {
|
|||
// returns false if the message is corrupted and could not be decrypted
|
||||
bool RawUncompress(Source* compressed, char* uncompressed);
|
||||
|
||||
// Given data in "compressed[0..compressed_length-1]" generated by
|
||||
// calling the Snappy::Compress routine, this routine
|
||||
// stores the uncompressed data to the iovec "iov". The number of physical
|
||||
// buffers in "iov" is given by iov_cnt and their cumulative size
|
||||
// must be at least GetUncompressedLength(compressed). The individual buffers
|
||||
// in "iov" must not overlap with each other.
|
||||
//
|
||||
// returns false if the message is corrupted and could not be decrypted
|
||||
bool RawUncompressToIOVec(const char* compressed, size_t compressed_length,
|
||||
const struct iovec* iov, size_t iov_cnt);
|
||||
|
||||
// Given data from the byte source 'compressed' generated by calling
|
||||
// the Snappy::Compress routine, this routine stores the uncompressed
|
||||
// data to the iovec "iov". The number of physical
|
||||
// buffers in "iov" is given by iov_cnt and their cumulative size
|
||||
// must be at least GetUncompressedLength(compressed). The individual buffers
|
||||
// in "iov" must not overlap with each other.
|
||||
//
|
||||
// returns false if the message is corrupted and could not be decrypted
|
||||
bool RawUncompressToIOVec(Source* compressed, const struct iovec* iov,
|
||||
size_t iov_cnt);
|
||||
|
||||
// Returns the maximal size of the compressed representation of
|
||||
// input data that is "source_bytes" bytes in length;
|
||||
size_t MaxCompressedLength(size_t source_bytes);
|
||||
|
@ -142,21 +177,31 @@ namespace snappy {
|
|||
bool IsValidCompressedBuffer(const char* compressed,
|
||||
size_t compressed_length);
|
||||
|
||||
// *** DO NOT CHANGE THE VALUE OF kBlockSize ***
|
||||
// Returns true iff the contents of "compressed" can be uncompressed
|
||||
// successfully. Does not return the uncompressed data. Takes
|
||||
// time proportional to *compressed length, but is usually at least
|
||||
// a factor of four faster than actual decompression.
|
||||
// On success, consumes all of *compressed. On failure, consumes an
|
||||
// unspecified prefix of *compressed.
|
||||
bool IsValidCompressed(Source* compressed);
|
||||
|
||||
// The size of a compression block. Note that many parts of the compression
|
||||
// code assumes that kBlockSize <= 65536; in particular, the hash table
|
||||
// can only store 16-bit offsets, and EmitCopy() also assumes the offset
|
||||
// is 65535 bytes or less. Note also that if you change this, it will
|
||||
// affect the framing format (see framing_format.txt).
|
||||
//
|
||||
// New Compression code chops up the input into blocks of at most
|
||||
// the following size. This ensures that back-references in the
|
||||
// output never cross kBlockSize block boundaries. This can be
|
||||
// helpful in implementing blocked decompression. However the
|
||||
// decompression code should not rely on this guarantee since older
|
||||
// compression code may not obey it.
|
||||
static const int kBlockLog = 15;
|
||||
static const size_t kBlockSize = 1 << kBlockLog;
|
||||
// Note that there might be older data around that is compressed with larger
|
||||
// block sizes, so the decompression code should not rely on the
|
||||
// non-existence of long backreferences.
|
||||
static constexpr int kBlockLog = 16;
|
||||
static constexpr size_t kBlockSize = 1 << kBlockLog;
|
||||
|
||||
static const int kMaxHashTableBits = 14;
|
||||
static const size_t kMaxHashTableSize = 1 << kMaxHashTableBits;
|
||||
static constexpr int kMinHashTableBits = 8;
|
||||
static constexpr size_t kMinHashTableSize = 1 << kMinHashTableBits;
|
||||
|
||||
static constexpr int kMaxHashTableBits = 14;
|
||||
static constexpr size_t kMaxHashTableSize = 1 << kMaxHashTableBits;
|
||||
} // end namespace snappy
|
||||
|
||||
|
||||
#endif // UTIL_SNAPPY_SNAPPY_H__
|
||||
#endif // THIRD_PARTY_SNAPPY_SNAPPY_H__
|
||||
|
|
|
@ -126,6 +126,8 @@ SOURCES_C += $(EXTDIR)/xxhash.c
|
|||
|
||||
SOURCES_CXX += \
|
||||
$(EXTDIR)/snappy/snappy-c.cpp \
|
||||
$(EXTDIR)/snappy/snappy-sinksource.cpp \
|
||||
$(EXTDIR)/snappy/snappy-stubs-internal.cpp \
|
||||
$(EXTDIR)/snappy/snappy.cpp
|
||||
|
||||
SOURCES_CXX += $(EXTDIR)/xbrz/xbrz.cpp
|
||||
|
|
Loading…
Add table
Reference in a new issue