#include <stdio.h>
#include "ldm.h"
-#include "util.h"
// Insert every (HASH_ONLY_EVERY + 1) into the hash table.
#define HASH_ONLY_EVERY 0
-#define LDM_MEMORY_USAGE 20
+#define LDM_MEMORY_USAGE 22
#define LDM_HASHLOG (LDM_MEMORY_USAGE-2)
#define LDM_HASHTABLESIZE (1 << (LDM_MEMORY_USAGE))
#define LDM_HASHTABLESIZE_U32 ((LDM_HASHTABLESIZE) >> 2)
#define LDM_OFFSET_SIZE 4
-#define WINDOW_SIZE (1 << 20)
+#define WINDOW_SIZE (1 << 29)
//These should be multiples of four.
-#define LDM_HASH_LENGTH 4
-#define MINMATCH 4
+#define LDM_HASH_LENGTH 8
+#define MINMATCH 8
#define ML_BITS 4
#define ML_MASK ((1U<<ML_BITS)-1)
//#define RUN_CHECKS
//#define LDM_DEBUG
-typedef uint8_t BYTE;
-typedef uint16_t U16;
-typedef uint32_t U32;
-typedef int32_t S32;
-typedef uint64_t U64;
-
-typedef uint32_t offset_t;
-typedef uint32_t hash_t;
-typedef signed char schar;
-
-typedef struct hashEntry {
+struct LDM_hashEntry {
offset_t offset;
-} hashEntry;
+};
-typedef struct LDM_compressStats {
+struct LDM_compressStats {
U32 numMatches;
U32 totalMatchLength;
U32 totalLiteralLength;
U32 numCollisions;
U32 numHashInserts;
-} LDM_compressStats;
+};
-typedef struct LDM_CCtx {
+struct LDM_CCtx {
size_t isize; /* Input size */
size_t maxOSize; /* Maximum output size */
LDM_compressStats stats; /* Compression statistics */
- hashEntry hashTable[LDM_HASHTABLESIZE_U32];
+ LDM_hashEntry hashTable[LDM_HASHTABLESIZE_U32];
const BYTE *lastPosHashed; /* Last position hashed */
hash_t lastHash; /* Hash corresponding to lastPosHashed */
// DEBUG
const BYTE *DEBUG_setNextHash;
-} LDM_CCtx;
+};
/**
* Outputs compression statistics.
const BYTE *curMatch = match;
for (; lengthLeft >= 8; lengthLeft -= 8) {
- if (LDM_read64(curP) != LDM_read64(curMatch)) {
+ if (MEM_read64(curP) != MEM_read64(curMatch)) {
return 0;
}
curP += 8;
curMatch += 8;
}
if (lengthLeft > 0) {
- return (LDM_read32(curP) == LDM_read32(curMatch));
+ return (MEM_read32(curP) == MEM_read32(curMatch));
}
return 1;
}
* b(k,l) = \sum_{i = k}^l ((l - i + 1) * x_i) (mod M)
* checksum(k,l) = a(k,l) + 2^{16} * b(k,l)
*/
-static U32 getChecksum(const char *data, U32 len) {
+static U32 getChecksum(const BYTE *buf, U32 len) {
U32 i;
U32 s1, s2;
- const schar *buf = (const schar *)data;
s1 = s2 = 0;
for (i = 0; i < (len - 4); i += 4) {
* Thus toRemove should correspond to data[0].
*/
static U32 updateChecksum(U32 sum, U32 len,
- schar toRemove, schar toAdd) {
+ BYTE toRemove, BYTE toAdd) {
U32 s1 = (sum & 0xffff) - toRemove + toAdd;
U32 s2 = (sum >> 16) - ((toRemove + CHECKSUM_CHAR_OFFSET) * len) + s1;
// cctx->nextSum = getChecksum((const char *)cctx->nextIp, LDM_HASH_LENGTH);
cctx->nextSum = updateChecksum(
cctx->lastSum, LDM_HASH_LENGTH,
- (schar)((cctx->lastPosHashed)[0]),
- (schar)((cctx->lastPosHashed)[LDM_HASH_LENGTH]));
+ (cctx->lastPosHashed)[0],
+ (cctx->lastPosHashed)[LDM_HASH_LENGTH]);
cctx->nextPosHashed = cctx->nextIp;
cctx->nextHash = checksumToHash(cctx->nextSum);
#ifdef RUN_CHECKS
- check = getChecksum((const char *)cctx->nextIp, LDM_HASH_LENGTH);
+ check = getChecksum(cctx->nextIp, LDM_HASH_LENGTH);
if (check != cctx->nextSum) {
printf("CHECK: setNextHash failed %u %u\n", check, cctx->nextSum);
// Hash only every HASH_ONLY_EVERY times, based on cctx->ip.
// Note: this works only when cctx->step is 1.
if (((cctx->ip - cctx->ibase) & HASH_ONLY_EVERY) == HASH_ONLY_EVERY) {
- (cctx->hashTable)[hash] = (hashEntry){ (offset_t)(cctx->ip - cctx->ibase) };
+ (cctx->hashTable)[hash] =
+ (LDM_hashEntry){ (offset_t)(cctx->ip - cctx->ibase) };
}
cctx->lastPosHashed = cctx->ip;
* Insert hash of the current position into the hash table.
*/
static void LDM_putHashOfCurrentPosition(LDM_CCtx *cctx) {
- U32 sum = getChecksum((const char *)cctx->ip, LDM_HASH_LENGTH);
+ U32 sum = getChecksum(cctx->ip, LDM_HASH_LENGTH);
hash_t hash = checksumToHash(sum);
#ifdef RUN_CHECKS
const BYTE *pInLimit) {
const BYTE * const pStart = pIn;
while (pIn < pInLimit - 1) {
- BYTE const diff = LDM_readByte(pMatch) ^ LDM_readByte(pIn);
+ BYTE const diff = (*pMatch) ^ *(pIn);
if (!diff) {
pIn++;
pMatch++;
* Update input pointer, inserting hashes into hash table along the way.
*/
static void outputBlock(LDM_CCtx *cctx,
- unsigned const literalLength,
- unsigned const offset,
- unsigned const matchLength) {
+ const unsigned literalLength,
+ const unsigned offset,
+ const unsigned matchLength) {
BYTE *token = cctx->op++;
/* Encode the literal length. */
cctx->op += literalLength;
/* Encode the offset. */
- LDM_write32(cctx->op, offset);
+ MEM_write32(cctx->op, offset);
cctx->op += LDM_OFFSET_SIZE;
/* Encode the match length. */
unsigned matchLengthRemaining = matchLength;
*token += ML_MASK;
matchLengthRemaining -= ML_MASK;
- LDM_write32(cctx->op, 0xFFFFFFFF);
+ MEM_write32(cctx->op, 0xFFFFFFFF);
while (matchLengthRemaining >= 4*0xFF) {
cctx->op += 4;
- LDM_write32(cctx->op, 0xffffffff);
+ MEM_write32(cctx->op, 0xffffffff);
matchLengthRemaining -= 4*0xFF;
}
cctx->op += matchLengthRemaining / 255;
* length) and update pointers and hashes.
*/
{
- unsigned const literalLength = (unsigned)(cctx.ip - cctx.anchor);
- unsigned const offset = cctx.ip - match;
- unsigned const matchLength = countMatchLength(
+ const unsigned literalLength = (unsigned)(cctx.ip - cctx.anchor);
+ const unsigned offset = cctx.ip - match;
+ const unsigned matchLength = countMatchLength(
cctx.ip + MINMATCH, match + MINMATCH, cctx.ihashLimit);
#ifdef COMPUTE_STATS
size_t length, offset;
/* Get the literal length. */
- unsigned const token = *(dctx.ip)++;
+ const unsigned token = *(dctx.ip)++;
if ((length = (token >> ML_BITS)) == RUN_MASK) {
unsigned s;
do {
dctx.op = cpy;
//TODO : dynamic offset size
- offset = LDM_read32(dctx.ip);
+ offset = MEM_read32(dctx.ip);
dctx.ip += LDM_OFFSET_SIZE;
match = dctx.op - offset;
return dctx.op - (BYTE *)dst;
}
+// TODO: implement and test hash function
+void LDM_test(void) {
+
+}
+
/*
void LDM_test(const void *src, size_t srcSize,
void *dst, size_t maxDstSize) {
+++ /dev/null
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include "util.h"
-
-typedef uint8_t BYTE;
-typedef uint16_t U16;
-typedef uint32_t U32;
-typedef int32_t S32;
-typedef uint64_t U64;
-
-unsigned LDM_isLittleEndian(void) {
- const union { U32 u; BYTE c[4]; } one = { 1 };
- return one.c[0];
-}
-
-U16 LDM_read16(const void *memPtr) {
- U16 val;
- memcpy(&val, memPtr, sizeof(val));
- return val;
-}
-
-U16 LDM_readLE16(const void *memPtr) {
- if (LDM_isLittleEndian()) {
- return LDM_read16(memPtr);
- } else {
- const BYTE *p = (const BYTE *)memPtr;
- return (U16)((U16)p[0] + (p[1] << 8));
- }
-}
-
-void LDM_write16(void *memPtr, U16 value){
- memcpy(memPtr, &value, sizeof(value));
-}
-
-void LDM_write32(void *memPtr, U32 value) {
- memcpy(memPtr, &value, sizeof(value));
-}
-
-void LDM_writeLE16(void *memPtr, U16 value) {
- if (LDM_isLittleEndian()) {
- LDM_write16(memPtr, value);
- } else {
- BYTE* p = (BYTE *)memPtr;
- p[0] = (BYTE) value;
- p[1] = (BYTE)(value>>8);
- }
-}
-
-U32 LDM_read32(const void *ptr) {
- return *(const U32 *)ptr;
-}
-
-U64 LDM_read64(const void *ptr) {
- return *(const U64 *)ptr;
-}
-
-void LDM_copy8(void *dst, const void *src) {
- memcpy(dst, src, 8);
-}
-
-BYTE LDM_readByte(const void *memPtr) {
- BYTE val;
- memcpy(&val, memPtr, 1);
- return val;
-}