// File: sisong[P]ApkDiffPatch/lzma/C/LzFind.c
// Function: MatchFinder_Create
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
    ISzAllocPtr alloc)
{
  /* we need one additional byte in (p->keepSizeBefore),
     since we use MoveBlock() after (p->pos++) and before dictionary using */
  // keepAddBufferBefore = (UInt32)0xFFFFFFFF - (1 << 22); // for debug
  p->keepSizeBefore = historySize + keepAddBufferBefore + 1;

  keepAddBufferAfter += matchMaxLen;
  /* we need (p->keepSizeAfter >= p->numHashBytes) */
  if (keepAddBufferAfter < p->numHashBytes)
    keepAddBufferAfter = p->numHashBytes;
  // keepAddBufferAfter -= 2; // for debug
  p->keepSizeAfter = keepAddBufferAfter;

  if (p->directInput)
    p->blockSize = 0;
  if (p->directInput || LzInWindow_Create2(p, GetBlockSize(p, historySize), alloc))
  {
    size_t hashSizeSum;
    {
      UInt32 hs;
      UInt32 hsCur;
      
      if (p->numHashOutBits != 0)
      {
        unsigned numBits = p->numHashOutBits;
        const unsigned nbMax =
            (p->numHashBytes == 2 ? 16 :
            (p->numHashBytes == 3 ? 24 : 32));
        if (numBits > nbMax)
          numBits = nbMax;
        if (numBits >= 32)
          hs = (UInt32)0 - 1;
        else
          hs = ((UInt32)1 << numBits) - 1;
        // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2)
        hs |= (1 << 16) - 1; /* don't change it! */
        if (p->numHashBytes >= 5)
          hs |= (256 << kLzHash_CrcShift_2) - 1;
        {
          const UInt32 hs2 = MatchFinder_GetHashMask2(p, historySize);
          if (hs > hs2)
            hs = hs2;
        }
        hsCur = hs;
        if (p->expectedDataSize < historySize)
        {
          const UInt32 hs2 = MatchFinder_GetHashMask2(p, (UInt32)p->expectedDataSize);
          if (hsCur > hs2)
            hsCur = hs2;
        }
      }
      else
      {
        hs = MatchFinder_GetHashMask(p, historySize);
        hsCur = hs;
        if (p->expectedDataSize < historySize)
        {
          hsCur = MatchFinder_GetHashMask(p, (UInt32)p->expectedDataSize);
          if (hsCur > hs) // is it possible?
            hsCur = hs;
        }
      }

      p->hashMask = hsCur;

      hashSizeSum = hs;
      hashSizeSum++;
      if (hashSizeSum < hs)
        return 0;
      {
        UInt32 fixedHashSize = 0;
        if (p->numHashBytes > 2 && p->numHashBytes_Min <= 2) fixedHashSize += kHash2Size;
        if (p->numHashBytes > 3 && p->numHashBytes_Min <= 3) fixedHashSize += kHash3Size;
        // if (p->numHashBytes > 4) p->fixedHashSize += hs4; // kHash4Size;
        hashSizeSum += fixedHashSize;
        p->fixedHashSize = fixedHashSize;
      }
    }

    p->matchMaxLen = matchMaxLen;

    {
      size_t newSize;
      size_t numSons;
      const UInt32 newCyclicBufferSize = historySize + 1; // do not change it
      p->historySize = historySize;
      p->cyclicBufferSize = newCyclicBufferSize; // it must be = (historySize + 1)
      
      numSons = newCyclicBufferSize;
      if (p->btMode)
        numSons <<= 1;
      newSize = hashSizeSum + numSons;

      if (numSons < newCyclicBufferSize || newSize < numSons)
        return 0;

      // aligned size is not required here, but it can be better for some loops
      #define NUM_REFS_ALIGN_MASK 0xF
      newSize = (newSize + NUM_REFS_ALIGN_MASK) & ~(size_t)NUM_REFS_ALIGN_MASK;

      // 22.02: we don't reallocate buffer, if old size is enough
      if (p->hash && p->numRefs >= newSize)
        return 1;
      
      MatchFinder_FreeThisClassMemory(p, alloc);
      p->numRefs = newSize;
      p->hash = AllocRefs(newSize, alloc);
      
      if (p->hash)
      {
        p->son = p->hash + hashSizeSum;
        return 1;
      }
    }
  }

  MatchFinder_Free(p, alloc);
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movq %r9, -0x28(%rbp)
movl -0x14(%rbp), %ecx
addl -0x18(%rbp), %ecx
addl $0x1, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x54(%rax)
movl -0x1c(%rbp), %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x20(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x5c(%rcx), %eax
jae 0x6f4ff
movq -0x10(%rbp), %rax
movl 0x5c(%rax), %eax
movl %eax, -0x20(%rbp)
movl -0x20(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x58(%rax)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x23(%rax)
je 0x6f51e
movq -0x10(%rbp), %rax
movl $0x0, 0x50(%rax)
movq -0x10(%rbp), %rax
movzbl 0x23(%rax), %eax
cmpl $0x0, %eax
jne 0x6f557
movq -0x10(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x6f900
movq -0x70(%rbp), %rdi
movl %eax, %esi
movq -0x28(%rbp), %rdx
callq 0x6f870
cmpl $0x0, %eax
je 0x6f848
movq -0x10(%rbp), %rax
movzbl 0x71(%rax), %eax
cmpl $0x0, %eax
je 0x6f655
movq -0x10(%rbp), %rax
movzbl 0x71(%rax), %eax
movl %eax, -0x3c(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x2, 0x5c(%rax)
jne 0x6f587
movl $0x10, %eax
movl %eax, -0x74(%rbp)
jmp 0x6f5a1
movq -0x10(%rbp), %rax
movl 0x5c(%rax), %edx
movl $0x20, %eax
movl $0x18, %ecx
cmpl $0x3, %edx
cmovel %ecx, %eax
movl %eax, -0x74(%rbp)
movl -0x74(%rbp), %eax
movl %eax, -0x40(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x40(%rbp), %eax
jbe 0x6f5b5
movl -0x40(%rbp), %eax
movl %eax, -0x3c(%rbp)
cmpl $0x20, -0x3c(%rbp)
jb 0x6f5c4
movl $0xffffffff, -0x34(%rbp) # imm = 0xFFFFFFFF
jmp 0x6f5d4
movl -0x3c(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
subl $0x1, %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
orl $0xffff, %eax           # imm = 0xFFFF
movl %eax, -0x34(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x5, 0x5c(%rax)
jb 0x6f5f4
movl -0x34(%rbp), %eax
orl $0x3ffff, %eax          # imm = 0x3FFFF
movl %eax, -0x34(%rbp)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x6f9d0
movl %eax, -0x44(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x44(%rbp), %eax
jbe 0x6f611
movl -0x44(%rbp), %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movq 0x480(%rax), %rax
movl -0x14(%rbp), %ecx
cmpq %rcx, %rax
jae 0x6f653
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x480(%rax), %rax
movl %eax, %esi
callq 0x6f9d0
movl %eax, -0x48(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x48(%rbp), %eax
jbe 0x6f651
movl -0x48(%rbp), %eax
movl %eax, -0x38(%rbp)
jmp 0x6f653
jmp 0x6f6a8
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x6fa80
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movq 0x480(%rax), %rax
movl -0x14(%rbp), %ecx
cmpq %rcx, %rax
jae 0x6f6a6
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x480(%rax), %rax
movl %eax, %esi
callq 0x6fa80
movl %eax, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x34(%rbp), %eax
jbe 0x6f6a4
movl -0x34(%rbp), %eax
movl %eax, -0x38(%rbp)
jmp 0x6f6a6
jmp 0x6f6a8
movl -0x38(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x38(%rax)
movl -0x34(%rbp), %eax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movl -0x34(%rbp), %ecx
cmpq %rcx, %rax
jae 0x6f6dd
movl $0x0, -0x4(%rbp)
jmp 0x6f85c
movl $0x0, -0x4c(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x2, 0x5c(%rax)
jbe 0x6f706
movq -0x10(%rbp), %rax
movzbl 0x70(%rax), %eax
cmpl $0x2, %eax
jg 0x6f706
movl -0x4c(%rbp), %eax
addl $0x400, %eax            # imm = 0x400
movl %eax, -0x4c(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x3, 0x5c(%rax)
jbe 0x6f728
movq -0x10(%rbp), %rax
movzbl 0x70(%rax), %eax
cmpl $0x3, %eax
jg 0x6f728
movl -0x4c(%rbp), %eax
addl $0x10000, %eax          # imm = 0x10000
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movl -0x4c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x6c(%rax)
movl -0x1c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x24(%rax)
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
movl -0x14(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x68(%rax)
movl -0x64(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x1c(%rax)
movl -0x64(%rbp), %eax
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x21(%rax)
je 0x6f780
movq -0x60(%rbp), %rax
shlq %rax
movq %rax, -0x60(%rbp)
movq -0x30(%rbp), %rax
addq -0x60(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x60(%rbp), %rax
movl -0x64(%rbp), %ecx
cmpq %rcx, %rax
jb 0x6f7a2
movq -0x58(%rbp), %rax
cmpq -0x60(%rbp), %rax
jae 0x6f7ae
movl $0x0, -0x4(%rbp)
jmp 0x6f85c
movq -0x58(%rbp), %rax
addq $0xf, %rax
andq $-0x10, %rax
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x28(%rax)
je 0x6f7e3
movq -0x10(%rbp), %rax
movq 0x478(%rax), %rax
cmpq -0x58(%rbp), %rax
jb 0x6f7e3
movl $0x1, -0x4(%rbp)
jmp 0x6f85c
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x6f430
movq -0x58(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x478(%rax)
movq -0x58(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x6fb40
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x28(%rax)
je 0x6f846
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rcx
movq -0x30(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
movl $0x1, -0x4(%rbp)
jmp 0x6f85c
jmp 0x6f848
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x6f400
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
nopl (%rax,%rax)