// File: adamnovak[P]rlcsa/sasamples.cpp
// Function: CSA::SASamples::SASamples(std::pair<unsigned int, unsigned int>*, CSA::DeltaVector*, unsigned int, unsigned int, unsigned int)
SASamples::SASamples(short_pair* sa, DeltaVector* end_points, usint data_size, usint sample_rate, usint threads) :
  weighted(false),
  rate(sample_rate),
  items(0)
{
  usint sequences = end_points->getNumberOfItems();

  DeltaVector::Iterator iter(*(end_points));

  // Determine the samples, insert them into a vector, and sort them.
  usint start = 0, end = iter.select(0);  // Closed range in padded collection.
  usint seq_start = 0, seq_end = end;     // Closed range in inverse SA.
  std::vector<pair_type>* vec = new std::vector<pair_type>();
  for(usint i = 0; i < sequences; i++)
  {
    for(usint j = seq_start; j <= seq_end; j += this->rate)
    {
      vec->push_back(pair_type(sa[j].second - sequences, this->items));
      this->items++;
    }
    start = nextMultipleOf(this->rate, end);
    end = iter.selectNext();
    seq_start = seq_end + 2;
    seq_end = seq_start + end - start;
  }
  #ifdef MULTITHREAD_SUPPORT
  omp_set_num_threads(threads);
  #endif
  parallelSort(vec->begin(), vec->end());

  // Compress the samples.
  this->size = end + 1;
  WriteBuffer sample_buffer(this->items, length(this->items - 1));
  SAVector::Encoder encoder(INDEX_BLOCK_SIZE);
  for(usint i = 0; i < this->items; i++)
  {
    pair_type sample = (*vec)[i];
    encoder.setBit(sample.first);
    sample_buffer.writeItem(sample.second);
  }
  delete vec;

  this->indexes = new SAVector(encoder, this->size);
  this->samples = sample_buffer.getReadBuffer();
  this->buildInverseSamples();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movl %r9d, -0x24(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x1b0(%rbp)
movb $0x0, (%rax)
movl -0x20(%rbp), %ecx
movl %ecx, 0x4(%rax)
movl $0x0, 0xc(%rax)
movq -0x18(%rbp), %rdi
callq 0xd4a0
movl %eax, -0x28(%rbp)
movq -0x18(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
movq %rdi, -0x1a8(%rbp)
callq 0x200a0
movq -0x1a8(%rbp), %rdi
movl $0x0, -0xa4(%rbp)
xorl %esi, %esi
callq 0x20200
movl %eax, -0x19c(%rbp)
jmp 0x13880
movl -0x19c(%rbp), %eax
movl %eax, -0xa8(%rbp)
movl $0x0, -0xb8(%rbp)
movl -0xa8(%rbp), %eax
movl %eax, -0xbc(%rbp)
movl $0x18, %edi
callq 0x32c0
movq %rax, -0x1b8(%rbp)
jmp 0x138b5
movq -0x1b8(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x3190
movq -0x1b8(%rbp), %rdi
callq 0x14dd0
movq -0x1b8(%rbp), %rax
movq %rax, -0xc8(%rbp)
movl $0x0, -0xcc(%rbp)
movl -0xcc(%rbp), %eax
cmpl -0x28(%rbp), %eax
jae 0x13a3b
movl -0xb8(%rbp), %eax
movl %eax, -0xd0(%rbp)
movl -0xd0(%rbp), %eax
cmpl -0xbc(%rbp), %eax
ja 0x139b7
movq -0x1b0(%rbp), %rdx
movq -0xc8(%rbp), %rax
movq %rax, -0x1c0(%rbp)
movq -0x10(%rbp), %rax
movl -0xd0(%rbp), %ecx
movl 0x4(%rax,%rcx,8), %eax
movl -0x28(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0xdc(%rbp)
addq $0xc, %rdx
leaq -0xd8(%rbp), %rdi
leaq -0xdc(%rbp), %rsi
callq 0xeb40
jmp 0x13960
movq -0x1c0(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x14df0
jmp 0x13975
movq -0x1b0(%rbp), %rax
movl 0xc(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xc(%rax)
movq -0x1b0(%rbp), %rax
movl 0x4(%rax), %eax
addl -0xd0(%rbp), %eax
movl %eax, -0xd0(%rbp)
jmp 0x13907
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x13c84
movq -0x1b0(%rbp), %rax
movl 0x4(%rax), %edi
movl -0xa8(%rbp), %esi
callq 0xe550
movl %eax, -0x1c4(%rbp)
jmp 0x139d4
movl -0x1c4(%rbp), %eax
movl %eax, -0xa4(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x202a0
movl %eax, -0x1c8(%rbp)
jmp 0x139f4
movl -0x1c8(%rbp), %eax
movl %eax, -0xa8(%rbp)
movl -0xbc(%rbp), %eax
addl $0x2, %eax
movl %eax, -0xb8(%rbp)
movl -0xb8(%rbp), %eax
addl -0xa8(%rbp), %eax
subl -0xa4(%rbp), %eax
movl %eax, -0xbc(%rbp)
movl -0xcc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xcc(%rbp)
jmp 0x138ec
movq -0xc8(%rbp), %rdi
callq 0xe2e0
movq %rax, -0xe8(%rbp)
movq -0xc8(%rbp), %rdi
callq 0xe350
movq %rax, -0xf0(%rbp)
movq -0xe8(%rbp), %rdi
movq -0xf0(%rbp), %rsi
callq 0x14e20
jmp 0x13a76
movq -0x1b0(%rbp), %rax
movl -0xa8(%rbp), %ecx
incl %ecx
movl %ecx, 0x8(%rax)
movl 0xc(%rax), %edi
movl %edi, -0x1d0(%rbp)
decl %edi
callq 0x14da0
movl %eax, -0x1cc(%rbp)
jmp 0x13aa0
movl -0x1cc(%rbp), %edx
movl -0x1d0(%rbp), %esi
leaq -0x118(%rbp), %rdi
callq 0x1e430
jmp 0x13aba
leaq -0x188(%rbp), %rdi
movl $0x10, %esi
movl $0x100000, %edx         # imm = 0x100000
callq 0x206f0
jmp 0x13ad2
movl $0x0, -0x18c(%rbp)
movq -0x1b0(%rbp), %rcx
movl -0x18c(%rbp), %eax
cmpl 0xc(%rcx), %eax
jae 0x13b79
movq -0xc8(%rbp), %rdi
movl -0x18c(%rbp), %eax
movl %eax, %esi
callq 0x14e60
movq (%rax), %rax
movq %rax, -0x198(%rbp)
movl -0x198(%rbp), %esi
leaq -0x188(%rbp), %rdi
callq 0x20740
jmp 0x13b24
movl -0x194(%rbp), %esi
leaq -0x118(%rbp), %rdi
callq 0x14e80
jmp 0x13b38
jmp 0x13b3a
movl -0x18c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18c(%rbp)
jmp 0x13adc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x13c78
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x13c6c
movq -0xc8(%rbp), %rax
movq %rax, -0x1d8(%rbp)
cmpq $0x0, %rax
je 0x13baa
movq -0x1d8(%rbp), %rdi
callq 0x14ec0
movq -0x1d8(%rbp), %rdi
movl $0x18, %esi
callq 0x32d0
movl $0x48, %edi
callq 0x32c0
movq %rax, -0x1e0(%rbp)
jmp 0x13bbd
movq -0x1e0(%rbp), %rdi
movq -0x1b0(%rbp), %rax
movl 0x8(%rax), %edx
leaq -0x188(%rbp), %rsi
callq 0x20020
jmp 0x13bdc
movq -0x1b0(%rbp), %rax
movq -0x1e0(%rbp), %rcx
movq %rcx, 0x10(%rax)
leaq -0x118(%rbp), %rdi
callq 0x1e5b0
movq %rax, -0x1e8(%rbp)
jmp 0x13c03
movq -0x1b0(%rbp), %rdi
movq -0x1e8(%rbp), %rax
movq %rax, 0x18(%rdi)
callq 0x13450
jmp 0x13c1c
leaq -0x188(%rbp), %rdi
callq 0x20720
leaq -0x118(%rbp), %rdi
callq 0x1e570
leaq -0xa0(%rbp), %rdi
callq 0x200d0
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
movq -0x1e0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
movl $0x48, %esi
callq 0x32d0
leaq -0x188(%rbp), %rdi
callq 0x20720
leaq -0x118(%rbp), %rdi
callq 0x1e570
leaq -0xa0(%rbp), %rdi
callq 0x200d0
movq -0xb0(%rbp), %rdi
callq 0x3530
nopl (%rax)