// File: /workspace/github_cpp_makefile_star2_O1/junhe[P]libpatterndetector/pattern.cpp
// Function: PatternUtil::findPattern(std::vector<long, std::allocator<long>>)
PatChain<PatternUnit> 
PatternUtil::findPattern( vector<off_t> deltas )
{
    // pointer(iterator) to the lookahead window, both should move together
//    mlog(IDX_WARN, "Entering %s", __FUNCTION__);
//    mlog(IDX_WARN, "deltas: %s", printVector(deltas).c_str());
    vector<off_t>::const_iterator p_lookahead_win;
    PatChain<PatternUnit> pattern_stack;

    p_lookahead_win = deltas.begin();
    pattern_stack.clear();

    while ( p_lookahead_win < deltas.end() ) {
        //lookahead window is not empty
//        mlog(IDX_WARN, "window position:%d", p_lookahead_win - deltas.begin());
        Tuple cur_tuple = searchNeighbor( deltas, p_lookahead_win );
        if ( cur_tuple.isRepeatingNeighbor() ) {
            if ( pattern_stack.isPopSafe( cur_tuple.length ) ) {
//                mlog(IDX_WARN, "SAFE" );
                //safe
                //pop out elements without breaking existing patterns
                pattern_stack.popElem( cur_tuple.length );

                vector<off_t>::const_iterator first, last;
                first = p_lookahead_win;
                last = p_lookahead_win + cur_tuple.length;

                PatternUnit pu;
                pu.seq.assign(first, last);
                pu.cnt = 2;

                pattern_stack.push( pu );
                p_lookahead_win += cur_tuple.length;
            } else {
                //unsafe
//                mlog(IDX_WARN, "UNSAFE" );
                PatternUnit pu = pattern_stack.top();

                if ( cur_tuple.length % pu.seq.size() == 0
                     && cur_tuple.length <= pu.seq.size() * pu.cnt ) {
//                    mlog(IDX_WARN, "-REPEATING LAST Pattern");
                    //the subseq in lookahead window repeats
                    //the top pattern in stack.
                    //initial remains the same.
                    pu.cnt += cur_tuple.length / pu.seq.size() ;
                    pattern_stack.popPattern();
                    pattern_stack.push(pu);

                    p_lookahead_win += cur_tuple.length;
                } else {
//                    mlog(IDX_WARN, "-Just Pust it in");
                    //cannot pop out cur_tuple.length elems without
                    //totally breaking any pattern.
                    //So we simply add one elem to the stack
                    PatternUnit pu;
                    pu.seq.push_back( *p_lookahead_win );
                    pu.cnt = 1;
                    pattern_stack.push(pu);
                    p_lookahead_win++;
                }
            }
        } else {
            //(0,0,x), nothing repeats
            PatternUnit pu;
            pu.seq.push_back(cur_tuple.next_symbol);
            pu.cnt = 1;

            pattern_stack.push(pu); 
            p_lookahead_win++;
        }
        pattern_stack.chain.back().compressRepeats();
//        mlog(IDX_WARN, "LOOP: %s", pattern_stack.show().c_str());
    }
   
//    mlog(IDX_WARN, "Leaving %s:%s", __FUNCTION__, pattern_stack.show().c_str());
    return pattern_stack;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x138, %rsp            # imm = 0x138
movq %rsi, %r15
movq %rdi, %rbx
leaq 0x8(%rdi), %rbp
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rdi)
movq $0x0, 0x18(%rdi)
leaq 0x50d3(%rip), %rax      # 0x8d90
movq %rax, (%rdi)
movq (%rsi), %r12
movq %rbp, %rdi
xorl %esi, %esi
callq 0x589a
cmpq 0x8(%r15), %r12
jae 0x40e9
leaq 0x50(%rsp), %r14
leaq 0x5055(%rip), %r13      # 0x8d38
movq %rbp, 0x40(%rsp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x4214
movq %rax, 0x30(%rsp)
movq %rdx, 0x38(%rsp)
movl 0x34(%rsp), %esi
cmpl %esi, %eax
setne %cl
testl %eax, %eax
setle %al
orb %cl, %al
jne 0x3e1d
movq %rbx, %rdi
callq 0x4984
testb %al, %al
je 0x3e5c
movl 0x34(%rsp), %esi
movq %rbx, %rdi
callq 0x49dc
movq %r14, %r13
movslq 0x34(%rsp), %rax
leaq (%r12,%rax,8), %rdx
xorps %xmm0, %xmm0
leaq 0x8(%rsp), %r14
movups %xmm0, (%r14)
movq $0x0, 0x10(%r14)
leaq 0x500a(%rip), %rax      # 0x8d60
movq %rax, (%rsp)
movq %r14, %rdi
movq %r12, %rsi
callq 0x58ca
movq $0x2, 0x20(%rsp)
leaq 0x4fc3(%rip), %rax      # 0x8d38
movq %rax, 0x108(%rsp)
leaq 0x110(%rsp), %rdi
movq %r14, %rsi
callq 0x485e
movups 0x20(%rsp), %xmm0
movups %xmm0, 0x128(%rsp)
leaq 0x4fbf(%rip), %rax      # 0x8d60
movq %rax, 0x108(%rsp)
movq %rbp, %rdi
leaq 0x108(%rsp), %rsi
callq 0x55d8
leaq 0x4f78(%rip), %rax      # 0x8d38
movq %rax, 0x108(%rsp)
movq 0x110(%rsp), %rdi
testq %rdi, %rdi
movq %r13, %r14
je 0x3de8
movq 0x120(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
movslq 0x34(%rsp), %rbp
leaq 0x4f44(%rip), %r13      # 0x8d38
movq %r13, (%rsp)
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x3e0f
movq 0x18(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
leaq (%r12,%rbp,8), %r12
movq 0x40(%rsp), %rbp
jmp 0x4027
xorps %xmm0, %xmm0
leaq 0x8(%rsp), %rdi
movups %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
leaq 0x4f29(%rip), %rax      # 0x8d60
movq %rax, (%rsp)
movq 0x10(%rsp), %rsi
cmpq 0x18(%rsp), %rsi
je 0x3ed9
movq %rdx, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x10(%rsp)
jmp 0x3ee3
movq %rsp, %rdi
movq %rbx, %rsi
callq 0x4ae2
movq 0x10(%rsp), %rsi
subq 0x8(%rsp), %rsi
movslq 0x34(%rsp), %rcx
sarq $0x3, %rsi
movq %rcx, %rax
xorl %edx, %edx
divq %rsi
testq %rdx, %rdx
jne 0x3e99
movq 0x20(%rsp), %rdx
imulq %rdx, %rsi
cmpq %rcx, %rsi
jae 0x4043
xorps %xmm0, %xmm0
movups %xmm0, (%r14)
movq $0x0, 0x10(%r14)
leaq 0x4eb1(%rip), %rax      # 0x8d60
movq %rax, 0x48(%rsp)
movq 0x58(%rsp), %rsi
cmpq 0x60(%rsp), %rsi
je 0x3f6f
movq (%r12), %rax
movq %rax, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x58(%rsp)
jmp 0x3f7a
leaq 0x38(%rsp), %rdx
callq 0x4eba
movq $0x1, 0x20(%rsp)
movq %r13, 0x78(%rsp)
leaq 0x80(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x485e
movups 0x20(%rsp), %xmm0
movups %xmm0, 0x98(%rsp)
leaq 0x4e49(%rip), %rax      # 0x8d60
movq %rax, 0x78(%rsp)
movq %rbp, %rdi
leaq 0x78(%rsp), %rsi
callq 0x55d8
movq %r13, 0x78(%rsp)
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x3f4b
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
movq %r13, (%rsp)
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x3f66
movq 0x18(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
addq $0x8, %r12
jmp 0x4027
movq %r14, %rdi
movq %r12, %rdx
callq 0x4eba
movq $0x1, 0x68(%rsp)
movq %r13, 0xa8(%rsp)
leaq 0xb0(%rsp), %rdi
movq %r14, %rsi
callq 0x485e
movups 0x68(%rsp), %xmm0
movups %xmm0, 0xc8(%rsp)
leaq 0x4db1(%rip), %rax      # 0x8d60
movq %rax, 0xa8(%rsp)
movq %rbp, %rdi
leaq 0xa8(%rsp), %rsi
callq 0x55d8
movq %r13, 0xa8(%rsp)
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x3fec
movq 0xc0(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
movq %r13, 0x48(%rsp)
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x4008
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
addq $0x8, %r12
movq %r13, (%rsp)
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x4027
movq 0x18(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
movq 0x10(%rbx), %rdi
addq $-0x30, %rdi
callq 0x3034
cmpq 0x8(%r15), %r12
jb 0x3ce8
jmp 0x40e9
addq %rdx, %rax
movq %rax, 0x20(%rsp)
movq 0x10(%rbx), %rax
leaq -0x30(%rax), %rcx
movq %rcx, 0x10(%rbx)
movq %r13, -0x30(%rax)
movq -0x28(%rax), %rdi
testq %rdi, %rdi
je 0x4070
movq -0x18(%rax), %rsi
subq %rdi, %rsi
callq 0x2140
movq %r13, 0xd8(%rsp)
leaq 0xe0(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x485e
movups 0x20(%rsp), %xmm0
movups %xmm0, 0xf8(%rsp)
leaq 0x4cc2(%rip), %rax      # 0x8d60
movq %rax, 0xd8(%rsp)
movq %rbp, %rdi
leaq 0xd8(%rsp), %rsi
callq 0x55d8
movq %r13, 0xd8(%rsp)
movq 0xe0(%rsp), %rdi
testq %rdi, %rdi
je 0x40db
movq 0xf0(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
movslq 0x34(%rsp), %rax
leaq (%r12,%rax,8), %r12
jmp 0x400c
movq %rbx, %rax
addq $0x138, %rsp            # imm = 0x138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r15
movq %r13, 0xd8(%rsp)
movq 0xe0(%rsp), %rdi
testq %rdi, %rdi
je 0x41d0
movq 0xf0(%rsp), %rsi
jmp 0x41c1
jmp 0x41cd
movq %rax, %r15
movq %r13, 0xa8(%rsp)
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x4187
movq 0xc0(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
jmp 0x4187
jmp 0x41f4
movq %rax, %r15
leaq 0x4bd3(%rip), %rax      # 0x8d38
movq %rax, 0x108(%rsp)
movq 0x110(%rsp), %rdi
testq %rdi, %rdi
je 0x41d0
movq 0x120(%rsp), %rsi
jmp 0x41c1
movq %rax, %r15
leaq 0x4baa(%rip), %rax      # 0x8d38
movq %rax, 0x48(%rsp)
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x41d0
movq 0x60(%rsp), %rsi
jmp 0x41c1
movq %rax, %r15
movq %r13, 0x78(%rsp)
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x41d0
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
jmp 0x41d0
jmp 0x41cd
movq %rax, %r15
leaq 0x4b61(%rip), %rax      # 0x8d38
movq %rax, (%rsp)
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x41f7
movq 0x18(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
jmp 0x41f7
movq %rax, %r15
leaq 0x4b12(%rip), %rax      # 0x8d10
movq %rax, (%rbx)
movq 0x40(%rsp), %rdi
callq 0x26dc
movq %r15, %rdi
callq 0x21c0
nop