summaryrefslogtreecommitdiff
path: root/snappy.cc
diff options
context:
space:
mode:
Diffstat (limited to 'snappy.cc')
-rw-r--r--snappy.cc72
1 files changed, 50 insertions, 22 deletions
diff --git a/snappy.cc b/snappy.cc
index c79edb5..799a640 100644
--- a/snappy.cc
+++ b/snappy.cc
@@ -435,12 +435,26 @@ char* CompressFragment(const char* input,
// bool CheckLength() const;
//
// // Called repeatedly during decompression
-// bool Append(const char* ip, uint32 length, bool allow_fast_path);
+// bool Append(const char* ip, uint32 length);
// bool AppendFromSelf(uint32 offset, uint32 length);
-// };
//
-// "allow_fast_path" is a parameter that says if there is at least 16
-// readable bytes in "ip". It is currently only used by SnappyArrayWriter.
+// // The difference between TryFastAppend and Append is that TryFastAppend
+// // is allowed to read up to <available> bytes from the input buffer,
+// // whereas Append is allowed to read <length>.
+// //
+// // Also, TryFastAppend is allowed to return false, declining the append,
+// // without it being a fatal error -- just "return false" would be
+// // a perfectly legal implementation of TryFastAppend. The intention
+// // is for TryFastAppend to allow a fast path in the common case of
+// // a small append.
+// //
+// // NOTE(user): TryFastAppend must always return decline (return false)
+// // if <length> is 61 or more, as in this case the literal length is not
+// // decoded fully. In practice, this should not be a big problem,
+// // as it is unlikely that one would implement a fast path accepting
+// // this much data.
+// bool TryFastAppend(const char* ip, uint32 available, uint32 length);
+// };
// -----------------------------------------------------------------------
// Lookup table for decompression code. Generated by ComputeTable() below.
@@ -665,19 +679,23 @@ class SnappyDecompressor {
const unsigned char c = *(reinterpret_cast<const unsigned char*>(ip++));
if ((c & 0x3) == LITERAL) {
- uint32 literal_length = c >> 2;
- if (PREDICT_FALSE(literal_length >= 60)) {
+ uint32 literal_length = (c >> 2) + 1;
+ if (writer->TryFastAppend(ip, ip_limit_ - ip, literal_length)) {
+ DCHECK_LT(literal_length, 61);
+ ip += literal_length;
+ continue;
+ }
+ if (PREDICT_FALSE(literal_length >= 61)) {
// Long literal.
- const uint32 literal_length_length = literal_length - 59;
+ const uint32 literal_length_length = literal_length - 60;
literal_length =
- LittleEndian::Load32(ip) & wordmask[literal_length_length];
+ (LittleEndian::Load32(ip) & wordmask[literal_length_length]) + 1;
ip += literal_length_length;
}
- ++literal_length;
uint32 avail = ip_limit_ - ip;
while (avail < literal_length) {
- if (!writer->Append(ip, avail, false)) return;
+ if (!writer->Append(ip, avail)) return;
literal_length -= avail;
reader_->Skip(peeked_);
size_t n;
@@ -687,8 +705,7 @@ class SnappyDecompressor {
if (avail == 0) return; // Premature end of input
ip_limit_ = ip + avail;
}
- bool allow_fast_path = (avail >= 16);
- if (!writer->Append(ip, literal_length, allow_fast_path)) {
+ if (!writer->Append(ip, literal_length)) {
return;
}
ip += literal_length;
@@ -902,21 +919,29 @@ class SnappyArrayWriter {
return op_ == op_limit_;
}
- inline bool Append(const char* ip, uint32 len, bool allow_fast_path) {
+ inline bool Append(const char* ip, uint32 len) {
char* op = op_;
const int space_left = op_limit_ - op;
- if (allow_fast_path && len <= 16 && space_left >= 16) {
- // Fast path, used for the majority (about 90%) of dynamic invocations.
+ if (space_left < len) {
+ return false;
+ }
+ memcpy(op, ip, len);
+ op_ = op + len;
+ return true;
+ }
+
+ inline bool TryFastAppend(const char* ip, uint32 available, uint32 len) {
+ char* op = op_;
+ const int space_left = op_limit_ - op;
+ if (len <= 16 && available >= 16 && space_left >= 16) {
+ // Fast path, used for the majority (about 95%) of invocations.
UNALIGNED_STORE64(op, UNALIGNED_LOAD64(ip));
UNALIGNED_STORE64(op + 8, UNALIGNED_LOAD64(ip + 8));
+ op_ = op + len;
+ return true;
} else {
- if (space_left < len) {
- return false;
- }
- memcpy(op, ip, len);
+ return false;
}
- op_ = op + len;
- return true;
}
inline bool AppendFromSelf(uint32 offset, uint32 len) {
@@ -985,10 +1010,13 @@ class SnappyDecompressionValidator {
inline bool CheckLength() const {
return expected_ == produced_;
}
- inline bool Append(const char* ip, uint32 len, bool allow_fast_path) {
+ inline bool Append(const char* ip, uint32 len) {
produced_ += len;
return produced_ <= expected_;
}
+ inline bool TryFastAppend(const char* ip, uint32 available, uint32 length) {
+ return false;
+ }
inline bool AppendFromSelf(uint32 offset, uint32 len) {
if (produced_ <= offset - 1u) return false; // -1u catches offset==0
produced_ += len;