lizard_parser_pricefast.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #define LIZARD_PRICEFAST_MIN_OFFSET 8
  2. FORCE_INLINE int Lizard_FindMatchFast(Lizard_stream_t* ctx, intptr_t matchIndex, intptr_t matchIndex3, /* Index table will be updated */
  3. const BYTE* ip, const BYTE* const iLimit,
  4. const BYTE** matchpos)
  5. {
  6. const BYTE* const base = ctx->base;
  7. const BYTE* const dictBase = ctx->dictBase;
  8. const intptr_t dictLimit = ctx->dictLimit;
  9. const BYTE* const dictEnd = dictBase + dictLimit;
  10. const intptr_t maxDistance = (1 << ctx->params.windowLog) - 1;
  11. const intptr_t current = (U32)(ip - base);
  12. const intptr_t lowLimit = ((intptr_t)ctx->lowLimit + maxDistance >= current) ? (intptr_t)ctx->lowLimit : current - maxDistance;
  13. const BYTE* const lowPrefixPtr = base + dictLimit;
  14. const size_t minMatchLongOff = ctx->params.minMatchLongOff;
  15. const BYTE* match, *matchDict;
  16. size_t ml=0, mlt;
  17. if (ctx->last_off >= LIZARD_PRICEFAST_MIN_OFFSET) {
  18. intptr_t matchIndexLO = (ip - ctx->last_off) - base;
  19. if (matchIndexLO >= lowLimit) {
  20. if (matchIndexLO >= dictLimit) {
  21. match = base + matchIndexLO;
  22. if (MEM_readMINMATCH(match) == MEM_readMINMATCH(ip)) {
  23. mlt = Lizard_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH;
  24. // if ((mlt >= minMatchLongOff) || (ctx->last_off < LIZARD_MAX_16BIT_OFFSET))
  25. {
  26. *matchpos = match;
  27. return (int)mlt;
  28. }
  29. }
  30. } else {
  31. match = dictBase + matchIndexLO;
  32. if ((U32)((dictLimit-1) - matchIndexLO) >= 3) /* intentional overflow */
  33. if (MEM_readMINMATCH(match) == MEM_readMINMATCH(ip)) {
  34. mlt = Lizard_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, lowPrefixPtr) + MINMATCH;
  35. // if ((mlt >= minMatchLongOff) || (ctx->last_off < LIZARD_MAX_16BIT_OFFSET))
  36. {
  37. *matchpos = base + matchIndexLO; /* virtual matchpos */
  38. return (int)mlt;
  39. }
  40. }
  41. }
  42. }
  43. }
  44. #if MINMATCH == 3
  45. if (matchIndex3 < current && matchIndex3 >= lowLimit) {
  46. intptr_t offset = current - matchIndex3;
  47. if (offset < LIZARD_MAX_8BIT_OFFSET) {
  48. match = ip - offset;
  49. if (match > base && MEM_readMINMATCH(ip) == MEM_readMINMATCH(match)) {
  50. ml = 3;//Lizard_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH;
  51. *matchpos = match;
  52. }
  53. }
  54. }
  55. #else
  56. (void)matchIndex3;
  57. #endif
  58. if ((matchIndex < current) && (matchIndex >= lowLimit)) {
  59. match = base + matchIndex;
  60. if ((U32)(ip - match) >= LIZARD_PRICEFAST_MIN_OFFSET) {
  61. if (matchIndex >= dictLimit) {
  62. if (*(match+ml) == *(ip+ml) && (MEM_read32(match) == MEM_read32(ip))) {
  63. mlt = Lizard_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH;
  64. if ((mlt >= minMatchLongOff) || ((U32)(ip - match) < LIZARD_MAX_16BIT_OFFSET))
  65. if (!ml || (mlt > ml)) // && Lizard_better_price((ip - *matchpos), ml, (ip - match), mlt, ctx->last_off)))
  66. { ml = mlt; *matchpos = match; }
  67. }
  68. } else {
  69. matchDict = dictBase + matchIndex;
  70. if ((U32)((dictLimit-1) - matchIndex) >= 3) /* intentional overflow */
  71. if (MEM_read32(matchDict) == MEM_read32(ip)) {
  72. mlt = Lizard_count_2segments(ip+MINMATCH, matchDict+MINMATCH, iLimit, dictEnd, lowPrefixPtr) + MINMATCH;
  73. if ((mlt >= minMatchLongOff) || ((U32)(ip - match) < LIZARD_MAX_16BIT_OFFSET))
  74. if (!ml || (mlt > ml)) // && Lizard_better_price((ip - *matchpos), ml, (U32)(ip - match), mlt, ctx->last_off)))
  75. { ml = mlt; *matchpos = match; } /* virtual matchpos */
  76. }
  77. }
  78. }
  79. }
  80. return (int)ml;
  81. }
  82. FORCE_INLINE int Lizard_FindMatchFaster (Lizard_stream_t* ctx, U32 matchIndex, /* Index table will be updated */
  83. const BYTE* ip, const BYTE* const iLimit,
  84. const BYTE** matchpos)
  85. {
  86. const BYTE* const base = ctx->base;
  87. const BYTE* const dictBase = ctx->dictBase;
  88. const U32 dictLimit = ctx->dictLimit;
  89. const BYTE* const dictEnd = dictBase + dictLimit;
  90. const U32 maxDistance = (1 << ctx->params.windowLog) - 1;
  91. const U32 current = (U32)(ip - base);
  92. const U32 lowLimit = (ctx->lowLimit + maxDistance >= current) ? ctx->lowLimit : current - maxDistance;
  93. const BYTE* const lowPrefixPtr = base + dictLimit;
  94. const size_t minMatchLongOff = ctx->params.minMatchLongOff;
  95. const BYTE* match, *matchDict;
  96. size_t ml=0, mlt;
  97. if (matchIndex < current && matchIndex >= lowLimit) {
  98. match = base + matchIndex;
  99. if ((U32)(ip - match) >= LIZARD_PRICEFAST_MIN_OFFSET) {
  100. if (matchIndex >= dictLimit) {
  101. if (MEM_read32(match) == MEM_read32(ip)) {
  102. mlt = Lizard_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH;
  103. if ((mlt >= minMatchLongOff) || ((U32)(ip - match) < LIZARD_MAX_16BIT_OFFSET))
  104. { ml = mlt; *matchpos = match; }
  105. }
  106. } else {
  107. matchDict = dictBase + matchIndex;
  108. if ((U32)((dictLimit-1) - matchIndex) >= 3) /* intentional overflow */
  109. if (MEM_read32(matchDict) == MEM_read32(ip)) {
  110. mlt = Lizard_count_2segments(ip+MINMATCH, matchDict+MINMATCH, iLimit, dictEnd, lowPrefixPtr) + MINMATCH;
  111. if ((mlt >= minMatchLongOff) || ((U32)(ip - match) < LIZARD_MAX_16BIT_OFFSET))
  112. { ml = mlt; *matchpos = match; } /* virtual matchpos */
  113. }
  114. }
  115. }
  116. }
  117. return (int)ml;
  118. }
  119. FORCE_INLINE int Lizard_compress_priceFast(
  120. Lizard_stream_t* const ctx,
  121. const BYTE* ip,
  122. const BYTE* const iend)
  123. {
  124. const BYTE* anchor = ip;
  125. const BYTE* const mflimit = iend - MFLIMIT;
  126. const BYTE* const matchlimit = (iend - LASTLITERALS);
  127. size_t ml, ml2=0;
  128. const BYTE* ref=NULL;
  129. const BYTE* start2=NULL;
  130. const BYTE* ref2=NULL;
  131. const BYTE* lowPrefixPtr = ctx->base + ctx->dictLimit;
  132. U32* HashTable = ctx->hashTable;
  133. #if MINMATCH == 3
  134. U32* HashTable3 = ctx->hashTable3;
  135. #endif
  136. const BYTE* const base = ctx->base;
  137. const size_t minMatchLongOff = ctx->params.minMatchLongOff;
  138. U32* HashPos;
  139. /* init */
  140. ip++;
  141. /* Main Loop */
  142. while (ip < mflimit)
  143. {
  144. HashPos = &HashTable[Lizard_hashPtr(ip, ctx->params.hashLog, ctx->params.searchLength)];
  145. #if MINMATCH == 3
  146. {
  147. U32* HashPos3 = &HashTable3[Lizard_hash3Ptr(ip, ctx->params.hashLog3)];
  148. ml = Lizard_FindMatchFast (ctx, *HashPos, *HashPos3, ip, matchlimit, (&ref));
  149. *HashPos3 = (U32)(ip - base);
  150. }
  151. #else
  152. ml = Lizard_FindMatchFast (ctx, *HashPos, 0, ip, matchlimit, (&ref));
  153. #endif
  154. if ((*HashPos >= (U32)(ip - base)) || ((U32)(ip - base) >= *HashPos + LIZARD_PRICEFAST_MIN_OFFSET))
  155. *HashPos = (U32)(ip - base);
  156. if (!ml) { ip++; continue; }
  157. if ((int)(ip - ref) == ctx->last_off) { ml2=0; ref=ip; goto _Encode; }
  158. {
  159. int back = 0;
  160. while ((ip+back>anchor) && (ref+back > lowPrefixPtr) && (ip[back-1] == ref[back-1])) back--;
  161. ml -= back;
  162. ip += back;
  163. ref += back;
  164. }
  165. _Search:
  166. if (ip+ml >= mflimit) goto _Encode;
  167. start2 = ip + ml - 2;
  168. HashPos = &HashTable[Lizard_hashPtr(start2, ctx->params.hashLog, ctx->params.searchLength)];
  169. ml2 = Lizard_FindMatchFaster(ctx, *HashPos, start2, matchlimit, (&ref2));
  170. if ((*HashPos >= (U32)(start2 - base)) || ((U32)(start2 - base) >= *HashPos + LIZARD_PRICEFAST_MIN_OFFSET))
  171. *HashPos = (U32)(start2 - base);
  172. if (!ml2) goto _Encode;
  173. {
  174. int back = 0;
  175. while ((start2+back>ip) && (ref2+back > lowPrefixPtr) && (start2[back-1] == ref2[back-1])) back--;
  176. ml2 -= back;
  177. start2 += back;
  178. ref2 += back;
  179. }
  180. if (ml2 <= ml) { ml2 = 0; goto _Encode; }
  181. if (start2 <= ip)
  182. {
  183. ip = start2; ref = ref2; ml = ml2;
  184. ml2 = 0;
  185. goto _Encode;
  186. }
  187. if (start2 - ip < 3)
  188. {
  189. ip = start2; ref = ref2; ml = ml2;
  190. ml2 = 0;
  191. goto _Search;
  192. }
  193. if (start2 < ip + ml)
  194. {
  195. size_t correction = ml - (int)(start2 - ip);
  196. start2 += correction;
  197. ref2 += correction;
  198. ml2 -= correction;
  199. if (ml2 < 3) { ml2 = 0; }
  200. if ((ml2 < minMatchLongOff) && ((U32)(start2 - ref2) >= LIZARD_MAX_16BIT_OFFSET)) { ml2 = 0; }
  201. }
  202. _Encode:
  203. if (Lizard_encodeSequence_LIZv1(ctx, &ip, &anchor, ml, ref)) goto _output_error;
  204. if (ml2)
  205. {
  206. ip = start2; ref = ref2; ml = ml2;
  207. ml2 = 0;
  208. goto _Search;
  209. }
  210. }
  211. /* Encode Last Literals */
  212. ip = iend;
  213. if (Lizard_encodeLastLiterals_LIZv1(ctx, &ip, &anchor)) goto _output_error;
  214. /* End */
  215. return 1;
  216. _output_error:
  217. return 0;
  218. }