// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1c8, %rsp            # imm = 0x1C8
movl %r8d, 0x10(%rsp)
movq %rsi, 0x8(%rsp)
cmpb $0x0, (%rsi)
jne 0xa37c
movq %rdx, %rbp
cmpb $0x1, (%rdx)
jne 0xa3a8
movq 0x12c6d(%rip), %rdi     # 0x1cff0
leaq 0x9302(%rip), %rsi      # 0x1368c
callq 0x3200
movq %rax, %rdi
addq $0x1c8, %rsp            # imm = 0x1C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3100
movl %r9d, %r13d
movq %rcx, %rbx
movq %rdi, %r15
movq 0x8(%rsp), %r14
movq 0x10(%r14), %rsi
leaq 0x68(%rsp), %rdi
callq 0xf8d8
movq 0x10(%rbp), %rsi
leaq 0x150(%rsp), %rdi
callq 0xf8d8
movq 0x18(%r14), %r12
movq 0x18(%rbp), %rax
movq %rax, 0x28(%rsp)
leaq 0x68(%rsp), %rdi
xorl %esi, %esi
callq 0xf976
movl %eax, %r14d
leaq 0x150(%rsp), %rdi
xorl %esi, %esi
callq 0xf976
movl %eax, 0x14(%rsp)
movq 0x8(%rsp), %rax
movl 0xc(%rax), %eax
movl %eax, 0x24(%rsp)
movabsq $0x2000000000, %rax     # imm = 0x2000000000
movq %rax, 0x18(%r12)
andl $0x0, 0x20(%r12)
movq 0x28(%rsp), %rcx
movq %rax, 0x18(%rcx)
andl $0x0, 0x20(%rcx)
leaq 0xe0(%rsp), %rdi
pushq $0x10
popq %rsi
movl $0x100000, %edx         # imm = 0x100000
callq 0xfbb6
movq %rbp, 0x18(%rsp)
movq %r15, 0x30(%rsp)
movl 0xc(%r15), %r15d
leal -0x1(%r15), %edi
callq 0xab34
leaq 0x40(%rsp), %rdi
movl %r15d, %esi
movl %eax, %edx
callq 0xe8b6
movl 0x10(%rsp), %eax
movq %rax, 0x38(%rsp)
xorl %r15d, %r15d
xorl %ebp, %ebp
cmpq 0x38(%rsp), %r15
je 0xa53b
movl %ebp, %eax
movl %eax, %ebp
testb $0x1, %al
jne 0xa4e8
movl (%rbx,%r15,4), %eax
subl %r13d, %eax
cmpl %eax, %r14d
jae 0xa4e8
leaq 0xe0(%rsp), %rdi
movl %r14d, %esi
callq 0xfbc4
movq %r12, %rdi
callq 0xabd0
leaq 0x40(%rsp), %rdi
movl %eax, %esi
callq 0xab42
movl 0x7c(%rsp), %ecx
addl 0x74(%rsp), %ecx
movq 0x68(%rsp), %rax
movl 0x4(%rax), %edx
decl %edx
movb $0x1, %al
cmpl %edx, %ecx
jae 0xa488
leaq 0x68(%rsp), %rdi
callq 0xf9d8
movl %eax, %r14d
addl %r15d, %r14d
jmp 0xa486
movl 0x14(%rsp), %eax
cmpq %rax, %r15
jne 0xa530
movl (%rbx,%r15,4), %esi
subl %r13d, %esi
leaq 0xe0(%rsp), %rdi
callq 0xfbc4
movq 0x28(%rsp), %rdi
callq 0xabd0
addl 0x24(%rsp), %eax
leaq 0x40(%rsp), %rdi
movl %eax, %esi
callq 0xab42
leaq 0x150(%rsp), %rdi
callq 0xf9d8
movl %eax, 0x14(%rsp)
incl %r14d
incq %r15
jmp 0xa47b
testb $0x1, %bpl
movq 0x30(%rsp), %rbp
je 0xa65c
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rbx
testq %rbx, %rbx
je 0xa560
movq %rbx, %rdi
callq 0xf8c6
pushq $0x48
popq %rsi
movq %rbx, %rdi
callq 0x3230
movq 0x8(%rsp), %rax
andq $0x0, 0x10(%rax)
movq 0x18(%rax), %rbx
testq %rbx, %rbx
je 0xa586
movq %rbx, %rdi
callq 0xe7c4
pushq $0x28
popq %rsi
movq %rbx, %rdi
callq 0x3230
movq 0x8(%rsp), %rax
andq $0x0, 0x18(%rax)
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rbx
testq %rbx, %rbx
je 0xa5b1
movq %rbx, %rdi
callq 0xf8c6
pushq $0x48
popq %rsi
movq %rbx, %rdi
callq 0x3230
movq 0x18(%rsp), %rax
andq $0x0, 0x10(%rax)
movq 0x18(%rax), %rbx
testq %rbx, %rbx
je 0xa5d7
movq %rbx, %rdi
callq 0xe7c4
pushq $0x28
popq %rsi
movq %rbx, %rdi
callq 0x3230
movq 0x18(%rsp), %rax
andq $0x0, 0x18(%rax)
pushq $0x48
popq %rdi
callq 0x3220
movq %rax, %r14
movl 0x8(%rbp), %edx
leaq 0xe0(%rsp), %rsi
movq %rax, %rdi
callq 0xf8c0
movq %r14, 0x10(%rbp)
leaq 0x40(%rsp), %rdi
callq 0xe972
movq %rax, 0x18(%rbp)
leaq 0x40(%rsp), %rdi
callq 0xe95e
leaq 0xe0(%rsp), %rdi
callq 0xfbbe
leaq 0x150(%rsp), %rdi
callq 0xf8de
leaq 0x68(%rsp), %rdi
callq 0xf8de
addq $0x1c8, %rsp            # imm = 0x1C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xe0(%rsp), %rbx
leaq 0x40(%rsp), %r15
leaq 0x68(%rsp), %r13
movq %rbx, %rdi
movl %r14d, %esi
callq 0xfbc4
movq %r12, %rdi
callq 0xabd0
movq %r15, %rdi
movl %eax, %esi
callq 0xab42
movl 0x7c(%rsp), %eax
addl 0x74(%rsp), %eax
movq 0x68(%rsp), %rcx
movl 0x4(%rcx), %ecx
decl %ecx
cmpl %ecx, %eax
jae 0xa54a
movq %r13, %rdi
callq 0xf9d8
movl %eax, %r14d
addl 0x10(%rsp), %r14d
jmp 0xa66e
movq %rax, %rbx
pushq $0x48
popq %rsi
movq %r14, %rdi
callq 0x3230
jmp 0xa6e5
movq %rax, %rbx
jmp 0xa6ef
jmp 0xa6d0
jmp 0xa6d0
movq %rax, %rbx
jmp 0xa6fc
movq %rax, %rbx
jmp 0xa709
jmp 0xa6e2
jmp 0xa6e2
jmp 0xa6e2
jmp 0xa6e2
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0xe95e
leaq 0xe0(%rsp), %rdi
callq 0xfbbe
leaq 0x150(%rsp), %rdi
callq 0xf8de
leaq 0x68(%rsp), %rdi
callq 0xf8de
movq %rbx, %rdi
callq 0x3410
nop