/**
* Create a hash table that can contain size elements.
* The number of buckets is determined by size >> HASH_BUCKET_SIZE_LOG.
+ *
+ * Returns NULL if table creation failed.
*/
static LDM_hashTable *HASH_createTable(U32 size) {
LDM_hashTable *table = malloc(sizeof(LDM_hashTable));
+ if (!table) return NULL;
+
table->numBuckets = size >> HASH_BUCKET_SIZE_LOG;
table->numEntries = size;
table->entries = calloc(size, sizeof(LDM_hashEntry));
table->bucketOffsets = calloc(size >> HASH_BUCKET_SIZE_LOG, sizeof(BYTE));
+
+ if (!table->entries || !table->bucketOffsets) {
+ free(table->bucketOffsets);
+ free(table->entries);
+ free(table);
+ return NULL;
+ }
+
return table;
}
putHashOfCurrentPositionFromHash(cctx, hash);
}
-void LDM_initializeCCtx(LDM_CCtx *cctx,
- const void *src, size_t srcSize,
- void *dst, size_t maxDstSize) {
+size_t LDM_initializeCCtx(LDM_CCtx *cctx,
+ const void *src, size_t srcSize,
+ void *dst, size_t maxDstSize) {
cctx->isize = srcSize;
cctx->maxOSize = maxDstSize;
#else
cctx->hashTable = HASH_createTable(LDM_HASHTABLESIZE_U32);
#endif
+
+ if (!cctx->hashTable) return 1;
+
cctx->stats.minOffset = UINT_MAX;
cctx->stats.windowSizeLog = LDM_WINDOW_SIZE_LOG;
cctx->stats.hashTableSizeLog = LDM_MEMORY_USAGE;
-
cctx->lastPosHashed = NULL;
cctx->step = 1; // Fixed to be 1 for now. Changing may break things.
cctx->nextIp = cctx->ip + cctx->step;
cctx->nextPosHashed = 0;
+
+ return 0;
}
void LDM_destroyCCtx(LDM_CCtx *cctx) {
U64 forwardMatchLength = 0;
U64 backwardsMatchLength = 0;
- LDM_initializeCCtx(&cctx, src, srcSize, dst, maxDstSize);
+ if (LDM_initializeCCtx(&cctx, src, srcSize, dst, maxDstSize)) {
+ // Initialization failed.
+ return 0;
+ }
#ifdef OUTPUT_CONFIGURATION
LDM_outputConfiguration();
* is less than the minimum match length), then stop searching for matches
* and encode the final literals.
*/
- while (LDM_findBestMatch(&cctx, &match, &forwardMatchLength,
- &backwardsMatchLength) == 0) {
+ while (!LDM_findBestMatch(&cctx, &match, &forwardMatchLength,
+ &backwardsMatchLength)) {
#ifdef COMPUTE_STATS
cctx.stats.numMatches++;
/**
* Compresses src into dst.
+ * Returns the compressed size if successful, 0 otherwise.
*
* NB: This currently ignores maxDstSize and assumes enough space is available.
*
* Initialize the compression context.
*
* Allocates memory for the hash table.
+ *
+ * Returns 0 if successful, 1 otherwise.
*/
-void LDM_initializeCCtx(LDM_CCtx *cctx,
- const void *src, size_t srcSize,
- void *dst, size_t maxDstSize);
+size_t LDM_initializeCCtx(LDM_CCtx *cctx,
+ const void *src, size_t srcSize,
+ void *dst, size_t maxDstSize);
/**
* Frees up memory allocated in LDM_initializeCCtx().
#include "ldm.h"
+/**
+ * This function reads the header at the beginning of src and writes
+ * the compressed and decompressed size to compressedSize and
+ * decompressedSize.
+ *
+ * The header consists of 16 bytes: 8 bytes each in little-endian format
+ * of the compressed size and the decompressed size.
+ */
void LDM_readHeader(const void *src, U64 *compressedSize,
U64 *decompressedSize) {
const BYTE *ip = (const BYTE *)src;
*compressedSize = MEM_readLE64(ip);
- ip += sizeof(U64);
- *decompressedSize = MEM_readLE64(ip);
- // ip += sizeof(U64);
+ *decompressedSize = MEM_readLE64(ip + 8);
}
+/**
+ * Writes the 16-byte header (8-bytes each of the compressedSize and
+ * decompressedSize in little-endian format) to memPtr.
+ */
void LDM_writeHeader(void *memPtr, U64 compressedSize,
U64 decompressedSize) {
- MEM_write64(memPtr, compressedSize);
- MEM_write64((BYTE *)memPtr + 8, decompressedSize);
+ MEM_writeLE64(memPtr, compressedSize);
+ MEM_writeLE64((BYTE *)memPtr + 8, decompressedSize);
}
struct LDM_DCtx {
#include "ldm.h"
#include "zstd.h"
-// #define DECOMPRESS_AND_VERIFY
+#define DECOMPRESS_AND_VERIFY
/* Compress file given by fname and output to oname.
* Returns 0 if successful, error code otherwise.
}
/* Verify the input file is the same as the decompressed file. */
-static void verify(const char *inpFilename, const char *decFilename) {
- FILE *inpFp = fopen(inpFilename, "rb");
- FILE *decFp = fopen(decFilename, "rb");
+static int verify(const char *inpFilename, const char *decFilename) {
+ FILE *inpFp, *decFp;
+
+ if ((inpFp = fopen(inpFilename, "rb")) == NULL) {
+ perror("Could not open input file\n");
+ return 1;
+ }
+
+ if ((decFp = fopen(decFilename, "rb")) == NULL) {
+ perror("Could not open decompressed file\n");
+ return 1;
+ }
printf("verify : %s <-> %s\n", inpFilename, decFilename);
{
fclose(decFp);
fclose(inpFp);
+ return 0;
}
#endif