summaryrefslogtreecommitdiff
path: root/lib/compression
diff options
context:
space:
mode:
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>2022-11-17 16:15:00 +1300
committerJoseph Sutton <jsutton@samba.org>2022-12-01 22:56:40 +0000
commitfb35cf29a426ee2cb0ee280e147627fd3e84a71d (patch)
tree5f2d631a789d1179efd008e233a046317d29a2c9 /lib/compression
parente4066b2be6d87cae130f40e3faf3a0c8815389f8 (diff)
downloadsamba-fb35cf29a426ee2cb0ee280e147627fd3e84a71d.tar.gz
lib/compression/lzxpress compression: use a write context struct
This will make it possible to move encoding operations into helper functions, which will make it easier to restructure the code to use a hash table for faster matching. Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Diffstat (limited to 'lib/compression')
-rw-r--r--lib/compression/lzxpress.c112
1 files changed, 62 insertions, 50 deletions
diff --git a/lib/compression/lzxpress.c b/lib/compression/lzxpress.c
index 6b2aeef02f6..7a1bb670bbc 100644
--- a/lib/compression/lzxpress.c
+++ b/lib/compression/lzxpress.c
@@ -48,10 +48,22 @@
} \
} while(0)
+struct write_context {
+ uint8_t *compressed;
+ uint32_t compressed_pos;
+ uint32_t max_compressed_size;
+ uint32_t indic;
+ uint32_t indic_bit;
+ uint32_t indic_pos;
+ uint32_t nibble_index;
+};
+
+
#define CHECK_INPUT_BYTES(__needed) \
__CHECK_BYTES(uncompressed_size, uncompressed_pos, __needed)
#define CHECK_OUTPUT_BYTES(__needed) \
- __CHECK_BYTES(max_compressed_size, compressed_pos, __needed)
+ __CHECK_BYTES(wc.max_compressed_size, wc.compressed_pos, __needed)
+
ssize_t lzxpress_compress(const uint8_t *uncompressed,
uint32_t uncompressed_size,
@@ -68,28 +80,28 @@ ssize_t lzxpress_compress(const uint8_t *uncompressed,
* the match length; they are always at least 16 bits long, and can
* implicitly use unused half-bytes from earlier in the stream.
*/
- uint32_t uncompressed_pos, compressed_pos;
- uint32_t indic;
- uint32_t indic_pos;
- uint32_t indic_bit, nibble_index;
+ uint32_t uncompressed_pos;
+ struct write_context wc = {
+ .indic = 0,
+ .indic_pos = 0,
+ .indic_bit = 0,
+ .nibble_index = 0,
+ .compressed = compressed,
+ .compressed_pos = 0,
+ .max_compressed_size = max_compressed_size
+ };
if (!uncompressed_size) {
return 0;
}
uncompressed_pos = 0;
- compressed_pos = 0;
- indic = 0;
CHECK_OUTPUT_BYTES(sizeof(uint32_t));
- PUSH_LE_U32(compressed, compressed_pos, 0);
- compressed_pos += sizeof(uint32_t);
- indic_pos = 0;
-
- indic_bit = 0;
- nibble_index = 0;
+ PUSH_LE_U32(wc.compressed, wc.compressed_pos, 0);
+ wc.compressed_pos += sizeof(uint32_t);
while ((uncompressed_pos < uncompressed_size) &&
- (compressed_pos < max_compressed_size)) {
+ (wc.compressed_pos < wc.max_compressed_size)) {
bool found = false;
uint32_t best_len = 2;
@@ -133,17 +145,17 @@ ssize_t lzxpress_compress(const uint8_t *uncompressed,
*/
CHECK_INPUT_BYTES(sizeof(uint8_t));
CHECK_OUTPUT_BYTES(sizeof(uint8_t));
- compressed[compressed_pos++] = uncompressed[uncompressed_pos++];
+ wc.compressed[wc.compressed_pos++] = uncompressed[uncompressed_pos++];
- indic <<= 1;
- indic_bit += 1;
+ wc.indic <<= 1;
+ wc.indic_bit += 1;
- if (indic_bit == 32) {
- PUSH_LE_U32(compressed, indic_pos, indic);
- indic_bit = 0;
+ if (wc.indic_bit == 32) {
+ PUSH_LE_U32(wc.compressed, wc.indic_pos, wc.indic);
+ wc.indic_bit = 0;
CHECK_OUTPUT_BYTES(sizeof(uint32_t));
- indic_pos = compressed_pos;
- compressed_pos += sizeof(uint32_t);
+ wc.indic_pos = wc.compressed_pos;
+ wc.compressed_pos += sizeof(uint32_t);
}
} else {
uint32_t match_len = best_len;
@@ -156,29 +168,29 @@ ssize_t lzxpress_compress(const uint8_t *uncompressed,
/* Classical meta-data */
CHECK_OUTPUT_BYTES(sizeof(uint16_t));
metadata = (uint16_t)((best_offset << 3) | MIN(match_len, 7));
- PUSH_LE_U16(compressed, compressed_pos, metadata);
- compressed_pos += sizeof(uint16_t);
+ PUSH_LE_U16(wc.compressed, wc.compressed_pos, metadata);
+ wc.compressed_pos += sizeof(uint16_t);
if (match_len >= 7) {
match_len -= 7;
- if (!nibble_index) {
- nibble_index = compressed_pos;
+ if (!wc.nibble_index) {
+ wc.nibble_index = wc.compressed_pos;
CHECK_OUTPUT_BYTES(sizeof(uint8_t));
- compressed[nibble_index] = MIN(match_len, 15);
- compressed_pos += sizeof(uint8_t);
+ wc.compressed[wc.nibble_index] = MIN(match_len, 15);
+ wc.compressed_pos += sizeof(uint8_t);
} else {
- compressed[nibble_index] |= MIN(match_len, 15) << 4;
- nibble_index = 0;
+ wc.compressed[wc.nibble_index] |= MIN(match_len, 15) << 4;
+ wc.nibble_index = 0;
}
if (match_len >= 15) {
match_len -= 15;
CHECK_OUTPUT_BYTES(sizeof(uint8_t));
- compressed[compressed_pos] = MIN(match_len, 255);
- compressed_pos += sizeof(uint8_t);
+ wc.compressed[wc.compressed_pos] = MIN(match_len, 255);
+ wc.compressed_pos += sizeof(uint8_t);
if (match_len >= 255) {
/* Additional match_len */
@@ -187,42 +199,42 @@ ssize_t lzxpress_compress(const uint8_t *uncompressed,
if (match_len < (1 << 16)) {
CHECK_OUTPUT_BYTES(sizeof(uint16_t));
- PUSH_LE_U16(compressed, compressed_pos, match_len);
- compressed_pos += sizeof(uint16_t);
+ PUSH_LE_U16(wc.compressed, wc.compressed_pos, match_len);
+ wc.compressed_pos += sizeof(uint16_t);
} else {
CHECK_OUTPUT_BYTES(sizeof(uint16_t) + sizeof(uint32_t));
- PUSH_LE_U16(compressed, compressed_pos, 0);
- compressed_pos += sizeof(uint16_t);
+ PUSH_LE_U16(wc.compressed, wc.compressed_pos, 0);
+ wc.compressed_pos += sizeof(uint16_t);
- PUSH_LE_U32(compressed, compressed_pos, match_len);
- compressed_pos += sizeof(uint32_t);
+ PUSH_LE_U32(wc.compressed, wc.compressed_pos, match_len);
+ wc.compressed_pos += sizeof(uint32_t);
}
}
}
}
- indic = (indic << 1) | 1;
- indic_bit += 1;
+ wc.indic = (wc.indic << 1) | 1;
+ wc.indic_bit += 1;
- if (indic_bit == 32) {
- PUSH_LE_U32(compressed, indic_pos, indic);
- indic_bit = 0;
+ if (wc.indic_bit == 32) {
+ PUSH_LE_U32(wc.compressed, wc.indic_pos, wc.indic);
+ wc.indic_bit = 0;
CHECK_OUTPUT_BYTES(sizeof(uint32_t));
- indic_pos = compressed_pos;
- compressed_pos += sizeof(uint32_t);
+ wc.indic_pos = wc.compressed_pos;
+ wc.compressed_pos += sizeof(uint32_t);
}
uncompressed_pos += best_len;
}
}
- if (indic_bit != 0) {
- indic <<= 32 - indic_bit;
+ if (wc.indic_bit != 0) {
+ wc.indic <<= 32 - wc.indic_bit;
}
- indic |= UINT32_MAX >> indic_bit;
- PUSH_LE_U32(compressed, indic_pos, indic);
+ wc.indic |= UINT32_MAX >> wc.indic_bit;
+ PUSH_LE_U32(wc.compressed, wc.indic_pos, wc.indic);
- return compressed_pos;
+ return wc.compressed_pos;
}
ssize_t lzxpress_decompress(const uint8_t *input,