// File: adamnovak[P]rlcsa/sasamples.cpp
// Function: CSA::SASamples::mergeSamples(CSA::SASamples&, CSA::SASamples&, unsigned int*, unsigned int, unsigned int)
void
SASamples::mergeSamples(SASamples& index, SASamples& increment, usint* positions, usint n, usint skip)
{
  if(index.isWeighted() || increment.isWeighted())
  {
    std::cerr << "Error: Cannot merge weighted samples!" << std::endl;
    return;
  }

  SAVector::Iterator first(*(index.indexes));
  SAVector::Iterator second(*(increment.indexes));
  ReadBuffer* first_samples = index.samples;
  ReadBuffer* second_samples = increment.samples;

  usint first_bit = first.select(0);
  bool first_finished = false;
  usint second_bit = second.select(0);
  usint sum = index.items;
  first_samples->goToItem(0);
  second_samples->goToItem(0);

  SAVector::Encoder encoder(INDEX_BLOCK_SIZE);
  WriteBuffer sample_buffer(this->items, length(this->items - 1));
  for(usint i = 0; i < n; i++, first_bit++)
  {
    while(!first_finished && first_bit < positions[i] - skip)
    {
      encoder.setBit(first_bit);
      sample_buffer.writeItem(first_samples->readItem());
      if(first.hasNext())
      {
        first_bit = first.selectNext() + i;
      }
      else
      {
        first_finished = true;
      }
    }

    if(i == second_bit) // positions[i] is one
    {
      encoder.setBit(positions[i] - skip);
      sample_buffer.writeItem(second_samples->readItem() + sum);
      second_bit = second.selectNext();
    }
  }

  while(!first_finished)
  {
    encoder.setBit(first_bit);
    sample_buffer.writeItem(first_samples->readItem());
    if(!first.hasNext()) { break; }
    first_bit = first.selectNext() + n;
  }

  delete index.indexes; index.indexes = 0;
  delete index.samples; index.samples = 0;
  delete increment.indexes; increment.indexes = 0;
  delete increment.samples; increment.samples = 0;

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

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x260, %rsp            # imm = 0x260
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movl %r9d, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq -0x10(%rbp), %rdi
callq 0xdaa0
testb $0x1, %al
jne 0x1403a
movq -0x18(%rbp), %rdi
callq 0xdaa0
testb $0x1, %al
jne 0x1403a
jmp 0x14061
movq 0x23faf(%rip), %rdi     # 0x37ff0
leaq 0x156d4(%rip), %rsi     # 0x2971c
callq 0x32a0
movq %rax, %rdi
movq 0x23f59(%rip), %rsi     # 0x37fb0
callq 0x3300
jmp 0x1458c
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rsi
leaq -0xa0(%rbp), %rdi
callq 0x200a0
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rsi
leaq -0x118(%rbp), %rdi
callq 0x200a0
jmp 0x1408b
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x130(%rbp)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x138(%rbp)
leaq -0xa0(%rbp), %rdi
xorl %esi, %esi
callq 0x20200
movl %eax, -0x1f4(%rbp)
jmp 0x140bf
movl -0x1f4(%rbp), %eax
movl %eax, -0x13c(%rbp)
movb $0x0, -0x13d(%rbp)
leaq -0x118(%rbp), %rdi
xorl %esi, %esi
callq 0x20200
movl %eax, -0x1f8(%rbp)
jmp 0x140e8
movl -0x1f8(%rbp), %eax
movl %eax, -0x144(%rbp)
movq -0x10(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x148(%rbp)
movq -0x130(%rbp), %rdi
xorl %esi, %esi
callq 0x15070
jmp 0x14111
movq -0x138(%rbp), %rdi
xorl %esi, %esi
callq 0x15070
jmp 0x14121
leaq -0x1b8(%rbp), %rdi
movl $0x10, %esi
movl $0x100000, %edx         # imm = 0x100000
callq 0x206f0
jmp 0x14139
movq -0x1f0(%rbp), %rax
movl 0xc(%rax), %edi
movl %edi, -0x200(%rbp)
decl %edi
callq 0x14da0
movl %eax, -0x1fc(%rbp)
jmp 0x14158
movl -0x1fc(%rbp), %edx
movl -0x200(%rbp), %esi
leaq -0x1e0(%rbp), %rdi
callq 0x1e430
jmp 0x14172
movl $0x0, -0x1e4(%rbp)
movl -0x1e4(%rbp), %eax
cmpl -0x24(%rbp), %eax
jae 0x14360
jmp 0x1418d
xorl %eax, %eax
testb $0x1, -0x13d(%rbp)
movb %al, -0x201(%rbp)
jne 0x141bf
movl -0x13c(%rbp), %eax
movq -0x20(%rbp), %rcx
movl -0x1e4(%rbp), %edx
movl (%rcx,%rdx,4), %ecx
subl -0x28(%rbp), %ecx
cmpl %ecx, %eax
setb %al
movb %al, -0x201(%rbp)
movb -0x201(%rbp), %al
testb $0x1, %al
jne 0x141ce
jmp 0x142bd
movl -0x13c(%rbp), %esi
leaq -0x1b8(%rbp), %rdi
callq 0x20740
jmp 0x141e2
movq -0x130(%rbp), %rdi
callq 0x14ff0
movl %eax, -0x208(%rbp)
jmp 0x141f6
movl -0x208(%rbp), %esi
leaq -0x1e0(%rbp), %rdi
callq 0x14e80
jmp 0x1420a
leaq -0xa0(%rbp), %rdi
callq 0xf6b0
movb %al, -0x209(%rbp)
jmp 0x1421e
movb -0x209(%rbp), %al
testb $0x1, %al
jne 0x1422d
jmp 0x142b1
leaq -0xa0(%rbp), %rdi
callq 0x202a0
movl %eax, -0x210(%rbp)
jmp 0x14241
movl -0x210(%rbp), %eax
addl -0x1e4(%rbp), %eax
movl %eax, -0x13c(%rbp)
jmp 0x142b8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x120(%rbp)
movl %eax, -0x124(%rbp)
jmp 0x145dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x120(%rbp)
movl %eax, -0x124(%rbp)
jmp 0x145d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x120(%rbp)
movl %eax, -0x124(%rbp)
jmp 0x145c4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x120(%rbp)
movl %eax, -0x124(%rbp)
jmp 0x145b8
movb $0x1, -0x13d(%rbp)
jmp 0x1418d
movl -0x1e4(%rbp), %eax
cmpl -0x144(%rbp), %eax
jne 0x1433b
movq -0x20(%rbp), %rax
movl -0x1e4(%rbp), %ecx
movl (%rax,%rcx,4), %esi
movl -0x28(%rbp), %eax
subl %eax, %esi
leaq -0x1b8(%rbp), %rdi
callq 0x20740
jmp 0x142eb
movq -0x138(%rbp), %rdi
callq 0x14ff0
movl %eax, -0x214(%rbp)
jmp 0x142ff
movl -0x214(%rbp), %esi
movl -0x148(%rbp), %eax
addl %eax, %esi
leaq -0x1e0(%rbp), %rdi
callq 0x14e80
jmp 0x1431b
leaq -0x118(%rbp), %rdi
callq 0x202a0
movl %eax, -0x218(%rbp)
jmp 0x1432f
movl -0x218(%rbp), %eax
movl %eax, -0x144(%rbp)
jmp 0x1433d
movl -0x1e4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1e4(%rbp)
movl -0x13c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x13c(%rbp)
jmp 0x1417c
jmp 0x14362
movb -0x13d(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x14373
jmp 0x143f9
movl -0x13c(%rbp), %esi
leaq -0x1b8(%rbp), %rdi
callq 0x20740
jmp 0x14387
movq -0x130(%rbp), %rdi
callq 0x14ff0
movl %eax, -0x21c(%rbp)
jmp 0x1439b
movl -0x21c(%rbp), %esi
leaq -0x1e0(%rbp), %rdi
callq 0x14e80
jmp 0x143af
leaq -0xa0(%rbp), %rdi
callq 0xf6b0
movb %al, -0x21d(%rbp)
jmp 0x143c3
movb -0x21d(%rbp), %al
testb $0x1, %al
jne 0x143d1
jmp 0x143cf
jmp 0x143f9
leaq -0xa0(%rbp), %rdi
callq 0x202a0
movl %eax, -0x224(%rbp)
jmp 0x143e5
movl -0x224(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x13c(%rbp)
jmp 0x14362
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x230(%rbp)
cmpq $0x0, %rax
je 0x1442b
movq -0x230(%rbp), %rdi
callq 0x20050
movq -0x230(%rbp), %rdi
movl $0x48, %esi
callq 0x32d0
movq -0x10(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x238(%rbp)
cmpq $0x0, %rax
je 0x14469
movq -0x238(%rbp), %rdi
callq 0x1e230
movq -0x238(%rbp), %rdi
movl $0x28, %esi
callq 0x32d0
movq -0x10(%rbp), %rax
movq $0x0, 0x18(%rax)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x240(%rbp)
cmpq $0x0, %rax
je 0x144a7
movq -0x240(%rbp), %rdi
callq 0x20050
movq -0x240(%rbp), %rdi
movl $0x48, %esi
callq 0x32d0
movq -0x18(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x248(%rbp)
cmpq $0x0, %rax
je 0x144e5
movq -0x248(%rbp), %rdi
callq 0x1e230
movq -0x248(%rbp), %rdi
movl $0x28, %esi
callq 0x32d0
movq -0x18(%rbp), %rax
movq $0x0, 0x18(%rax)
movl $0x48, %edi
callq 0x32c0
movq %rax, -0x250(%rbp)
jmp 0x14504
movq -0x250(%rbp), %rdi
movq -0x1f0(%rbp), %rax
movl 0x8(%rax), %edx
leaq -0x1b8(%rbp), %rsi
callq 0x20020
jmp 0x14523
movq -0x1f0(%rbp), %rax
movq -0x250(%rbp), %rcx
movq %rcx, 0x10(%rax)
leaq -0x1e0(%rbp), %rdi
callq 0x1e5b0
movq %rax, -0x258(%rbp)
jmp 0x1454a
movq -0x1f0(%rbp), %rax
movq -0x258(%rbp), %rcx
movq %rcx, 0x18(%rax)
leaq -0x1e0(%rbp), %rdi
callq 0x1e570
leaq -0x1b8(%rbp), %rdi
callq 0x20720
leaq -0x118(%rbp), %rdi
callq 0x200d0
leaq -0xa0(%rbp), %rdi
callq 0x200d0
addq $0x260, %rsp            # imm = 0x260
popq %rbp
retq
movq -0x250(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x120(%rbp)
movl %eax, -0x124(%rbp)
movl $0x48, %esi
callq 0x32d0
leaq -0x1e0(%rbp), %rdi
callq 0x1e570
leaq -0x1b8(%rbp), %rdi
callq 0x20720
leaq -0x118(%rbp), %rdi
callq 0x200d0
leaq -0xa0(%rbp), %rdi
callq 0x200d0
movq -0x120(%rbp), %rdi
callq 0x3530
nopw %cs:(%rax,%rax)