// File: adamnovak[P]rlcsa/bits/rlevector.cpp
// Function: CSA::RLEEncoder::setRun(unsigned int, unsigned int)
void
RLEEncoder::setRun(usint start, usint len)
{
  if(this->items == 0)
  {
    this->setFirstBit(start);
    if(len > 1)
    {
      this->RLEncode(1, len - 1);
    }
    return;
  }
  if(start < this->size || len == 0) { return; }

  // Write as much into the buffer as possible.
  usint diff = start + 1 - this->size;
  usint free_bits = this->buffer->bitsLeft();
  usint code_bits = this->buffer->deltaCodeLength(diff);
  if(free_bits > code_bits) // At least a part of the run fits into the block.
  {
    free_bits -= code_bits;
    usint run_bits = this->buffer->deltaCodeLength(len);
    if(run_bits <= free_bits)
    {
      this->RLEncode(diff, len);
      return;
    }

    // Encode as much as possible and let the rest spill.
    usint llen = 1;
    while(llen + 2 * length(llen + 1) - 1 <= free_bits) { llen++; }
    llen = ((usint)1 << llen) - 1;

    this->RLEncode(diff, llen);
    len -= llen;

    // A new sample will be added.
    this->size++;
    this->items++;
  }
  else
  {
    this->size = start + 1;
    this->items++;
  }

  // Didn't fit into the block. A new sample & block required.
  this->addNewBlock();
  if(len > 1)
  {
    this->RLEncode(1, len - 1);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x30(%rbp)
cmpl $0x0, 0x4(%rax)
jne 0x2141b
movq -0x30(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x1fe70
cmpl $0x1, -0x10(%rbp)
jbe 0x21416
movq -0x30(%rbp), %rdi
movl -0x10(%rbp), %edx
subl $0x1, %edx
movl $0x1, %esi
callq 0x21660
jmp 0x21553
movq -0x30(%rbp), %rcx
movl -0xc(%rbp), %eax
cmpl (%rcx), %eax
jb 0x2142c
cmpl $0x0, -0x10(%rbp)
jne 0x21431
jmp 0x21553
movq -0x30(%rbp), %rax
movl -0xc(%rbp), %ecx
addl $0x1, %ecx
subl (%rax), %ecx
movl %ecx, -0x14(%rbp)
movq 0x18(%rax), %rdi
callq 0x1db30
movl %eax, %ecx
movq -0x30(%rbp), %rax
movl %ecx, -0x18(%rbp)
movq 0x18(%rax), %rdi
movl -0x14(%rbp), %esi
callq 0x216c0
movl %eax, -0x1c(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jbe 0x2151b
movq -0x30(%rbp), %rax
movl -0x1c(%rbp), %edx
movl -0x18(%rbp), %ecx
subl %edx, %ecx
movl %ecx, -0x18(%rbp)
movq 0x18(%rax), %rdi
movl -0x10(%rbp), %esi
callq 0x216c0
movl %eax, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0x18(%rbp), %eax
ja 0x214a7
movq -0x30(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x10(%rbp), %edx
callq 0x21660
jmp 0x21553
movl $0x1, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x34(%rbp)
movl -0x24(%rbp), %edi
addl $0x1, %edi
callq 0x14da0
movl %eax, %ecx
movl -0x34(%rbp), %eax
shll %ecx
addl %ecx, %eax
subl $0x1, %eax
cmpl -0x18(%rbp), %eax
ja 0x214db
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x214ae
movq -0x30(%rbp), %rdi
movl -0x24(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
subl $0x1, %eax
movl %eax, -0x24(%rbp)
movl -0x14(%rbp), %esi
movl -0x24(%rbp), %edx
callq 0x21660
movq -0x30(%rbp), %rax
movl -0x24(%rbp), %edx
movl -0x10(%rbp), %ecx
subl %edx, %ecx
movl %ecx, -0x10(%rbp)
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
jmp 0x21530
movq -0x30(%rbp), %rax
movl -0xc(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
movq -0x30(%rbp), %rdi
callq 0x1fd00
cmpl $0x1, -0x10(%rbp)
jbe 0x21553
movq -0x30(%rbp), %rdi
movl -0x10(%rbp), %edx
subl $0x1, %edx
movl $0x1, %esi
callq 0x21660
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)