* (and therefore reduced cache pressure), the code only uses 32-bit integers if
* they are needed to represent all possible positions.
*
- * You must allocate the 'struct hc_matchfinder' on a
- * MATCHFINDER_ALIGNMENT-aligned boundary, and its necessary allocation size
- * must be gotten by calling hc_matchfinder_size().
+ * The number of bytes that must be allocated for a given 'struct
+ * hc_matchfinder' must be gotten by calling hc_matchfinder_size().
*
* ----------------------------------------------------------------------------
*
#ifndef _HC_MATCHFINDER_H
#define _HC_MATCHFINDER_H
+#ifndef MATCHFINDER_MAX_WINDOW_ORDER
+# error "MATCHFINDER_MAX_WINDOW_ORDER must be defined!"
+#endif
+
+#include <string.h>
+
#include "wimlib/lz_extend.h"
#include "wimlib/lz_hash.h"
-#include "wimlib/matchfinder_common.h"
#include "wimlib/unaligned.h"
#if MATCHFINDER_MAX_WINDOW_ORDER < 14
# define HC_MATCHFINDER_HASH_ORDER 15
#endif
-#define HC_MATCHFINDER_HASH_LENGTH (1UL << HC_MATCHFINDER_HASH_ORDER)
+#if MATCHFINDER_MAX_WINDOW_ORDER <= 16
+typedef u16 pos_t;
+#else
+typedef u32 pos_t;
+#endif
struct hc_matchfinder {
- pos_t hash_tab[HC_MATCHFINDER_HASH_LENGTH];
+ pos_t hash_tab[1UL << HC_MATCHFINDER_HASH_ORDER];
pos_t next_tab[];
-} _aligned_attribute(MATCHFINDER_ALIGNMENT);
+};
/* Return the number of bytes that must be allocated for a 'hc_matchfinder' that
* can work with buffers up to the specified size. */
static inline size_t
hc_matchfinder_size(size_t max_bufsize)
{
- return sizeof(pos_t) * (HC_MATCHFINDER_HASH_LENGTH + max_bufsize);
+ return sizeof(struct hc_matchfinder) + (max_bufsize * sizeof(pos_t));
}
/* Prepare the matchfinder for a new input buffer. */
static inline void
hc_matchfinder_init(struct hc_matchfinder *mf)
{
- matchfinder_init(mf->hash_tab, HC_MATCHFINDER_HASH_LENGTH);
+ memset(mf, 0, sizeof(*mf));
}
/*
* The maximum permissible match length at this position.
* @nice_len
* Stop searching if a match of at least this length is found.
+ * Must be <= @max_len.
* @max_search_depth
- * Limit on the number of potential matches to consider.
+ * Limit on the number of potential matches to consider. Must be >= 1.
* @offset_ret
* If a match is found, its offset is returned in this location.
*
pos_t cur_node;
/* Insert the current sequence into the appropriate linked list. */
- if (unlikely(max_len < LZ_HASH_REQUIRED_NBYTES))
+ if (unlikely(max_len < LOAD_U24_REQUIRED_NBYTES))
goto out;
first_3_bytes = load_u24_unaligned(in_next);
hash = lz_hash(first_3_bytes, HC_MATCHFINDER_HASH_ORDER);
/* Search the appropriate linked list for matches. */
- if (!(matchfinder_node_valid(cur_node)))
+ if (!cur_node)
goto out;
if (best_len < 3) {
/* The first 3 bytes did not match. Keep trying. */
cur_node = mf->next_tab[cur_node];
- if (!matchfinder_node_valid(cur_node) || !--depth_remaining)
+ if (!cur_node || !--depth_remaining)
goto out;
}
if (best_len >= nice_len)
goto out;
cur_node = mf->next_tab[cur_node];
- if (!matchfinder_node_valid(cur_node) || !--depth_remaining)
+ if (!cur_node || !--depth_remaining)
goto out;
}
for (;;) {
matchptr = &in_begin[cur_node];
- /* Already found a length 3 match. Try for a longer match;
- * start by checking the last 2 bytes and the first 4 bytes. */
+ /* Already found a length 3 match. Try for a longer
+ * match; start by checking either the last 4 bytes and
+ * the first 4 bytes, or the last byte. (The last byte,
+ * the one which would extend the match length by 1, is
+ * the most important.) */
#if UNALIGNED_ACCESS_IS_FAST
if ((load_u32_unaligned(matchptr + best_len - 3) ==
load_u32_unaligned(in_next + best_len - 3)) &&
break;
cur_node = mf->next_tab[cur_node];
- if (!matchfinder_node_valid(cur_node) || !--depth_remaining)
+ if (!cur_node || !--depth_remaining)
goto out;
}
goto out;
}
cur_node = mf->next_tab[cur_node];
- if (!matchfinder_node_valid(cur_node) || !--depth_remaining)
+ if (!cur_node || !--depth_remaining)
goto out;
}
out:
{
u32 hash;
- if (unlikely(in_next + count >= in_end - LZ_HASH_REQUIRED_NBYTES))
+ if (unlikely(in_next + count >= in_end - LZ_HASH3_REQUIRED_NBYTES))
return;
do {