// File: /workspace/github_cpp_makefile_star2_O3/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
addq $0x8, %rdi
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rbx)
movq $0x0, 0x18(%rbx)
leaq 0x515b(%rip), %rax      # 0x8d90
movq %rax, (%rbx)
movq (%rsi), %r12
movq %rdi, (%rsp)
xorl %esi, %esi
callq 0x571a
cmpq 0x8(%r15), %r12
jae 0x400c
leaq 0x10(%rsp), %rbp
leaq 0x5104(%rip), %r14      # 0x8d60
leaq 0x50d5(%rip), %r13      # 0x8d38
movq %r15, %rdi
movq %r12, %rsi
callq 0x4136
movq %rax, 0x38(%rsp)
movq %rdx, 0x40(%rsp)
movq %rax, %rcx
shrq $0x20, %rcx
cmpl %ecx, %eax
setne %cl
testl %eax, %eax
setle %dl
orb %cl, %dl
jne 0x3d94
movq %rbx, %rdi
movl %eax, %esi
callq 0x4884
testb %al, %al
je 0x3e30
movl 0x3c(%rsp), %esi
movq %rbx, %rdi
callq 0x48dc
movq %rbp, %r13
movslq 0x3c(%rsp), %rax
leaq (%r12,%rax,8), %rdx
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rbp
movups %xmm0, (%rbp)
movq $0x0, 0x10(%rbp)
movq %r14, 0x8(%rsp)
movq %rbp, %rdi
movq %r12, %rsi
callq 0x574a
movq $0x2, 0x28(%rsp)
leaq 0x5049(%rip), %rax      # 0x8d38
movq %rax, 0xd8(%rsp)
leaq 0xe0(%rsp), %rdi
movq %rbp, %rsi
callq 0x475e
movq %r14, 0xd8(%rsp)
movups 0x28(%rsp), %xmm0
movups %xmm0, 0xf8(%rsp)
movq (%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x549a
leaq 0x5004(%rip), %rax      # 0x8d38
movq %rax, 0xd8(%rsp)
movq 0xe0(%rsp), %rdi
testq %rdi, %rdi
movq %r13, %rbp
je 0x3d5c
movq 0xf0(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
movslq 0x3c(%rsp), %r14
leaq 0x4fd0(%rip), %r13      # 0x8d38
movq %r13, 0x8(%rsp)
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3d84
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
leaq (%r12,%r14,8), %r12
leaq 0x4fd1(%rip), %r14      # 0x8d60
jmp 0x3f50
xorps %xmm0, %xmm0
movups %xmm0, (%rbp)
movq $0x0, 0x10(%rbp)
movq %r14, 0x8(%rsp)
movq %rbp, %rdi
xorl %esi, %esi
leaq 0x40(%rsp), %rdx
callq 0x4dc0
movq $0x1, 0x28(%rsp)
movq %r13, 0x48(%rsp)
leaq 0x50(%rsp), %rdi
movq %rbp, %rsi
callq 0x475e
movq %r14, 0x48(%rsp)
movups 0x28(%rsp), %xmm0
movups %xmm0, 0x68(%rsp)
movq (%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x549a
movq %r13, 0x48(%rsp)
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x3e0b
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
movq %r13, 0x8(%rsp)
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3e27
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
addq $0x8, %r12
jmp 0x3f50
leaq 0x8(%rsp), %rdi
movq %rbx, %rsi
callq 0x49e0
movq 0x18(%rsp), %rsi
subq 0x10(%rsp), %rsi
movslq 0x3c(%rsp), %rcx
sarq $0x3, %rsi
movq %rcx, %rax
xorl %edx, %edx
divq %rsi
testq %rdx, %rdx
jne 0x3e6f
movq 0x28(%rsp), %rdx
imulq %rdx, %rsi
cmpq %rcx, %rsi
jae 0x3f6c
xorps %xmm0, %xmm0
movq %r14, %rax
leaq 0x110(%rsp), %r14
movups %xmm0, (%r14)
movq $0x0, 0x10(%r14)
movq %rax, 0x108(%rsp)
movq %r14, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x4dc0
movq $0x1, 0x128(%rsp)
movq %r13, 0x78(%rsp)
leaq 0x80(%rsp), %rdi
movq %r14, %rsi
callq 0x475e
leaq 0x4e9a(%rip), %r14      # 0x8d60
movq %r14, 0x78(%rsp)
movups 0x128(%rsp), %xmm0
movups %xmm0, 0x98(%rsp)
movq (%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x549a
movq %r13, 0x78(%rsp)
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x3f0b
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
movq %r13, 0x108(%rsp)
movq 0x110(%rsp), %rdi
testq %rdi, %rdi
je 0x3f30
movq 0x120(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
addq $0x8, %r12
movq %r13, 0x8(%rsp)
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3f50
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
movq 0x10(%rbx), %rdi
addq $-0x30, %rdi
callq 0x2fd0
cmpq 0x8(%r15), %r12
jb 0x3c63
jmp 0x400c
addq %rdx, %rax
movq %rax, 0x28(%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 0x3f99
movq -0x18(%rax), %rsi
subq %rdi, %rsi
callq 0x2140
movq %r13, 0xa8(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x475e
movq %r14, 0xa8(%rsp)
movups 0x28(%rsp), %xmm0
movups %xmm0, 0xc8(%rsp)
movq (%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x549a
movq %r13, 0xa8(%rsp)
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x3ffe
movq 0xc0(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
movslq 0x3c(%rsp), %rax
leaq (%r12,%rax,8), %r12
jmp 0x3f34
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, 0xa8(%rsp)
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x40f3
movq 0xc0(%rsp), %rsi
jmp 0x40e4
jmp 0x40f0
movq %rax, %r15
movq %r13, 0x78(%rsp)
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x40a7
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
jmp 0x40a7
jmp 0x4118
movq %rax, %r15
leaq 0x4cb3(%rip), %rax      # 0x8d38
movq %rax, 0xd8(%rsp)
movq 0xe0(%rsp), %rdi
testq %rdi, %rdi
je 0x40f3
movq 0xf0(%rsp), %rsi
jmp 0x40e4
movq %rax, %r15
leaq 0x4c8a(%rip), %rax      # 0x8d38
movq %rax, 0x108(%rsp)
movq 0x110(%rsp), %rdi
testq %rdi, %rdi
je 0x40f3
movq 0x120(%rsp), %rsi
jmp 0x40e4
movq %rax, %r15
movq %r13, 0x48(%rsp)
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x40f3
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
jmp 0x40f3
jmp 0x40f0
movq %rax, %r15
leaq 0x4c3e(%rip), %rax      # 0x8d38
movq %rax, 0x8(%rsp)
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x411b
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2140
jmp 0x411b
movq %rax, %r15
leaq 0x4bee(%rip), %rax      # 0x8d10
movq %rax, (%rbx)
movq (%rsp), %rdi
callq 0x26d6
movq %r15, %rdi
callq 0x21c0