// File: adamnovak[P]rlcsa/./bits/vectors.h
// Function: CSA::RLEVector* CSA::mergeVectors<CSA::RLEVector, CSA::RLEEncoder, CSA::RLEVector::Iterator>(CSA::RLEVector*, CSA::RLEVector*, unsigned int*, unsigned int, unsigned int, unsigned int)
V*
mergeVectors(V* first, V* second, usint* positions, usint n, usint size, usint block_size)
{
  if((first == 0 && second == 0) || positions == 0) { return 0; }

  I* first_iter = 0;
  I* second_iter = 0;

  pair_type first_run;
  bool first_finished;
  if(first == 0)
  {
    first_run = pair_type(size, 0);
    first_finished = true;
  }
  else
  {
    first_iter = new I(*first);
    first_run = first_iter->selectRun(0, size);
    first_run.second++;
    first_finished = false;
  }

  usint second_bit;
  if(second == 0)
  {
    second_bit = n;
  }
  else
  {
    second_iter = new I(*second);
    second_bit = second_iter->select(0);
  }

  E encoder(block_size);
  for(usint i = 0; i < n; i++)
  {
    while(!first_finished && first_run.first + i < positions[i])
    {
      usint bits = std::min(first_run.second, positions[i] - i - first_run.first);
      encoder.addRun(first_run.first + i, bits);
      first_run.first += bits;
      first_run.second -= bits;
      if(first_run.second == 0)
      {
        if(first_iter->hasNext())
        {
          first_run = first_iter->selectNextRun(size);
          first_run.second++;
        }
        else { first_finished = true; }
      }
    }

    if(i == second_bit) // positions[i] is one
    {
      encoder.addBit(positions[i]);
      second_bit = second_iter->selectNext();
    }
  }

  while(!first_finished)
  {
    encoder.addRun(first_run.first + n, first_run.second);
    if(first_iter->hasNext())
    {
      first_run = first_iter->selectNextRun(size);
      first_run.second++;
    }
    else { first_finished = true; }
  }

  delete first_iter; delete second_iter;
  delete first; delete second;
  encoder.flush();
  return new V(encoder, size);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x160, %rsp            # imm = 0x160
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movl %r8d, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0xd580
cmpq $0x0, -0x18(%rbp)
je 0xd587
cmpq $0x0, -0x20(%rbp)
jne 0xd594
movq $0x0, -0x8(%rbp)
jmp 0xda36
movq $0x0, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
leaq -0x48(%rbp), %rdi
callq 0xe530
cmpq $0x0, -0x10(%rbp)
jne 0xd5df
movl $0x0, -0x58(%rbp)
leaq -0x54(%rbp), %rdi
leaq -0x28(%rbp), %rsi
leaq -0x58(%rbp), %rdx
callq 0xe9d0
leaq -0x48(%rbp), %rdi
leaq -0x54(%rbp), %rsi
callq 0xdb70
movb $0x1, -0x49(%rbp)
jmp 0xd65c
movl $0x78, %edi
callq 0x32c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x110(%rbp)
movq -0x10(%rbp), %rsi
callq 0x20a90
jmp 0xd601
movq -0x110(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
movl -0x28(%rbp), %edx
xorl %esi, %esi
callq 0x21120
movq %rax, -0x6c(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x6c(%rbp), %rsi
callq 0xdb70
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
movb $0x0, -0x49(%rbp)
jmp 0xd65c
movq -0x110(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
movl $0x78, %esi
callq 0x32d0
jmp 0xda43
cmpq $0x0, -0x18(%rbp)
jne 0xd66b
movl -0x24(%rbp), %eax
movl %eax, -0x70(%rbp)
jmp 0xd6ca
movl $0x78, %edi
callq 0x32c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x118(%rbp)
movq -0x18(%rbp), %rsi
callq 0x20a90
jmp 0xd68d
movq -0x118(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
xorl %esi, %esi
callq 0x20c90
movl %eax, -0x70(%rbp)
jmp 0xd6ca
movq -0x118(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
movl $0x78, %esi
callq 0x32d0
jmp 0xda43
movl -0x2c(%rbp), %esi
leaq -0xe8(%rbp), %rdi
movl $0x100000, %edx         # imm = 0x100000
callq 0x21340
movl $0x0, -0xec(%rbp)
movl -0xec(%rbp), %eax
cmpl -0x24(%rbp), %eax
jae 0xd877
jmp 0xd6f9
xorl %eax, %eax
testb $0x1, -0x49(%rbp)
movb %al, -0x119(%rbp)
jne 0xd726
movl -0x48(%rbp), %eax
addl -0xec(%rbp), %eax
movq -0x20(%rbp), %rcx
movl -0xec(%rbp), %edx
cmpl (%rcx,%rdx,4), %eax
setb %al
movb %al, -0x119(%rbp)
movb -0x119(%rbp), %al
testb $0x1, %al
jne 0xd735
jmp 0xd821
leaq -0x44(%rbp), %rdi
movq -0x20(%rbp), %rax
movl -0xec(%rbp), %ecx
movl %ecx, %edx
movl %edx, %ecx
movl (%rax,%rdx,4), %eax
subl %ecx, %eax
movl -0x48(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0xf4(%rbp)
leaq -0xf4(%rbp), %rsi
callq 0x63a0
movl (%rax), %eax
movl %eax, -0xf0(%rbp)
movl -0x48(%rbp), %esi
movl -0xec(%rbp), %eax
addl %eax, %esi
movl -0xf0(%rbp), %edx
leaq -0xe8(%rbp), %rdi
callq 0x21590
jmp 0xd78a
movl -0xf0(%rbp), %eax
addl -0x48(%rbp), %eax
movl %eax, -0x48(%rbp)
movl -0xf0(%rbp), %ecx
movl -0x44(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x44(%rbp)
cmpl $0x0, -0x44(%rbp)
jne 0xd81c
movq -0x38(%rbp), %rdi
callq 0xf6b0
movb %al, -0x11a(%rbp)
jmp 0xd7bb
movb -0x11a(%rbp), %al
testb $0x1, %al
jne 0xd7c7
jmp 0xd816
movq -0x38(%rbp), %rdi
movl -0x28(%rbp), %esi
callq 0x211a0
movq %rax, -0x128(%rbp)
jmp 0xd7dc
movq -0x128(%rbp), %rax
movq %rax, -0xfc(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0xfc(%rbp), %rsi
callq 0xdb70
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0xd81a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0xda28
movb $0x1, -0x49(%rbp)
jmp 0xd81c
jmp 0xd6f9
movl -0xec(%rbp), %eax
cmpl -0x70(%rbp), %eax
jne 0xd861
movq -0x20(%rbp), %rax
movl -0xec(%rbp), %ecx
movl (%rax,%rcx,4), %esi
leaq -0xe8(%rbp), %rdi
callq 0x21560
jmp 0xd847
movq -0x40(%rbp), %rdi
callq 0x20d90
movl %eax, -0x12c(%rbp)
jmp 0xd858
movl -0x12c(%rbp), %eax
movl %eax, -0x70(%rbp)
jmp 0xd863
movl -0xec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xec(%rbp)
jmp 0xd6e8
jmp 0xd879
movb -0x49(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xd884
jmp 0xd901
movl -0x24(%rbp), %eax
movl -0x48(%rbp), %esi
movl -0x44(%rbp), %edx
addl %eax, %esi
leaq -0xe8(%rbp), %rdi
callq 0x21590
jmp 0xd89d
movq -0x38(%rbp), %rdi
callq 0xf6b0
movb %al, -0x12d(%rbp)
jmp 0xd8ae
movb -0x12d(%rbp), %al
testb $0x1, %al
jne 0xd8ba
jmp 0xd8f8
movq -0x38(%rbp), %rdi
movl -0x28(%rbp), %esi
callq 0x211a0
movq %rax, -0x138(%rbp)
jmp 0xd8cf
movq -0x138(%rbp), %rax
movq %rax, -0x104(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x104(%rbp), %rsi
callq 0xdb70
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0xd8fc
movb $0x1, -0x49(%rbp)
jmp 0xd879
movq -0x38(%rbp), %rax
movq %rax, -0x140(%rbp)
cmpq $0x0, %rax
je 0xd92f
movq -0x140(%rbp), %rdi
callq 0x20ac0
movq -0x140(%rbp), %rdi
movl $0x78, %esi
callq 0x32d0
movq -0x40(%rbp), %rax
movq %rax, -0x148(%rbp)
cmpq $0x0, %rax
je 0xd95d
movq -0x148(%rbp), %rdi
callq 0x20ac0
movq -0x148(%rbp), %rdi
movl $0x78, %esi
callq 0x32d0
movq -0x10(%rbp), %rax
movq %rax, -0x150(%rbp)
cmpq $0x0, %rax
je 0xd98b
movq -0x150(%rbp), %rdi
callq 0x20a40
movq -0x150(%rbp), %rdi
movl $0x48, %esi
callq 0x32d0
movq -0x18(%rbp), %rax
movq %rax, -0x158(%rbp)
cmpq $0x0, %rax
je 0xd9b9
movq -0x158(%rbp), %rdi
callq 0x20a40
movq -0x158(%rbp), %rdi
movl $0x48, %esi
callq 0x32d0
leaq -0xe8(%rbp), %rdi
callq 0x21630
jmp 0xd9c7
movl $0x48, %edi
callq 0x32c0
movq %rax, -0x160(%rbp)
jmp 0xd9da
movq -0x160(%rbp), %rdi
movl -0x28(%rbp), %edx
leaq -0xe8(%rbp), %rsi
callq 0x20a10
jmp 0xd9f2
movq -0x160(%rbp), %rax
movq %rax, -0x8(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x21380
jmp 0xda36
movq -0x160(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
movl $0x48, %esi
callq 0x32d0
leaq -0xe8(%rbp), %rdi
callq 0x21380
jmp 0xda43
movq -0x8(%rbp), %rax
addq $0x160, %rsp            # imm = 0x160
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x3530
nopl (%rax)