// File: sisong[P]ApkDiffPatch/HDiffPatch/libHDiffPatch/HDiff/private_diff/limit_mem_diff/digest_matcher.cpp
// Function: void hdiff_private::tm_search_cover<unsigned long>(unsigned long const*, unsigned long const*, unsigned long const*, hdiff_private::TOldStreamCache&, hdiff_private::TNewStreamCache&, hdiff_private::TBloomFilter<unsigned long> const&, hpatch_TOutputCovers*, unsigned long long, void*, void*, hdiff_TMTSets_s const&)
static void tm_search_cover(const adler_uint_t* blocksBase,
                            const TIndex* iblocks,const TIndex* iblocks_end,
                            TOldStreamCache& oldStream,TNewStreamCache& newStream,
                            const TBloomFilter<adler_hash_t>& filter,
                            hpatch_TOutputCovers* out_covers,
                            hpatch_StreamPos_t _coverNewOffset,
                            void* _newLocker,void* _dataLocker,const hdiff_TMTSets_s& _mtsets) {
    const size_t blocksSize=iblocks_end-iblocks;
    TDigest_comp comp(blocksBase);
    TCover  lastCover={0,0,0};
    while (true) {
        adler_uint_t digest=newStream.rollDigest();
        if (!filter.is_hit(adler_to_hash(digest)))
            { if (newStream.roll()) continue; else break; }//finish
        typename TDigest_comp::TDigest digest_value(digest);
        std::pair<const TIndex*,const TIndex*>
        range=std::equal_range(iblocks,iblocks_end,digest_value,comp);
        if (range.first==range.second)
            { if (newStream.roll()) continue; else break; }//finish
        
        hpatch_StreamPos_t newPosNext=newStream.pos()+1;
        size_t digests_eq_n;
        const TIndex* besti=getBestMatchi(blocksBase,blocksSize,&range.first,&range.second,
                                          newStream,lastCover,&digests_eq_n);
        {
    #if (_IS_USED_MULTITHREAD)
            CAutoLocker _autoDataLocker(_mtsets.oldDataIsMTSafe?0:
                                        (_mtsets.newAndOldDataIsMTSameRes?_newLocker:_dataLocker));
    #endif
            TCover  curCover;
            if (getBestMatch(range.first,range.second,besti,oldStream,newStream,
                             lastCover,digests_eq_n,&curCover)){
                tryLink(lastCover,curCover,oldStream,newStream);
                if (curCover.length>=kMinMatchedLength){//matched
                    TCover _cover;
                    setCover(_cover,curCover.oldPos,curCover.newPos+_coverNewOffset,curCover.length);
                    {
    #if (_IS_USED_MULTITHREAD)
                        CAutoLocker _autoCoverLocker(_mtsets.oldDataIsMTSafe?_dataLocker:0);
    #endif
                        if (!out_covers->push_cover(out_covers,&_cover))
                            throw std::runtime_error("TDigestMatcher::search_cover() push_cover error!");
                    }
                    lastCover=curCover;
                    newPosNext=curCover.newPos+curCover.length;//next
                }
            }
        }
        //next
        if (!newStream.resetPos(newPosNext)) break;//finish
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq 0x30(%rbp), %rax
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
subq %rcx, %rax
sarq $0x3, %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x49590
leaq -0x58(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x4210
movq -0x28(%rbp), %rdi
callq 0x495b0
movq %rax, -0x60(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x100(%rbp)
movq -0x60(%rbp), %rdi
callq 0x40500
movq -0x100(%rbp), %rdi
movq %rax, %rsi
callq 0x495d0
testb $0x1, %al
jne 0x3f731
movq -0x28(%rbp), %rdi
callq 0x49660
testb $0x1, %al
jne 0x3f72a
jmp 0x3f72c
jmp 0x3f6e7
jmp 0x3fa3c
movq -0x60(%rbp), %rsi
leaq -0x68(%rbp), %rdi
callq 0x49720
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x40(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rcx
leaq -0x68(%rbp), %rdx
callq 0x49740
movq %rax, -0x78(%rbp)
movq %rdx, -0x70(%rbp)
movq -0x78(%rbp), %rax
cmpq -0x70(%rbp), %rax
jne 0x3f786
movq -0x28(%rbp), %rdi
callq 0x49660
testb $0x1, %al
jne 0x3f77c
jmp 0x3f781
jmp 0x3f6e7
jmp 0x3fa3c
movq -0x28(%rbp), %rdi
callq 0x497d0
addq $0x1, %rax
movq %rax, -0x88(%rbp)
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
leaq -0x78(%rbp), %rdx
leaq -0x78(%rbp), %rcx
addq $0x8, %rcx
movq -0x28(%rbp), %r8
leaq -0x58(%rbp), %r9
leaq -0x90(%rbp), %rax
movq %rax, (%rsp)
callq 0x40d80
movq %rax, -0x98(%rbp)
movq 0x30(%rbp), %rax
testb $0x1, 0x11(%rax)
je 0x3f7e2
xorl %eax, %eax
movq %rax, -0x108(%rbp)
jmp 0x3f812
movq 0x30(%rbp), %rax
testb $0x1, 0x12(%rax)
je 0x3f7f9
movq 0x20(%rbp), %rax
movq %rax, -0x110(%rbp)
jmp 0x3f804
movq 0x28(%rbp), %rax
movq %rax, -0x110(%rbp)
movq -0x110(%rbp), %rax
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
callq 0x42c30
movq -0x78(%rbp), %rdi
movq -0x70(%rbp), %rsi
movq -0x98(%rbp), %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x90(%rbp), %r9
movq %rsp, %rax
leaq -0xc0(%rbp), %r10
movq %r10, 0x8(%rax)
movq %r9, (%rax)
leaq -0x58(%rbp), %r9
callq 0x413c0
movb %al, -0x111(%rbp)
jmp 0x3f865
movb -0x111(%rbp), %al
testb $0x1, %al
jne 0x3f874
jmp 0x3fa07
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
leaq -0x58(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x41610
jmp 0x3f88e
cmpq $0x10, -0xb0(%rbp)
jb 0x3fa05
movq -0xc0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
movq 0x18(%rbp), %rax
addq %rax, %rdx
movq -0xb0(%rbp), %rcx
leaq -0xe8(%rbp), %rdi
callq 0x41720
jmp 0x3f8c6
movq 0x30(%rbp), %rax
testb $0x1, 0x11(%rax)
je 0x3f8dd
movq 0x28(%rbp), %rax
movq %rax, -0x120(%rbp)
jmp 0x3f8e8
xorl %eax, %eax
movq %rax, -0x120(%rbp)
jmp 0x3f8e8
movq -0x120(%rbp), %rsi
leaq -0xf8(%rbp), %rdi
callq 0x42c30
jmp 0x3f8fd
movq 0x10(%rbp), %rdi
movq (%rdi), %rax
leaq -0xe8(%rbp), %rsi
callq *%rax
movl %eax, -0x124(%rbp)
jmp 0x3f915
movl -0x124(%rbp), %eax
cmpl $0x0, %eax
jne 0x3f9b3
movl $0x10, %edi
callq 0x41e0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x130(%rbp)
leaq 0x70c44(%rip), %rsi     # 0xb0586
callq 0x4140
jmp 0x3f949
movq -0x130(%rbp), %rdi
movq 0xa6699(%rip), %rsi     # 0xe5ff0
movq 0xa6662(%rip), %rdx     # 0xe5fc0
callq 0x4630
jmp 0x3fa51
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x3fa29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x3f9f7
movq -0x130(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
callq 0x42e0
jmp 0x3f9f7
leaq -0xf8(%rbp), %rdi
callq 0x42f60
movq -0xc0(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0xb8(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0xb8(%rbp), %rax
addq -0xb0(%rbp), %rax
movq %rax, -0x88(%rbp)
jmp 0x3fa05
leaq -0xf8(%rbp), %rdi
callq 0x42f60
jmp 0x3fa29
jmp 0x3fa07
leaq -0xa8(%rbp), %rdi
callq 0x42f60
movq -0x28(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x43ba0
testb $0x1, %al
jne 0x3fa37
jmp 0x3fa3c
leaq -0xa8(%rbp), %rdi
callq 0x42f60
jmp 0x3fa45
jmp 0x3f6e7
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
movq -0xc8(%rbp), %rdi
callq 0x4680
nopw %cs:(%rax,%rax)