Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update snappy #18

Closed
wants to merge 40 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
7dd738f
Merge pull request #3 from refuge/master
fdmanana Jun 19, 2011
3c255f1
Updated supported versions to include R15.
pmembrey Apr 20, 2012
9876d57
Merge pull request #4 from pmembrey/master
fdmanana Apr 21, 2012
07641e7
Update rebar executable.
kellymclaughlin Apr 23, 2012
516b04c
Update deprecated options in rebar.config.
kellymclaughlin Apr 23, 2012
80db168
Merge pull request #5 from kellymclaughlin/update-deprecated-rebar-opts
fdmanana Apr 23, 2012
07e8b6d
Updated rebar.config to support R16 (test suite passes)
Nov 15, 2013
05c004c
Updating to snappy 1.1.1
Nov 15, 2013
8b0d536
Merge branch 'master' of https://github.com/pmembrey/snappy-erlang-nif
Nov 15, 2013
b978761
Forgot to bump the app file
Nov 15, 2013
348da43
Merge pull request #8 from pmembrey/master
dch Mar 13, 2014
868243b
rebar: support forthcoming OTP 17.0 releases
dch Mar 13, 2014
6ac8b1d
Added test to show library compresses an empty list but won't decompr…
pmembrey May 16, 2014
9d15a21
Added test to show library compresses an empty binary but won't decom…
pmembrey May 16, 2014
fbbb707
Added a check for empty IOLists during decompression.
pmembrey May 16, 2014
990f688
Added additional tests for multiple compress / decompress and
pmembrey May 16, 2014
b9152c1
Returns empty binary and bypasses the compression library if an empty…
pmembrey May 16, 2014
73f2014
Quick refactor - only init the structs when necessary
pmembrey May 16, 2014
1d29d69
Merge pull request #10 from pmembrey/master
dch Jan 6, 2015
2c17ed5
support native clang under FreeBSD 10.1
dch Jan 6, 2015
b9d3b0d
Support big-endian builds
bryanpkc Feb 7, 2015
ec20611
Merge pull request #11 from bryanpkc/master
dch Feb 26, 2015
fddda99
Add erlang 18 support
glejeune Aug 26, 2015
76417d1
Merge pull request #13 from homeswap/master
dch Sep 29, 2015
7bc779d
Add rebar3 support (#15)
lpgauth Jul 6, 2016
b29c869
Update Snappy to 1.1.3 (#14)
lpgauth Jul 6, 2016
c4cd1bb
build: support OTP 19
dch Jul 7, 2016
0951a1b
Change to nif_error
joshuawscott Dec 7, 2016
4e3b861
Improve build on Mac
fenek Jan 25, 2017
bcfcdb4
Compile NIF using Port Compiler plugin
arcusfelis Nov 6, 2018
c1aa0e1
README celebrates your patches
dch Nov 7, 2018
a066f7a
segFault dammit
dch Nov 7, 2018
e8907ee
c_src: handle catch cleanly
dch Nov 7, 2018
b434602
as R13B is long since gone we no longer need to catch this
dch Nov 7, 2018
cfb7ae5
updated snappy to version 1.1.8
skaes Jul 24, 2020
717918f
switch to rebar3 and enc
dch Dec 2, 2020
6372bb6
Add Erlang 24 support
nickva May 17, 2021
ceaceb4
docs: note OTP-24 support
dch Sep 29, 2021
a38f7d9
Merge upstream (skunkwerks) and update Snappy to 1.1.8
big-r81 Jun 14, 2022
7b6e145
Merge branch 'main' into update-snappy
big-r81 Jun 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,41 @@ priv
*.la
*~
*.swp
_build
c_src/snappy/*.d
c_src/*.d
compile_commands.json

### Elixir ###
/_build
/cover
/deps
/doc
/.fetch
erl_crash.dump
*.ez
*.beam
/config/*.secret.exs
.elixir_ls/

### Elixir Patch ###

### Erlang ###
.eunit
*.o
*.plt
.concrete/DEV_MODE

# rebar 2.x
.rebar
rel/example_project
ebin/*.beam
deps

# rebar 3
.rebar3
_build/
_checkouts/

### Erlang Patch ###
rebar3.crashdump
43 changes: 8 additions & 35 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,41 +1,14 @@
REBAR?=rebar
all: snappy eunit

snappy:
./rebar3 compile

.PHONY: all
# target: all - Makes everything
all: build


.PHONY: build
# target: build - Builds the project
build:
$(REBAR) compile


.PHONY: check
# target: check - Checks if project builds and passes all the tests
check: build eunit
eunit:
./rebar3 eunit

check: eunit

.PHONY: clean
# target: clean - Removes build artifacts
clean:
$(REBAR) clean


.PHONY: distclean
# target: distclean - Removes all unversioned files
distclean: clean
git clean -fxd


.PHONY: eunit
# target: eunit - Runs eunit test suite
eunit:
$(REBAR) eunit

./rebar3 clean
rm -fr priv ebin

.PHONY: help
# target: help - Prints this help
help:
@egrep "^# target:" Makefile | sed -e 's/^# target: //g' | sort
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,42 @@ Google snappy's official repository and bug tracking system is at:

Its source is included in this project.

# changelog

- tag `1.1.2` as tests pass against OTP-24
- tag `otp-24` compatibility
- switch build chain to [rebar3] and [enc] requiring OTP20 or newer
- tag `snappy-1.1.8`, also first version compatible with OTP23 (thanks @skaes)
- tag `snappy-1.1.3`
- add a changelog

[rebar3]: https://rebar3.org/
[enc]: https://github.com/davisp/erlang-native-compiler

# site

https://github.com/fdmanana/snappy-erlang-nif
https://github.com/skunkwerks/snappy-erlang-nif

# credits

Software is built by a few people and maintained by many. Thank-you for
all your patches!


- Arne Ehrlich <[email protected]>
- Bryan Chan <[email protected]>
- Dave Cottlehuber <[email protected]>
- Filipe David Manana <[email protected]>
- Joshua Scott <[email protected]>
- Kelly McLaughlin <[email protected]>
- Louis-Philippe Gauthier <[email protected]>
- Mikhail Uvarov <[email protected]>
- Peter Membrey <[email protected]>
- Piotr Nosek <[email protected]>
- benoitc <[email protected]>
- @dch314
- glejeune <[email protected]>
- Stefan Kaes <[email protected]>

# performance tests

Expand Down
135 changes: 108 additions & 27 deletions c_src/snappy/snappy-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,30 @@
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"
Expand All @@ -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)) {
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)) {
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;
Expand All @@ -140,10 +164,67 @@ 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

Expand Down
2 changes: 1 addition & 1 deletion c_src/snappy/snappy-stubs-internal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

namespace snappy {

void Varint::Append32(string* s, uint32 value) {
void Varint::Append32(std::string* s, uint32 value) {
char buf[Varint::kMax32];
const char* p = Varint::Encode32(buf, value);
s->append(buf, p - buf);
Expand Down
Loading