// File: junhe[P]libpatterndetector/pattern.cpp
// Function: PatternUtil::searchNeighbor(std::vector<long, std::allocator<long>> const&, __gnu_cxx::__normal_iterator<long const*, std::vector<long, std::allocator<long>>>)
Tuple 
PatternUtil::searchNeighbor( vector<off_t> const &seq,
        vector<off_t>::const_iterator p_lookahead_win ) 
{
    vector<off_t>::const_iterator i;     
    int j;
    //cout << "------------------- I am in searchNeighbor() " << endl;

    //i goes left util the begin or reaching window size
    i = p_lookahead_win;
    int remain = seq.end() - p_lookahead_win;
    while ( i != seq.begin() 
            && (p_lookahead_win - i) < win_size
            && (p_lookahead_win - i) < remain ) {
        i--;
    }
    //termination: i == seq.begin() or distance == win_size

    /*
    //print out search buffer and lookahead buffer
    //cout << "search buf: " ;
    vector<off_t>::const_iterator k;
    for ( k = i ; k != p_lookahead_win ; k++ ) {
    cout << *k << " ";
    }
    cout << endl;

    cout << "lookahead buf: " ;
    vector<off_t>::const_iterator p;
    p = p_lookahead_win;
    for ( p = p_lookahead_win ; 
    p != seq.end() && p - p_lookahead_win < win_size ; 
    p++ ) {
    cout << *p << " ";
    }
    cout << endl;
    */

    //i points to a element in search buffer where matching starts
    //j is the iterator from the start to the end of search buffer to compare
    //smarter algorithm can be used better time complexity, like KMP.
    for ( ; i != p_lookahead_win ; i++ ) {
        int search_length = p_lookahead_win - i;
        for ( j = 0 ; j < search_length ; j++ ) {
            if ( *(i+j) != *(p_lookahead_win + j) ) {
                break;
            }
        }
        if ( j == search_length ) {
            //found a repeating neighbor
            return Tuple(search_length, search_length, 
                    *(p_lookahead_win + search_length));
        }
    }

    //Cannot find a repeating neighbor
    return Tuple(0, 0, *(p_lookahead_win));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rsi, -0x18(%rbp)
movq %rdi, -0x20(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x6980
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rdi
callq 0x6d00
movq %rax, -0x38(%rbp)
leaq -0x38(%rbp), %rdi
leaq -0x18(%rbp), %rsi
callq 0x79d0
movl %eax, -0x30(%rbp)
movq -0x20(%rbp), %rdi
callq 0x6c90
movq %rax, -0x40(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x6cc0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x71(%rbp)
jne 0x5f49
jmp 0x5f7e
leaq -0x18(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x79d0
movq %rax, %rcx
xorl %eax, %eax
cmpq $0x6, %rcx
movb %al, -0x71(%rbp)
jge 0x5f7e
leaq -0x18(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x79d0
movslq -0x30(%rbp), %rcx
cmpq %rcx, %rax
setl %al
movb %al, -0x71(%rbp)
movb -0x71(%rbp), %al
testb $0x1, %al
jne 0x5f87
jmp 0x5f98
leaq -0x28(%rbp), %rdi
xorl %esi, %esi
callq 0x7a10
movq %rax, -0x48(%rbp)
jmp 0x5f21
jmp 0x5f9a
leaq -0x28(%rbp), %rdi
leaq -0x18(%rbp), %rsi
callq 0x6cc0
testb $0x1, %al
jne 0x5fb0
jmp 0x6089
leaq -0x18(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x79d0
movl %eax, -0x4c(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x4c(%rbp), %eax
jge 0x6025
movslq -0x2c(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x7890
movq %rax, -0x58(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x6a80
movq (%rax), %rax
movq %rax, -0x80(%rbp)
movslq -0x2c(%rbp), %rsi
leaq -0x18(%rbp), %rdi
callq 0x7890
movq %rax, -0x60(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x6a80
movq %rax, %rcx
movq -0x80(%rbp), %rax
cmpq (%rcx), %rax
je 0x6018
jmp 0x6025
jmp 0x601a
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x5fc7
movl -0x2c(%rbp), %eax
cmpl -0x4c(%rbp), %eax
jne 0x6073
movl -0x4c(%rbp), %eax
movl %eax, -0x88(%rbp)
movl -0x4c(%rbp), %eax
movl %eax, -0x84(%rbp)
movslq -0x4c(%rbp), %rsi
leaq -0x18(%rbp), %rdi
callq 0x7890
movq %rax, -0x68(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x6a80
movl -0x88(%rbp), %esi
movl -0x84(%rbp), %edx
movq (%rax), %rcx
leaq -0x10(%rbp), %rdi
callq 0x7a50
jmp 0x60a2
jmp 0x6075
leaq -0x28(%rbp), %rdi
xorl %esi, %esi
callq 0x6aa0
movq %rax, -0x70(%rbp)
jmp 0x5f9a
leaq -0x18(%rbp), %rdi
callq 0x6a80
movq (%rax), %rcx
leaq -0x10(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x7a50
movq -0x10(%rbp), %rax
movq -0x8(%rbp), %rdx
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)