- /* Rank of highest ranked suffix that has rank lower than the suffix
- * corresponding to this structure and either has a lower position
- * (initially) or has a position lower than the highest position at
- * which matches have been searched for so far, or LZ_SARRAY_POS_MAX if
- * there is no such suffix.
- *
- * Think of this as a pointer to the closest position in the suffix
- * array to the left that corresponds to a suffix that begins at a
- * position in the current dictionary (i.e. before the current position
- * in the window). */
- lz_sarray_pos_t prev;
-
- /* Rank of lowest ranked suffix that has rank greater than the suffix
- * corresponding to this structure and either has a lower position
- * (intially) or has a position lower than the highest position at which
- * matches have been searched for so far, or LZ_SARRAY_POS_MAX if there
- * is no such suffix.
-
- * Think of this as a pointer to the closest position in the suffix
- * array to the right that corresponds to a suffix that begins at a
- * position in the current dictionary (i.e. before the current position
- * in the window). */
- lz_sarray_pos_t next;
-
- /* Length of longest common prefix between the suffix corresponding to
- * this structure and the suffix with rank @prev, or 0 if @prev is
- * LZ_SARRAY_POS_MAX. Capped to the maximum match length. */
- lz_sarray_len_t lcpprev;
-
- /* Length of longest common prefix between the suffix corresponding to
- * this structure and the suffix with rank @next, or 0 if @next is
- * LZ_SARRAY_POS_MAX. Capped to the maximum match length. */
- lz_sarray_len_t lcpnext;
+ union {
+ /* Temporary fields used while this structure is being
+ * initialized.
+ *
+ * Note: we want the entire `struct salink' to be only 6 bytes,
+ * even though this makes "next_initial" unaligned. */
+ struct {
+ lz_sarray_pos_t next_initial;
+ lz_sarray_len_t lcpnext_initial;
+ } _packed_attribute;
+
+ struct {
+ /* Intially, the length, in bytes, of the longest common
+ * prefix (LCP) between the suffix having this rank and
+ * the suffix with the smallest larger rank that
+ * starts earlier in the window than the suffix having
+ * this rank. If no such suffix exists, this will be 0.
+ *
+ * Later, during match-finding, after the corresponding
+ * suffix has entered the LZ77 dictionary, this value
+ * may be updated by lz_sarray_update_salink() to refer
+ * instead to a lexicographically closer (but still
+ * larger) suffix that begins at a later position that
+ * has entered the LZ77 dictionary. */
+ lz_sarray_len_t lcpnext;
+
+ /* Initially, the length, in bytes, of the longest
+ * common prefix (LCP) between the suffix having this
+ * rank and the suffix with the largest smaller rank
+ * that starts earlier in the window than the suffix
+ * having this rank. If no such suffix exists, this
+ * will be 0.
+ *
+ * Later, during match-finding, after the corresponding
+ * suffix has entered the LZ77 dictionary, this value
+ * may be updated by lz_sarray_update_salink() to refer
+ * instead to a lexicographically closer (but still
+ * smaller) suffix that begins at a later position that
+ * has entered the LZ77 dictionary. */
+ lz_sarray_len_t lcpprev;
+
+ /* Distance to the suffix referred to in the description
+ * of "lcpnext" above, but capped to a maximum value to
+ * save memory; or, 0 if no such suffix exists. If the
+ * true distance was truncated, this will give the
+ * distance to the rank of a suffix that is
+ * lexicographically closer to the current suffix than
+ * the desired suffix, but appears *later* in the window
+ * and hence cannot be used as the basis for an LZ77
+ * match. */
+ lz_sarray_delta_t dist_to_next;
+
+ /* Distance to the suffix referred to in the description
+ * of "lcpprev" above, but capped to a maximum value to
+ * save memory; or, 0 if no such suffix exists. If the
+ * true distance was truncated, this will give the
+ * distance to the rank of a suffix that is
+ * lexicographically closer to the current suffix than
+ * the desired suffix, but appears *later* in the window
+ * and hence cannot be used as the basis for an LZ77
+ * match. */
+ lz_sarray_delta_t dist_to_prev;
+ };
+ };