// File: sisong[P]ApkDiffPatch/HDiffPatch/libHDiffPatch/HPatch/patch.c
// Function: cache_old_load
static hpatch_BOOL _cache_old_load(const hpatch_TStreamInput*oldData,
                                   hpatch_StreamPos_t oldPos,hpatch_StreamPos_t oldPosAllEnd,
                                   _TArrayCovers* arrayCovers,hpatch_size_t maxCachedLen,hpatch_size_t sumCacheLen,
                                   TByte* old_cache,TByte* old_cache_end,TByte* cache_buf_end){
    const hpatch_size_t kMinSpaceLen   =(1<<(20+2));//跳过seekTime*speed长度的空间(SSD可以更小)时间上划得来,否则就顺序访问;
    const hpatch_size_t kAccessPageSize=4096;//磁盘页面对齐访问(只和速度有关，但影响不大);
    hpatch_BOOL result=hpatch_TRUE;
    hpatch_size_t cur_i=0,i;
    const hpatch_size_t coverCount=arrayCovers->coverCount;
    TByte* cache_buf=old_cache_end;
    assert((hpatch_size_t)(old_cache_end-old_cache)>=sumCacheLen);
    
    if ((hpatch_size_t)(cache_buf_end-cache_buf)>=kAccessPageSize*2){
        cache_buf=(TByte*)_hpatch_align_upper(cache_buf,kAccessPageSize);
        if ((hpatch_size_t)(cache_buf_end-cache_buf)>=(kMinSpaceLen>>1))
            cache_buf_end=cache_buf+(kMinSpaceLen>>1);
        else
            cache_buf_end=(TByte*)_hpatch_align_lower(cache_buf_end,kAccessPageSize);
    }
    oldPos=_hpatch_align_type_lower(hpatch_StreamPos_t,oldPos,kAccessPageSize);
    if (oldPos<kMinSpaceLen) oldPos=0;
    
    _arrayCovers_sort_by_old(arrayCovers);
    while ((oldPos<oldPosAllEnd)&(cur_i<coverCount)) {
        hpatch_StreamPos_t oldPosEnd;
        hpatch_size_t readLen=(cache_buf_end-cache_buf);
        if (readLen>(oldPosAllEnd-oldPos)) readLen=(hpatch_size_t)(oldPosAllEnd-oldPos);
        if (!oldData->read(oldData,oldPos,cache_buf,
                           cache_buf+readLen)) { result=_hpatch_FALSE; break; } //error
        oldPosEnd=oldPos+readLen;
        for (i=cur_i;i<coverCount;++i){
            hpatch_StreamPos_t ioldPos,ioldPosEnd;
            hpatch_StreamPos_t ilen=_arrayCovers_get_len(arrayCovers,i);
            if (ilen>maxCachedLen){//覆盖线比较长不需要缓存,下一个覆盖线;
                if (i==cur_i)
                    ++cur_i;
                continue;
            }
            ioldPos=_arrayCovers_get_oldPos(arrayCovers,i);
            ioldPosEnd=ioldPos+ilen;
            if (ioldPosEnd>oldPos){
                //        [oldPos                  oldPosEnd]
                //                           ioldPosEnd]----or----]
                if (ioldPos<oldPosEnd){//有交集,需要cache
                //  [----or----[ioldPos      ioldPosEnd]----or----]
                    hpatch_StreamPos_t from;
                    hpatch_size_t      copyLen;
                    hpatch_StreamPos_t dstPos=_arrayCovers_get_cachePos(arrayCovers,i);
                    //assert(dstPos<=(hpatch_size_t)(old_cache_end-old_cache));
                    if (ioldPos>=oldPos){
                //             [ioldPos      ioldPosEnd]----or----]
                        from=ioldPos;
                    }else{
                //  [ioldPos                 ioldPosEnd]----or----]
                        from=oldPos;
                        dstPos+=(oldPos-ioldPos);
                    }
                    copyLen=(hpatch_size_t)(((ioldPosEnd<=oldPosEnd)?ioldPosEnd:oldPosEnd)-from);
                    //assert(dstPos+copyLen<=(hpatch_size_t)(old_cache_end-old_cache));
                    //assert(sumCacheLen>=copyLen);
                    memcpy(old_cache+(hpatch_size_t)dstPos,cache_buf+(from-oldPos),copyLen);
                    sumCacheLen-=copyLen;
                    if ((i==cur_i)&(oldPosEnd>=ioldPosEnd))
                        ++cur_i;
                }else{//后面覆盖线暂时都不会与当前数据有交集了,下一块数据;
                //  [oldPos     oldPosEnd]
                //                        [ioldPos      ioldPosEnd]
                    if ((i==cur_i)&&(ioldPos-oldPosEnd>=kMinSpaceLen))
                        oldPosEnd=_hpatch_align_type_lower(hpatch_StreamPos_t,ioldPos,kAccessPageSize);
                    break;
                }
            }else{//当前覆盖线已经落后于当前数据,下一个覆盖线;
                //                        [oldPos     oldPosEnd]
                // [ioldPos    ioldPosEnd]
                if (i==cur_i)
                    ++cur_i;
            }
        }
        oldPos=oldPosEnd;
    }
    _arrayCovers_sort_by_new(arrayCovers);
    assert(sumCacheLen==0);
    return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
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 $0x400000, -0x38(%rbp)  # imm = 0x400000
movq $0x1000, -0x40(%rbp)    # imm = 0x1000
movl $0x1, -0x44(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x60(%rbp)
movq 0x18(%rbp), %rax
movq %rax, -0x68(%rbp)
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rcx
subq %rcx, %rax
cmpq -0x30(%rbp), %rax
jb 0x8b435
jmp 0x8b454
leaq 0x2a032(%rip), %rdi     # 0xb546e
leaq 0x29597(%rip), %rsi     # 0xb49da
movl $0x662, %edx            # imm = 0x662
leaq 0x2a055(%rip), %rcx     # 0xb54a4
callq 0x4270
movq 0x20(%rbp), %rax
movq -0x68(%rbp), %rcx
subq %rcx, %rax
cmpq $0x2000, %rax           # imm = 0x2000
jb 0x8b4ae
movq -0x68(%rbp), %rax
addq $0xfff, %rax            # imm = 0xFFF
andq $-0x1000, %rax          # imm = 0xF000
movq %rax, -0x68(%rbp)
movq 0x20(%rbp), %rax
movq -0x68(%rbp), %rcx
subq %rcx, %rax
cmpq $0x200000, %rax         # imm = 0x200000
jb 0x8b49e
movq -0x68(%rbp), %rax
addq $0x200000, %rax         # imm = 0x200000
movq %rax, 0x20(%rbp)
jmp 0x8b4ac
movq 0x20(%rbp), %rax
andq $-0x1000, %rax          # imm = 0xF000
movq %rax, 0x20(%rbp)
jmp 0x8b4ae
movq -0x10(%rbp), %rax
andq $-0x1000, %rax          # imm = 0xF000
movq %rax, -0x10(%rbp)
cmpq $0x400000, -0x10(%rbp)  # imm = 0x400000
jae 0x8b4ce
movq $0x0, -0x10(%rbp)
movq -0x20(%rbp), %rdi
callq 0x8bb90
movq -0x10(%rbp), %rax
cmpq -0x18(%rbp), %rax
setb %al
andb $0x1, %al
movzbl %al, %eax
movq -0x50(%rbp), %rcx
cmpq -0x60(%rbp), %rcx
setb %cl
andb $0x1, %cl
movzbl %cl, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x8b814
movq 0x20(%rbp), %rax
movq -0x68(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq -0x18(%rbp), %rcx
subq -0x10(%rbp), %rcx
cmpq %rcx, %rax
jbe 0x8b52f
movq -0x18(%rbp), %rax
subq -0x10(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x68(%rbp), %rdx
movq -0x68(%rbp), %rcx
addq -0x78(%rbp), %rcx
callq *%rax
cmpl $0x0, %eax
jne 0x8b55e
movl $0x0, -0x44(%rbp)
jmp 0x8b814
movq -0x10(%rbp), %rax
addq -0x78(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x60(%rbp), %rax
jae 0x8b807
movq -0x20(%rbp), %rax
cmpl $0x0, 0x38(%rax)
je 0x8b5a7
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x58(%rbp), %rcx
shlq $0x2, %rcx
movl 0x8(%rax,%rcx,4), %eax
movq %rax, -0xb0(%rbp)
jmp 0x8b5c3
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x58(%rbp), %rcx
shlq $0x2, %rcx
movq 0x10(%rax,%rcx,8), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
cmpq -0x28(%rbp), %rax
jbe 0x8b5f9
movq -0x58(%rbp), %rax
cmpq -0x50(%rbp), %rax
jne 0x8b5f4
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x8b7f6
movq -0x20(%rbp), %rax
cmpl $0x0, 0x38(%rax)
je 0x8b61f
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x58(%rbp), %rcx
shlq $0x2, %rcx
movl (%rax,%rcx,4), %eax
movq %rax, -0xb8(%rbp)
jmp 0x8b63a
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x58(%rbp), %rcx
shlq $0x2, %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
addq -0x90(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
cmpq -0x10(%rbp), %rax
jbe 0x8b7dc
movq -0x80(%rbp), %rax
cmpq -0x70(%rbp), %rax
jae 0x8b7b0
movq -0x20(%rbp), %rax
cmpl $0x0, 0x38(%rax)
je 0x8b69d
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x58(%rbp), %rcx
shlq $0x2, %rcx
movl 0xc(%rax,%rcx,4), %eax
movq %rax, -0xc0(%rbp)
jmp 0x8b6b9
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x58(%rbp), %rcx
shlq $0x2, %rcx
movq 0x18(%rax,%rcx,8), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x80(%rbp), %rax
cmpq -0x10(%rbp), %rax
jb 0x8b6de
movq -0x80(%rbp), %rax
movq %rax, -0x98(%rbp)
jmp 0x8b6ff
movq -0x10(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x10(%rbp), %rax
subq -0x80(%rbp), %rax
addq -0xa8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x88(%rbp), %rax
cmpq -0x70(%rbp), %rax
ja 0x8b71c
movq -0x88(%rbp), %rax
movq %rax, -0xc8(%rbp)
jmp 0x8b727
movq -0x70(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rax
subq -0x98(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq 0x10(%rbp), %rdi
addq -0xa8(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x98(%rbp), %rax
subq -0x10(%rbp), %rax
addq %rax, %rsi
movq -0xa0(%rbp), %rdx
callq 0x4320
movq -0xa0(%rbp), %rcx
movq -0x30(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x50(%rbp), %rax
sete %al
andb $0x1, %al
movzbl %al, %eax
movq -0x70(%rbp), %rcx
cmpq -0x88(%rbp), %rcx
setae %cl
andb $0x1, %cl
movzbl %cl, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x8b7ae
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x8b7da
movq -0x58(%rbp), %rax
cmpq -0x50(%rbp), %rax
jne 0x8b7d8
movq -0x80(%rbp), %rax
subq -0x70(%rbp), %rax
cmpq $0x400000, %rax         # imm = 0x400000
jb 0x8b7d8
movq -0x80(%rbp), %rax
andq $-0x1000, %rax          # imm = 0xF000
movq %rax, -0x70(%rbp)
jmp 0x8b807
jmp 0x8b7f4
movq -0x58(%rbp), %rax
cmpq -0x50(%rbp), %rax
jne 0x8b7f2
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x8b7f4
jmp 0x8b7f6
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0x8b572
movq -0x70(%rbp), %rax
movq %rax, -0x10(%rbp)
jmp 0x8b4d7
movq -0x20(%rbp), %rdi
callq 0x8bbf0
cmpq $0x0, -0x30(%rbp)
jne 0x8b826
jmp 0x8b845
leaq 0x29d22(%rip), %rdi     # 0xb554f
leaq 0x291a6(%rip), %rsi     # 0xb49da
movl $0x6a9, %edx            # imm = 0x6A9
leaq 0x29c64(%rip), %rcx     # 0xb54a4
callq 0x4270
movl -0x44(%rbp), %eax
addq $0xd0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)