]> wimlib.net Git - wimlib/blobdiff - include/wimlib/hc_matchfinder.h
Get rid of matchfinder_common.h and manual memsets
[wimlib] / include / wimlib / hc_matchfinder.h
index 1403a15781039a49f0400e4789ecde9667f7b261..eb509d9aa9b02d82e915203488e7c183c06b2e15 100644 (file)
@@ -54,9 +54,8 @@
  * (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));
 }
 
 /*
@@ -145,8 +153,9 @@ hc_matchfinder_init(struct hc_matchfinder *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.
  *
@@ -172,7 +181,7 @@ hc_matchfinder_longest_match(struct hc_matchfinder * const restrict mf,
        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);
@@ -185,7 +194,7 @@ hc_matchfinder_longest_match(struct hc_matchfinder * const restrict mf,
 
        /* Search the appropriate linked list for matches.  */
 
-       if (!(matchfinder_node_valid(cur_node)))
+       if (!cur_node)
                goto out;
 
        if (best_len < 3) {
@@ -199,7 +208,7 @@ hc_matchfinder_longest_match(struct hc_matchfinder * const restrict mf,
 
                        /* 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;
                }
 
@@ -209,7 +218,7 @@ hc_matchfinder_longest_match(struct hc_matchfinder * const restrict mf,
                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;
        }
 
@@ -217,8 +226,11 @@ hc_matchfinder_longest_match(struct hc_matchfinder * const restrict mf,
                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)) &&
@@ -230,7 +242,7 @@ hc_matchfinder_longest_match(struct hc_matchfinder * const restrict mf,
                                break;
 
                        cur_node = mf->next_tab[cur_node];
-                       if (!matchfinder_node_valid(cur_node) || !--depth_remaining)
+                       if (!cur_node || !--depth_remaining)
                                goto out;
                }
 
@@ -247,7 +259,7 @@ hc_matchfinder_longest_match(struct hc_matchfinder * const restrict mf,
                                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:
@@ -278,7 +290,7 @@ hc_matchfinder_skip_positions(struct hc_matchfinder * restrict mf,
 {
        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 {