summaryrefslogtreecommitdiff
path: root/ext/compressors/snappy/snappy_compress.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/compressors/snappy/snappy_compress.c')
-rw-r--r--ext/compressors/snappy/snappy_compress.c119
1 files changed, 68 insertions, 51 deletions
diff --git a/ext/compressors/snappy/snappy_compress.c b/ext/compressors/snappy/snappy_compress.c
index 981e334a2de..32f1ddcb9a0 100644
--- a/ext/compressors/snappy/snappy_compress.c
+++ b/ext/compressors/snappy/snappy_compress.c
@@ -31,10 +31,20 @@
#include <stdlib.h>
#include <string.h>
+/*
+ * We need to include the configuration file to detect whether this extension
+ * is being built into the WiredTiger library; application-loaded compression
+ * functions won't need it.
+ */
#include <wiredtiger_config.h>
+
#include <wiredtiger.h>
#include <wiredtiger_ext.h>
+#ifdef _MSC_VER
+#define inline __inline
+#endif
+
/* Local compressor structure. */
typedef struct {
WT_COMPRESSOR compressor; /* Must come first */
@@ -42,6 +52,12 @@ typedef struct {
WT_EXTENSION_API *wt_api; /* Extension API */
} SNAPPY_COMPRESSOR;
+/*
+ * Snappy decompression requires an exact compressed byte count. WiredTiger
+ * doesn't track that value, store it in the destination buffer.
+ */
+#define SNAPPY_PREFIX sizeof(uint64_t)
+
#ifdef WORDS_BIGENDIAN
/*
* snappy_bswap64 --
@@ -64,11 +80,11 @@ snappy_bswap64(uint64_t v)
#endif
/*
- * wt_snappy_error --
+ * snappy_error --
* Output an error message, and return a standard error code.
*/
static int
-wt_snappy_error(WT_COMPRESSOR *compressor,
+snappy_error(WT_COMPRESSOR *compressor,
WT_SESSION *session, const char *call, snappy_status snret)
{
WT_EXTENSION_API *wt_api;
@@ -94,68 +110,69 @@ wt_snappy_error(WT_COMPRESSOR *compressor,
}
/*
- * wt_snappy_compress --
+ * snappy_compression --
* WiredTiger snappy compression.
*/
static int
-wt_snappy_compress(WT_COMPRESSOR *compressor, WT_SESSION *session,
+snappy_compression(WT_COMPRESSOR *compressor, WT_SESSION *session,
uint8_t *src, size_t src_len,
uint8_t *dst, size_t dst_len,
size_t *result_lenp, int *compression_failed)
{
snappy_status snret;
size_t snaplen;
+ uint64_t snaplen_u64;
char *snapbuf;
/*
- * dst_len was computed in wt_snappy_pre_size, so we know it's big
- * enough. Skip past the space we'll use to store the final count
- * of compressed bytes.
+ * dst_len was computed in snappy_pre_size, so we know it's big enough.
+ * Skip past the space we'll use to store the final count of compressed
+ * bytes.
*/
- snaplen = dst_len - sizeof(size_t);
- snapbuf = (char *)dst + sizeof(size_t);
+ snaplen = dst_len - SNAPPY_PREFIX;
+ snapbuf = (char *)dst + SNAPPY_PREFIX;
/* snaplen is an input and an output arg. */
snret = snappy_compress((char *)src, src_len, snapbuf, &snaplen);
- if (snret == SNAPPY_OK) {
- if (snaplen + sizeof(size_t) < src_len) {
- *result_lenp = snaplen + sizeof(size_t);
- *compression_failed = 0;
-
- /*
- * On decompression, snappy requires an exact compressed
- * byte count (the current value of snaplen). WiredTiger
- * does not preserve that value, so save snaplen at the
- * beginning of the destination buffer.
- *
- * Store the value in little-endian format.
- */
+ if (snret == SNAPPY_OK && snaplen + SNAPPY_PREFIX < src_len) {
+ *result_lenp = snaplen + SNAPPY_PREFIX;
+ *compression_failed = 0;
+
+ /*
+ * On decompression, snappy requires an exact compressed byte
+ * count (the current value of snaplen). WiredTiger does not
+ * preserve that value, so save snaplen at the beginning of
+ * the destination buffer.
+ *
+ * Store the value in little-endian format.
+ */
+ snaplen_u64 = snaplen;
#ifdef WORDS_BIGENDIAN
- snaplen = snappy_bswap64(snaplen);
+ snaplen_u64 = snappy_bswap64(snaplen_u64);
#endif
- *(size_t *)dst = snaplen;
- } else
- /* The compressor failed to produce a smaller result. */
- *compression_failed = 1;
+ *(uint64_t *)dst = snaplen_u64;
return (0);
}
- return (wt_snappy_error(compressor, session, "snappy_compress", snret));
+
+ *compression_failed = 1;
+ return (snret == SNAPPY_OK ?
+ 0 : snappy_error(compressor, session, "snappy_compress", snret));
}
/*
- * wt_snappy_decompress --
+ * snappy_decompression --
* WiredTiger snappy decompression.
*/
static int
-wt_snappy_decompress(WT_COMPRESSOR *compressor, WT_SESSION *session,
+snappy_decompression(WT_COMPRESSOR *compressor, WT_SESSION *session,
uint8_t *src, size_t src_len,
uint8_t *dst, size_t dst_len,
size_t *result_lenp)
{
WT_EXTENSION_API *wt_api;
snappy_status snret;
- size_t snaplen;
+ uint64_t snaplen;
wt_api = ((SNAPPY_COMPRESSOR *)compressor)->wt_api;
@@ -163,36 +180,36 @@ wt_snappy_decompress(WT_COMPRESSOR *compressor, WT_SESSION *session,
* Retrieve the saved length, handling little- to big-endian conversion
* as necessary.
*/
- snaplen = *(size_t *)src;
+ snaplen = *(uint64_t *)src;
#ifdef WORDS_BIGENDIAN
snaplen = snappy_bswap64(snaplen);
#endif
- if (snaplen + sizeof(size_t) > src_len) {
+ if (snaplen + SNAPPY_PREFIX > src_len) {
(void)wt_api->err_printf(wt_api,
session,
- "wt_snappy_decompress: stored size exceeds buffer size");
+ "WT_COMPRESSOR.decompress: stored size exceeds source "
+ "size");
return (WT_ERROR);
}
/* dst_len is an input and an output arg. */
snret = snappy_uncompress(
- (char *)src + sizeof(size_t), snaplen, (char *)dst, &dst_len);
+ (char *)src + SNAPPY_PREFIX,
+ (size_t)snaplen, (char *)dst, &dst_len);
if (snret == SNAPPY_OK) {
*result_lenp = dst_len;
return (0);
}
-
- return (
- wt_snappy_error(compressor, session, "snappy_decompress", snret));
+ return (snappy_error(compressor, session, "snappy_decompress", snret));
}
/*
- * wt_snappy_pre_size --
+ * snappy_pre_size --
* WiredTiger snappy destination buffer sizing.
*/
static int
-wt_snappy_pre_size(WT_COMPRESSOR *compressor, WT_SESSION *session,
+snappy_pre_size(WT_COMPRESSOR *compressor, WT_SESSION *session,
uint8_t *src, size_t src_len,
size_t *result_lenp)
{
@@ -203,19 +220,19 @@ wt_snappy_pre_size(WT_COMPRESSOR *compressor, WT_SESSION *session,
/*
* Snappy requires the dest buffer be somewhat larger than the source.
* Fortunately, this is fast to compute, and will give us a dest buffer
- * in wt_snappy_compress that we can compress to directly. We add space
+ * in snappy_compress that we can compress to directly. We add space
* in the dest buffer to store the accurate compressed size.
*/
- *result_lenp = snappy_max_compressed_length(src_len) + sizeof(size_t);
+ *result_lenp = snappy_max_compressed_length(src_len) + SNAPPY_PREFIX;
return (0);
}
/*
- * wt_snappy_terminate --
+ * snappy_terminate --
* WiredTiger snappy compression termination.
*/
static int
-wt_snappy_terminate(WT_COMPRESSOR *compressor, WT_SESSION *session)
+snappy_terminate(WT_COMPRESSOR *compressor, WT_SESSION *session)
{
(void)session; /* Unused parameters */
@@ -227,9 +244,9 @@ int snappy_extension_init(WT_CONNECTION *, WT_CONFIG_ARG *);
/*
* snappy_extension_init --
- * WiredTiger snappy compression extension - called directly when
- * Snappy support is built in, or via wiredtiger_extension_init when
- * snappy support is included via extension loading.
+ * WiredTiger snappy compression extension - called directly when snappy
+ * support is built in, or via wiredtiger_extension_init when snappy support
+ * is included via extension loading.
*/
int
snappy_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config)
@@ -241,11 +258,11 @@ snappy_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config)
if ((snappy_compressor = calloc(1, sizeof(SNAPPY_COMPRESSOR))) == NULL)
return (errno);
- snappy_compressor->compressor.compress = wt_snappy_compress;
+ snappy_compressor->compressor.compress = snappy_compression;
snappy_compressor->compressor.compress_raw = NULL;
- snappy_compressor->compressor.decompress = wt_snappy_decompress;
- snappy_compressor->compressor.pre_size = wt_snappy_pre_size;
- snappy_compressor->compressor.terminate = wt_snappy_terminate;
+ snappy_compressor->compressor.decompress = snappy_decompression;
+ snappy_compressor->compressor.pre_size = snappy_pre_size;
+ snappy_compressor->compressor.terminate = snappy_terminate;
snappy_compressor->wt_api = connection->get_extension_api(connection);