// File: /workspace/github_cpp_makefile_star2_O2/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 $0x148, %rsp            # imm = 0x148
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x8(%rdi), %r15
xorps %xmm0, %xmm0
andq $0x0, 0x18(%rdi)
movups %xmm0, 0x8(%rdi)
leaq 0x4970(%rip), %rax      # 0x7d98
movq %rax, (%rdi)
movq (%rsi), %r12
movq %r15, %rdi
callq 0x4a96
leaq 0x28(%rsp), %r13
leaq 0x88(%rsp), %rbp
movq %rbx, 0x20(%rsp)
movq %r15, 0x18(%rsp)
cmpq 0x8(%r14), %r12
jae 0x368e
movq %r14, %rdi
movq %r12, %rsi
callq 0x372a
movq %rax, 0x8(%rsp)
movq %rdx, 0x10(%rsp)
movq %rax, %rcx
shrq $0x20, %rcx
cmpl %ecx, %eax
setne %cl
testl %eax, %eax
setle %dl
orb %cl, %dl
jne 0x352e
movq %rbx, %rdi
movl %eax, %esi
callq 0x3c8c
testb %al, %al
je 0x3584
movl 0xc(%rsp), %esi
movq %rbx, %rdi
callq 0x3cc8
movq %r15, %rbp
movq %r13, %r15
movslq 0xc(%rsp), %rax
leaq (%r12,%rax,8), %rdx
xorps %xmm0, %xmm0
leaq 0x30(%rsp), %rdi
movups %xmm0, (%rdi)
andq $0x0, 0x10(%rdi)
leaq 0x489f(%rip), %rax      # 0x7d68
movq %rax, 0x28(%rsp)
movq %r12, %rsi
callq 0x4ae2
leaq 0x118(%rsp), %r13
movq $0x2, 0x48(%rsp)
movq %r13, %rdi
movq %r15, %rsi
callq 0x3c62
movq %rbp, %rdi
movq %r13, %rsi
callq 0x48b6
movq %r13, %rdi
callq 0x2522
movslq 0xc(%rsp), %rax
leaq (%r12,%rax,8), %r12
movq %r15, %r13
movq %r15, %rdi
callq 0x2522
movq %rbp, %r15
movq 0x20(%rsp), %rbx
leaq 0x88(%rsp), %rbp
jmp 0x3634
xorps %xmm0, %xmm0
leaq 0x30(%rsp), %rdi
movups %xmm0, (%rdi)
andq $0x0, 0x10(%rdi)
leaq 0x4823(%rip), %rax      # 0x7d68
movq %rax, 0x28(%rsp)
leaq 0x10(%rsp), %rsi
callq 0x3b42
movq $0x1, 0x48(%rsp)
movq %rbp, %rdi
movq %r13, %rsi
callq 0x3c62
movq %r15, %rdi
movq %rbp, %rsi
callq 0x48b6
movq %rbp, %rdi
callq 0x2522
addq $0x8, %r12
jmp 0x362c
movq %r13, %rdi
movq %rbx, %rsi
callq 0x3d7a
movq 0x38(%rsp), %rsi
subq 0x30(%rsp), %rsi
movslq 0xc(%rsp), %rcx
sarq $0x3, %rsi
movq %rcx, %rax
xorl %edx, %edx
divq %rsi
testq %rdx, %rdx
jne 0x35c1
movq 0x48(%rsp), %rdx
imulq %rdx, %rsi
cmpq %rcx, %rsi
jae 0x3646
xorps %xmm0, %xmm0
leaq 0x60(%rsp), %rdi
movups %xmm0, (%rdi)
andq $0x0, 0x10(%rdi)
leaq 0x4790(%rip), %rax      # 0x7d68
movq %rax, 0x58(%rsp)
movq %r12, %rsi
callq 0x3b42
leaq 0xb8(%rsp), %rbp
movq $0x1, 0x78(%rsp)
movq %rbp, %rdi
leaq 0x58(%rsp), %rsi
callq 0x3c62
movq %r15, %rdi
movq %rbp, %rsi
callq 0x48b6
movq %rbp, %rdi
callq 0x2522
addq $0x8, %r12
leaq 0x58(%rsp), %rdi
callq 0x2522
leaq 0x88(%rsp), %rbp
movq %r13, %rdi
callq 0x2522
movq 0x10(%rbx), %rdi
addq $-0x30, %rdi
callq 0x2c60
jmp 0x344d
addq %rdx, %rax
movq %rax, 0x48(%rsp)
movq %r15, %rdi
callq 0x4ace
leaq 0xe8(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0x3c62
movq 0x18(%rsp), %rdi
movq %r15, %rsi
callq 0x48b6
movq %r15, %rdi
callq 0x2522
movslq 0xc(%rsp), %rax
leaq (%r12,%rax,8), %r12
movq 0x18(%rsp), %r15
jmp 0x362c
movq %rbx, %rax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3708
movq %rax, %r15
leaq 0xe8(%rsp), %rdi
jmp 0x36ed
movq %rax, %r15
leaq 0xb8(%rsp), %rdi
callq 0x2522
jmp 0x36db
jmp 0x3717
movq %rax, %r15
leaq 0x118(%rsp), %rdi
callq 0x2522
jmp 0x36f7
movq %rax, %r15
leaq 0x58(%rsp), %rdi
jmp 0x36ed
movq %rax, %r15
leaq 0x88(%rsp), %rdi
callq 0x2522
jmp 0x370b
movq %rax, %r15
leaq 0x28(%rsp), %rdi
callq 0x2522
movq 0x20(%rsp), %rbx
jmp 0x371a
movq %rax, %r15
leaq 0x28(%rsp), %rdi
callq 0x2522
jmp 0x371a
movq %rax, %r15
movq %rbx, %rdi
callq 0x250e
movq %r15, %rdi
callq 0x21a0