// File: /workspace/github_cpp_makefile_star2_O2/adamnovak[P]rlcsa/adaptive_samples.cpp
// Function: CSA::AdaptiveSamples::locate(unsigned int, bool)
usint
AdaptiveSamples::locate(usint i, bool steps)
{
  if(i >= this->index.getSize()) { return (steps ? 0 : this->index.getSize()); }

  usint offset = 0;
  sample_type sample(i, 0);
  this->index.convertToBWTIndex(i);

  while(true)
  {
    // Priority 1: Implicit samples.
    if(this->index.hasImplicitSample(i))
    {
      sample.second = this->index.getImplicitSample(i) - offset;
      break;
    }
    this->index.convertToSAIndex(i);

    // Priority 2: Regular samples.
    if(this->half_greedy && this->regular_samples->isSampled(i))
    {
      sample.second = this->regular_samples->getSampleAt(i) - offset;
      break;
    }

    // Priority 3: Primary samples.
    key_type j = this->hash(i);
    if(this->samples[j].first == i)
    {
      sample.second = this->samples[j].second - offset;
      break;
    }

    // Priority 4: Candidate samples.
    if(this->use_candidates)
    {
      j = this->secondaryHash(i);
      if(this->candidate_samples[j].first == i)
      {
        sample.second = this->candidate_samples[j].second - offset;
        this->addSample(this->candidate_samples[j]);
        break;
      }
    }

    i = this->index.psi(i); offset++;
  }

  if(offset > 0) { this->trySample(sample, offset); }

  // Update the average number of steps taken.
  if(this->promote_probability > 0.0)
  {
    this->sum = this->sum + offset - this->window[this->pos];
    this->window[this->pos] = offset; this->pos = (this->pos + 1) % this->window_size;
  }

  return (steps ? offset : sample.second);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %ebx
movq %rdi, %r14
movq (%rdi), %rdi
movl 0x4(%rdi), %r12d
cmpl %esi, %r12d
jbe 0x10b57
movl %esi, %r15d
movl 0x820(%rdi), %ecx
leal (%rcx,%r15), %eax
xorl %r13d, %r13d
movl %eax, %ebp
subl %ecx, %ebp
jb 0x10b64
cmpb $0x1, 0x35(%r14)
jne 0x10b0e
movq 0x28(%r14), %rdi
movl %ebp, %esi
callq 0xb23a
testb %al, %al
jne 0x10b74
movq %r14, %rdi
movl %ebp, %esi
callq 0x10c08
movq 0x8(%r14), %rcx
movl %eax, %eax
cmpl %ebp, (%rcx,%rax,8)
je 0x10b6d
cmpb $0x1, 0x34(%r14)
jne 0x10b3f
movq %r14, %rdi
movl %ebp, %esi
callq 0x10c38
movq 0x18(%r14), %rcx
movl %eax, %eax
cmpl %ebp, (%rcx,%rax,8)
je 0x10b84
movq (%r14), %rdi
movl %ebp, %esi
callq 0xb2ec
movq (%r14), %rdi
movl 0x820(%rdi), %ecx
decl %r13d
jmp 0x10af2
xorl %eax, %eax
testb %bl, %bl
cmovnel %eax, %r12d
jmp 0x10bf5
movl %eax, %esi
callq 0xb1ec
jmp 0x10b7f
movl 0x4(%rcx,%rax,8), %r12d
jmp 0x10b95
movq 0x28(%r14), %rdi
movl %ebp, %esi
callq 0xb284
movl %eax, %r12d
jmp 0x10b95
movl 0x4(%rcx,%rax,8), %r12d
movq (%rcx,%rax,8), %rsi
movq %r14, %rdi
callq 0x107a4
addl %r13d, %r12d
movl %r13d, %ebp
negl %ebp
jae 0x10bb6
movq %r12, %rax
shlq $0x20, %rax
movl %r15d, %esi
orq %rax, %rsi
movq %r14, %rdi
movl %ebp, %edx
callq 0x10c88
movsd 0x38(%r14), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x10bef
movl 0x44(%r14), %eax
movl 0x48(%r14), %ecx
movq 0x50(%r14), %rdx
subl (%rdx,%rax,4), %ecx
subl %r13d, %ecx
movl %ecx, 0x48(%r14)
movl %ebp, (%rdx,%rax,4)
movl 0x44(%r14), %eax
incl %eax
xorl %edx, %edx
divl 0x40(%r14)
movl %edx, 0x44(%r14)
testb %bl, %bl
cmovnel %ebp, %r12d
movl %r12d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop