xref: /freebsd/contrib/xz/src/liblzma/lz/lz_encoder_mf.c (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       lz_encoder_mf.c
4 /// \brief      Match finders
5 ///
6 //  Authors:    Igor Pavlov
7 //              Lasse Collin
8 //
9 //  This file has been put into the public domain.
10 //  You can do whatever you want with this file.
11 //
12 ///////////////////////////////////////////////////////////////////////////////
13 
14 #include "lz_encoder.h"
15 #include "lz_encoder_hash.h"
16 #include "memcmplen.h"
17 
18 
19 /// \brief      Find matches starting from the current byte
20 ///
21 /// \return     The length of the longest match found
22 extern uint32_t
23 lzma_mf_find(lzma_mf *mf, uint32_t *count_ptr, lzma_match *matches)
24 {
25 	// Call the match finder. It returns the number of length-distance
26 	// pairs found.
27 	// FIXME: Minimum count is zero, what _exactly_ is the maximum?
28 	const uint32_t count = mf->find(mf, matches);
29 
30 	// Length of the longest match; assume that no matches were found
31 	// and thus the maximum length is zero.
32 	uint32_t len_best = 0;
33 
34 	if (count > 0) {
35 #ifndef NDEBUG
36 		// Validate the matches.
37 		for (uint32_t i = 0; i < count; ++i) {
38 			assert(matches[i].len <= mf->nice_len);
39 			assert(matches[i].dist < mf->read_pos);
40 			assert(memcmp(mf_ptr(mf) - 1,
41 				mf_ptr(mf) - matches[i].dist - 2,
42 				matches[i].len) == 0);
43 		}
44 #endif
45 
46 		// The last used element in the array contains
47 		// the longest match.
48 		len_best = matches[count - 1].len;
49 
50 		// If a match of maximum search length was found, try to
51 		// extend the match to maximum possible length.
52 		if (len_best == mf->nice_len) {
53 			// The limit for the match length is either the
54 			// maximum match length supported by the LZ-based
55 			// encoder or the number of bytes left in the
56 			// dictionary, whichever is smaller.
57 			uint32_t limit = mf_avail(mf) + 1;
58 			if (limit > mf->match_len_max)
59 				limit = mf->match_len_max;
60 
61 			// Pointer to the byte we just ran through
62 			// the match finder.
63 			const uint8_t *p1 = mf_ptr(mf) - 1;
64 
65 			// Pointer to the beginning of the match. We need -1
66 			// here because the match distances are zero based.
67 			const uint8_t *p2 = p1 - matches[count - 1].dist - 1;
68 
69 			len_best = lzma_memcmplen(p1, p2, len_best, limit);
70 		}
71 	}
72 
73 	*count_ptr = count;
74 
75 	// Finally update the read position to indicate that match finder was
76 	// run for this dictionary offset.
77 	++mf->read_ahead;
78 
79 	return len_best;
80 }
81 
82 
83 /// Hash value to indicate unused element in the hash. Since we start the
84 /// positions from dict_size + 1, zero is always too far to qualify
85 /// as usable match position.
86 #define EMPTY_HASH_VALUE 0
87 
88 
89 /// Normalization must be done when lzma_mf.offset + lzma_mf.read_pos
90 /// reaches MUST_NORMALIZE_POS.
91 #define MUST_NORMALIZE_POS UINT32_MAX
92 
93 
94 /// \brief      Normalizes hash values
95 ///
96 /// The hash arrays store positions of match candidates. The positions are
97 /// relative to an arbitrary offset that is not the same as the absolute
98 /// offset in the input stream. The relative position of the current byte
99 /// is lzma_mf.offset + lzma_mf.read_pos. The distances of the matches are
100 /// the differences of the current read position and the position found from
101 /// the hash.
102 ///
103 /// To prevent integer overflows of the offsets stored in the hash arrays,
104 /// we need to "normalize" the stored values now and then. During the
105 /// normalization, we drop values that indicate distance greater than the
106 /// dictionary size, thus making space for new values.
107 static void
108 normalize(lzma_mf *mf)
109 {
110 	assert(mf->read_pos + mf->offset == MUST_NORMALIZE_POS);
111 
112 	// In future we may not want to touch the lowest bits, because there
113 	// may be match finders that use larger resolution than one byte.
114 	const uint32_t subvalue
115 			= (MUST_NORMALIZE_POS - mf->cyclic_size);
116 				// & ~((UINT32_C(1) << 10) - 1);
117 
118 	for (uint32_t i = 0; i < mf->hash_count; ++i) {
119 		// If the distance is greater than the dictionary size,
120 		// we can simply mark the hash element as empty.
121 		if (mf->hash[i] <= subvalue)
122 			mf->hash[i] = EMPTY_HASH_VALUE;
123 		else
124 			mf->hash[i] -= subvalue;
125 	}
126 
127 	for (uint32_t i = 0; i < mf->sons_count; ++i) {
128 		// Do the same for mf->son.
129 		//
130 		// NOTE: There may be uninitialized elements in mf->son.
131 		// Valgrind may complain that the "if" below depends on
132 		// an uninitialized value. In this case it is safe to ignore
133 		// the warning. See also the comments in lz_encoder_init()
134 		// in lz_encoder.c.
135 		if (mf->son[i] <= subvalue)
136 			mf->son[i] = EMPTY_HASH_VALUE;
137 		else
138 			mf->son[i] -= subvalue;
139 	}
140 
141 	// Update offset to match the new locations.
142 	mf->offset -= subvalue;
143 
144 	return;
145 }
146 
147 
148 /// Mark the current byte as processed from point of view of the match finder.
149 static void
150 move_pos(lzma_mf *mf)
151 {
152 	if (++mf->cyclic_pos == mf->cyclic_size)
153 		mf->cyclic_pos = 0;
154 
155 	++mf->read_pos;
156 	assert(mf->read_pos <= mf->write_pos);
157 
158 	if (unlikely(mf->read_pos + mf->offset == UINT32_MAX))
159 		normalize(mf);
160 }
161 
162 
163 /// When flushing, we cannot run the match finder unless there is nice_len
164 /// bytes available in the dictionary. Instead, we skip running the match
165 /// finder (indicating that no match was found), and count how many bytes we
166 /// have ignored this way.
167 ///
168 /// When new data is given after the flushing was completed, the match finder
169 /// is restarted by rewinding mf->read_pos backwards by mf->pending. Then
170 /// the missed bytes are added to the hash using the match finder's skip
171 /// function (with small amount of input, it may start using mf->pending
172 /// again if flushing).
173 ///
174 /// Due to this rewinding, we don't touch cyclic_pos or test for
175 /// normalization. It will be done when the match finder's skip function
176 /// catches up after a flush.
177 static void
178 move_pending(lzma_mf *mf)
179 {
180 	++mf->read_pos;
181 	assert(mf->read_pos <= mf->write_pos);
182 	++mf->pending;
183 }
184 
185 
186 /// Calculate len_limit and determine if there is enough input to run
187 /// the actual match finder code. Sets up "cur" and "pos". This macro
188 /// is used by all find functions and binary tree skip functions. Hash
189 /// chain skip function doesn't need len_limit so a simpler code is used
190 /// in them.
191 #define header(is_bt, len_min, ret_op) \
192 	uint32_t len_limit = mf_avail(mf); \
193 	if (mf->nice_len <= len_limit) { \
194 		len_limit = mf->nice_len; \
195 	} else if (len_limit < (len_min) \
196 			|| (is_bt && mf->action == LZMA_SYNC_FLUSH)) { \
197 		assert(mf->action != LZMA_RUN); \
198 		move_pending(mf); \
199 		ret_op; \
200 	} \
201 	const uint8_t *cur = mf_ptr(mf); \
202 	const uint32_t pos = mf->read_pos + mf->offset
203 
204 
205 /// Header for find functions. "return 0" indicates that zero matches
206 /// were found.
207 #define header_find(is_bt, len_min) \
208 	header(is_bt, len_min, return 0); \
209 	uint32_t matches_count = 0
210 
211 
212 /// Header for a loop in a skip function. "continue" tells to skip the rest
213 /// of the code in the loop.
214 #define header_skip(is_bt, len_min) \
215 	header(is_bt, len_min, continue)
216 
217 
218 /// Calls hc_find_func() or bt_find_func() and calculates the total number
219 /// of matches found. Updates the dictionary position and returns the number
220 /// of matches found.
221 #define call_find(func, len_best) \
222 do { \
223 	matches_count = (uint32_t)(func(len_limit, pos, cur, cur_match, \
224 				mf->depth, mf->son, \
225 				mf->cyclic_pos, mf->cyclic_size, \
226 				matches + matches_count, len_best) \
227 			- matches); \
228 	move_pos(mf); \
229 	return matches_count; \
230 } while (0)
231 
232 
233 ////////////////
234 // Hash Chain //
235 ////////////////
236 
237 #if defined(HAVE_MF_HC3) || defined(HAVE_MF_HC4)
238 ///
239 ///
240 /// \param      len_limit       Don't look for matches longer than len_limit.
241 /// \param      pos             lzma_mf.read_pos + lzma_mf.offset
242 /// \param      cur             Pointer to current byte (mf_ptr(mf))
243 /// \param      cur_match       Start position of the current match candidate
244 /// \param      depth           Maximum length of the hash chain
245 /// \param      son             lzma_mf.son (contains the hash chain)
246 /// \param      cyclic_pos      lzma_mf.cyclic_pos
247 /// \param      cyclic_size     lzma_mf_cyclic_size
248 /// \param      matches         Array to hold the matches.
249 /// \param      len_best        The length of the longest match found so far.
250 static lzma_match *
251 hc_find_func(
252 		const uint32_t len_limit,
253 		const uint32_t pos,
254 		const uint8_t *const cur,
255 		uint32_t cur_match,
256 		uint32_t depth,
257 		uint32_t *const son,
258 		const uint32_t cyclic_pos,
259 		const uint32_t cyclic_size,
260 		lzma_match *matches,
261 		uint32_t len_best)
262 {
263 	son[cyclic_pos] = cur_match;
264 
265 	while (true) {
266 		const uint32_t delta = pos - cur_match;
267 		if (depth-- == 0 || delta >= cyclic_size)
268 			return matches;
269 
270 		const uint8_t *const pb = cur - delta;
271 		cur_match = son[cyclic_pos - delta
272 				+ (delta > cyclic_pos ? cyclic_size : 0)];
273 
274 		if (pb[len_best] == cur[len_best] && pb[0] == cur[0]) {
275 			uint32_t len = lzma_memcmplen(pb, cur, 1, len_limit);
276 
277 			if (len_best < len) {
278 				len_best = len;
279 				matches->len = len;
280 				matches->dist = delta - 1;
281 				++matches;
282 
283 				if (len == len_limit)
284 					return matches;
285 			}
286 		}
287 	}
288 }
289 
290 
291 #define hc_find(len_best) \
292 	call_find(hc_find_func, len_best)
293 
294 
295 #define hc_skip() \
296 do { \
297 	mf->son[mf->cyclic_pos] = cur_match; \
298 	move_pos(mf); \
299 } while (0)
300 
301 #endif
302 
303 
304 #ifdef HAVE_MF_HC3
305 extern uint32_t
306 lzma_mf_hc3_find(lzma_mf *mf, lzma_match *matches)
307 {
308 	header_find(false, 3);
309 
310 	hash_3_calc();
311 
312 	const uint32_t delta2 = pos - mf->hash[hash_2_value];
313 	const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];
314 
315 	mf->hash[hash_2_value] = pos;
316 	mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
317 
318 	uint32_t len_best = 2;
319 
320 	if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
321 		len_best = lzma_memcmplen(cur - delta2, cur,
322 				len_best, len_limit);
323 
324 		matches[0].len = len_best;
325 		matches[0].dist = delta2 - 1;
326 		matches_count = 1;
327 
328 		if (len_best == len_limit) {
329 			hc_skip();
330 			return 1; // matches_count
331 		}
332 	}
333 
334 	hc_find(len_best);
335 }
336 
337 
338 extern void
339 lzma_mf_hc3_skip(lzma_mf *mf, uint32_t amount)
340 {
341 	do {
342 		if (mf_avail(mf) < 3) {
343 			move_pending(mf);
344 			continue;
345 		}
346 
347 		const uint8_t *cur = mf_ptr(mf);
348 		const uint32_t pos = mf->read_pos + mf->offset;
349 
350 		hash_3_calc();
351 
352 		const uint32_t cur_match
353 				= mf->hash[FIX_3_HASH_SIZE + hash_value];
354 
355 		mf->hash[hash_2_value] = pos;
356 		mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
357 
358 		hc_skip();
359 
360 	} while (--amount != 0);
361 }
362 #endif
363 
364 
365 #ifdef HAVE_MF_HC4
366 extern uint32_t
367 lzma_mf_hc4_find(lzma_mf *mf, lzma_match *matches)
368 {
369 	header_find(false, 4);
370 
371 	hash_4_calc();
372 
373 	uint32_t delta2 = pos - mf->hash[hash_2_value];
374 	const uint32_t delta3
375 			= pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value];
376 	const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];
377 
378 	mf->hash[hash_2_value ] = pos;
379 	mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
380 	mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
381 
382 	uint32_t len_best = 1;
383 
384 	if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
385 		len_best = 2;
386 		matches[0].len = 2;
387 		matches[0].dist = delta2 - 1;
388 		matches_count = 1;
389 	}
390 
391 	if (delta2 != delta3 && delta3 < mf->cyclic_size
392 			&& *(cur - delta3) == *cur) {
393 		len_best = 3;
394 		matches[matches_count++].dist = delta3 - 1;
395 		delta2 = delta3;
396 	}
397 
398 	if (matches_count != 0) {
399 		len_best = lzma_memcmplen(cur - delta2, cur,
400 				len_best, len_limit);
401 
402 		matches[matches_count - 1].len = len_best;
403 
404 		if (len_best == len_limit) {
405 			hc_skip();
406 			return matches_count;
407 		}
408 	}
409 
410 	if (len_best < 3)
411 		len_best = 3;
412 
413 	hc_find(len_best);
414 }
415 
416 
417 extern void
418 lzma_mf_hc4_skip(lzma_mf *mf, uint32_t amount)
419 {
420 	do {
421 		if (mf_avail(mf) < 4) {
422 			move_pending(mf);
423 			continue;
424 		}
425 
426 		const uint8_t *cur = mf_ptr(mf);
427 		const uint32_t pos = mf->read_pos + mf->offset;
428 
429 		hash_4_calc();
430 
431 		const uint32_t cur_match
432 				= mf->hash[FIX_4_HASH_SIZE + hash_value];
433 
434 		mf->hash[hash_2_value] = pos;
435 		mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
436 		mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
437 
438 		hc_skip();
439 
440 	} while (--amount != 0);
441 }
442 #endif
443 
444 
445 /////////////////
446 // Binary Tree //
447 /////////////////
448 
449 #if defined(HAVE_MF_BT2) || defined(HAVE_MF_BT3) || defined(HAVE_MF_BT4)
450 static lzma_match *
451 bt_find_func(
452 		const uint32_t len_limit,
453 		const uint32_t pos,
454 		const uint8_t *const cur,
455 		uint32_t cur_match,
456 		uint32_t depth,
457 		uint32_t *const son,
458 		const uint32_t cyclic_pos,
459 		const uint32_t cyclic_size,
460 		lzma_match *matches,
461 		uint32_t len_best)
462 {
463 	uint32_t *ptr0 = son + (cyclic_pos << 1) + 1;
464 	uint32_t *ptr1 = son + (cyclic_pos << 1);
465 
466 	uint32_t len0 = 0;
467 	uint32_t len1 = 0;
468 
469 	while (true) {
470 		const uint32_t delta = pos - cur_match;
471 		if (depth-- == 0 || delta >= cyclic_size) {
472 			*ptr0 = EMPTY_HASH_VALUE;
473 			*ptr1 = EMPTY_HASH_VALUE;
474 			return matches;
475 		}
476 
477 		uint32_t *const pair = son + ((cyclic_pos - delta
478 				+ (delta > cyclic_pos ? cyclic_size : 0))
479 				<< 1);
480 
481 		const uint8_t *const pb = cur - delta;
482 		uint32_t len = my_min(len0, len1);
483 
484 		if (pb[len] == cur[len]) {
485 			len = lzma_memcmplen(pb, cur, len + 1, len_limit);
486 
487 			if (len_best < len) {
488 				len_best = len;
489 				matches->len = len;
490 				matches->dist = delta - 1;
491 				++matches;
492 
493 				if (len == len_limit) {
494 					*ptr1 = pair[0];
495 					*ptr0 = pair[1];
496 					return matches;
497 				}
498 			}
499 		}
500 
501 		if (pb[len] < cur[len]) {
502 			*ptr1 = cur_match;
503 			ptr1 = pair + 1;
504 			cur_match = *ptr1;
505 			len1 = len;
506 		} else {
507 			*ptr0 = cur_match;
508 			ptr0 = pair;
509 			cur_match = *ptr0;
510 			len0 = len;
511 		}
512 	}
513 }
514 
515 
516 static void
517 bt_skip_func(
518 		const uint32_t len_limit,
519 		const uint32_t pos,
520 		const uint8_t *const cur,
521 		uint32_t cur_match,
522 		uint32_t depth,
523 		uint32_t *const son,
524 		const uint32_t cyclic_pos,
525 		const uint32_t cyclic_size)
526 {
527 	uint32_t *ptr0 = son + (cyclic_pos << 1) + 1;
528 	uint32_t *ptr1 = son + (cyclic_pos << 1);
529 
530 	uint32_t len0 = 0;
531 	uint32_t len1 = 0;
532 
533 	while (true) {
534 		const uint32_t delta = pos - cur_match;
535 		if (depth-- == 0 || delta >= cyclic_size) {
536 			*ptr0 = EMPTY_HASH_VALUE;
537 			*ptr1 = EMPTY_HASH_VALUE;
538 			return;
539 		}
540 
541 		uint32_t *pair = son + ((cyclic_pos - delta
542 				+ (delta > cyclic_pos ? cyclic_size : 0))
543 				<< 1);
544 		const uint8_t *pb = cur - delta;
545 		uint32_t len = my_min(len0, len1);
546 
547 		if (pb[len] == cur[len]) {
548 			len = lzma_memcmplen(pb, cur, len + 1, len_limit);
549 
550 			if (len == len_limit) {
551 				*ptr1 = pair[0];
552 				*ptr0 = pair[1];
553 				return;
554 			}
555 		}
556 
557 		if (pb[len] < cur[len]) {
558 			*ptr1 = cur_match;
559 			ptr1 = pair + 1;
560 			cur_match = *ptr1;
561 			len1 = len;
562 		} else {
563 			*ptr0 = cur_match;
564 			ptr0 = pair;
565 			cur_match = *ptr0;
566 			len0 = len;
567 		}
568 	}
569 }
570 
571 
572 #define bt_find(len_best) \
573 	call_find(bt_find_func, len_best)
574 
575 #define bt_skip() \
576 do { \
577 	bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, \
578 			mf->son, mf->cyclic_pos, \
579 			mf->cyclic_size); \
580 	move_pos(mf); \
581 } while (0)
582 
583 #endif
584 
585 
586 #ifdef HAVE_MF_BT2
587 extern uint32_t
588 lzma_mf_bt2_find(lzma_mf *mf, lzma_match *matches)
589 {
590 	header_find(true, 2);
591 
592 	hash_2_calc();
593 
594 	const uint32_t cur_match = mf->hash[hash_value];
595 	mf->hash[hash_value] = pos;
596 
597 	bt_find(1);
598 }
599 
600 
601 extern void
602 lzma_mf_bt2_skip(lzma_mf *mf, uint32_t amount)
603 {
604 	do {
605 		header_skip(true, 2);
606 
607 		hash_2_calc();
608 
609 		const uint32_t cur_match = mf->hash[hash_value];
610 		mf->hash[hash_value] = pos;
611 
612 		bt_skip();
613 
614 	} while (--amount != 0);
615 }
616 #endif
617 
618 
619 #ifdef HAVE_MF_BT3
620 extern uint32_t
621 lzma_mf_bt3_find(lzma_mf *mf, lzma_match *matches)
622 {
623 	header_find(true, 3);
624 
625 	hash_3_calc();
626 
627 	const uint32_t delta2 = pos - mf->hash[hash_2_value];
628 	const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];
629 
630 	mf->hash[hash_2_value] = pos;
631 	mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
632 
633 	uint32_t len_best = 2;
634 
635 	if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
636 		len_best = lzma_memcmplen(
637 				cur, cur - delta2, len_best, len_limit);
638 
639 		matches[0].len = len_best;
640 		matches[0].dist = delta2 - 1;
641 		matches_count = 1;
642 
643 		if (len_best == len_limit) {
644 			bt_skip();
645 			return 1; // matches_count
646 		}
647 	}
648 
649 	bt_find(len_best);
650 }
651 
652 
653 extern void
654 lzma_mf_bt3_skip(lzma_mf *mf, uint32_t amount)
655 {
656 	do {
657 		header_skip(true, 3);
658 
659 		hash_3_calc();
660 
661 		const uint32_t cur_match
662 				= mf->hash[FIX_3_HASH_SIZE + hash_value];
663 
664 		mf->hash[hash_2_value] = pos;
665 		mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
666 
667 		bt_skip();
668 
669 	} while (--amount != 0);
670 }
671 #endif
672 
673 
674 #ifdef HAVE_MF_BT4
675 extern uint32_t
676 lzma_mf_bt4_find(lzma_mf *mf, lzma_match *matches)
677 {
678 	header_find(true, 4);
679 
680 	hash_4_calc();
681 
682 	uint32_t delta2 = pos - mf->hash[hash_2_value];
683 	const uint32_t delta3
684 			= pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value];
685 	const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];
686 
687 	mf->hash[hash_2_value] = pos;
688 	mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
689 	mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
690 
691 	uint32_t len_best = 1;
692 
693 	if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
694 		len_best = 2;
695 		matches[0].len = 2;
696 		matches[0].dist = delta2 - 1;
697 		matches_count = 1;
698 	}
699 
700 	if (delta2 != delta3 && delta3 < mf->cyclic_size
701 			&& *(cur - delta3) == *cur) {
702 		len_best = 3;
703 		matches[matches_count++].dist = delta3 - 1;
704 		delta2 = delta3;
705 	}
706 
707 	if (matches_count != 0) {
708 		len_best = lzma_memcmplen(
709 				cur, cur - delta2, len_best, len_limit);
710 
711 		matches[matches_count - 1].len = len_best;
712 
713 		if (len_best == len_limit) {
714 			bt_skip();
715 			return matches_count;
716 		}
717 	}
718 
719 	if (len_best < 3)
720 		len_best = 3;
721 
722 	bt_find(len_best);
723 }
724 
725 
726 extern void
727 lzma_mf_bt4_skip(lzma_mf *mf, uint32_t amount)
728 {
729 	do {
730 		header_skip(true, 4);
731 
732 		hash_4_calc();
733 
734 		const uint32_t cur_match
735 				= mf->hash[FIX_4_HASH_SIZE + hash_value];
736 
737 		mf->hash[hash_2_value] = pos;
738 		mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
739 		mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
740 
741 		bt_skip();
742 
743 	} while (--amount != 0);
744 }
745 #endif
746