// File: adamnovak[P]rlcsa/docarray.cpp
// Function: CSA::DocArray::DocArray(CSA::STNode*, CSA::RLCSA const&)
DocArray::DocArray(STNode* root, const RLCSA& _rlcsa) :
  rlcsa(_rlcsa),
  leaf_ranges(0), first_children(0), parents(0), next_leaves(0),
  rule_borders(0), rules(0),
  block_borders(0), blocks(0),
  ok(false), has_grammar(false), uses_rle(false)
{
  if(root == 0) { return; }

  uint nodes = 0, leaves = 0;
  root->determineSize(nodes, leaves);
  root->setNext();

  DeltaVector::Encoder range_encoder(RANGE_BLOCK_SIZE);
  SuccinctVector::Encoder child_encoder(PARENT_BLOCK_SIZE,
    nextMultipleOf(PARENT_BLOCK_SIZE, BITS_TO_BYTES(nodes)));

  std::stack<STNode*> nodestack;
  for(STNode* curr = root; curr != 0; curr = curr->child) { nodestack.push(curr); }
  while(nodestack.top() != root)
  {
    STNode* curr = nodestack.top(); nodestack.pop();
    for(STNode* temp = curr->sibling; temp != 0; temp = temp->child) { nodestack.push(temp); }
    if(curr->child == 0) { range_encoder.addBit(curr->range.first); }
    if(curr == curr->parent->child) { child_encoder.setBit(curr->id); }
  }
  this->leaf_ranges = new DeltaVector(range_encoder, root->range.second + 1);
  this->first_children = new SuccinctVector(child_encoder);

  // Pointers to the parents for first children and to the next leaf for internal nodes.
  WriteBuffer par_buffer(nodes - leaves, length(nodes - leaves - 1));
  WriteBuffer next_buffer(nodes - leaves, length(leaves));
  SuccinctVector::Iterator iter(*(this->first_children));
  while(!(nodestack.empty())) { nodestack.pop(); }
  for(STNode* curr = root; curr != 0; curr = curr->child) { nodestack.push(curr); }
  while(nodestack.top() != root)
  {
    STNode* curr = nodestack.top(); nodestack.pop();
    for(STNode* temp = curr->sibling; temp != 0; temp = temp->child) { nodestack.push(temp); }
    if(curr == curr->parent->child)
    {
      par_buffer.goToItem(iter.rank(curr->id) - 1);
      par_buffer.writeItem(curr->parent->id - leaves);
    }
    if(curr->id >= leaves)
    {
      next_buffer.writeItem(curr->next == 0 ? this->getNumberOfLeaves() : curr->next->id);
    }
  }
  this->parents = par_buffer.getReadBuffer();
  this->next_leaves = next_buffer.getReadBuffer();

  this->ok = true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x270, %rsp            # imm = 0x270
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x1f8(%rbp)
movq -0x18(%rbp), %rcx
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movq $0x0, 0x10(%rax)
movq $0x0, 0x18(%rax)
movq $0x0, 0x20(%rax)
movq $0x0, 0x28(%rax)
movq $0x0, 0x30(%rax)
movq $0x0, 0x38(%rax)
movq $0x0, 0x40(%rax)
movb $0x0, 0x48(%rax)
movb $0x0, 0x49(%rax)
movb $0x0, 0x4a(%rax)
cmpq $0x0, -0x10(%rbp)
jne 0x1fe61
jmp 0x204ab
movl $0x0, -0x1c(%rbp)
movl $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x1c(%rbp), %rsi
leaq -0x20(%rbp), %rdx
callq 0x1f7a0
movq -0x10(%rbp), %rdi
callq 0x1fb70
leaq -0x90(%rbp), %rdi
movl $0x20, %esi
movl %esi, -0x200(%rbp)
movl $0x100000, %edx         # imm = 0x100000
callq 0x2b0f0
movl -0x200(%rbp), %edi
movl -0x1c(%rbp), %esi
addl $0x7, %esi
shrl $0x3, %esi
callq 0x10d50
movl %eax, -0x1fc(%rbp)
jmp 0x1fec1
movl -0x1fc(%rbp), %edx
leaq -0x100(%rbp), %rdi
movl $0x20, %esi
callq 0x2cf20
jmp 0x1feda
leaq -0x160(%rbp), %rdi
callq 0x7620
jmp 0x1fee8
movq -0x10(%rbp), %rax
movq %rax, -0x168(%rbp)
cmpq $0x0, -0x168(%rbp)
je 0x1ff6d
leaq -0x160(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x7740
jmp 0x1ff12
jmp 0x1ff14
movq -0x168(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x168(%rbp)
jmp 0x1fef3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
jmp 0x204e4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
jmp 0x204d8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
jmp 0x204cc
jmp 0x1ff6f
leaq -0x160(%rbp), %rdi
callq 0x76b0
movq %rax, -0x208(%rbp)
jmp 0x1ff84
movq -0x208(%rbp), %rax
movq (%rax), %rax
cmpq -0x10(%rbp), %rax
je 0x20072
leaq -0x160(%rbp), %rdi
callq 0x76b0
movq %rax, -0x210(%rbp)
jmp 0x1ffad
movq -0x210(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x170(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x76d0
jmp 0x1ffcc
movq -0x170(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x178(%rbp)
cmpq $0x0, -0x178(%rbp)
je 0x20013
leaq -0x160(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x7740
jmp 0x1fffd
jmp 0x1ffff
movq -0x178(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x178(%rbp)
jmp 0x1ffde
movq -0x170(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x2003b
movq -0x170(%rbp), %rax
movl 0x4(%rax), %esi
leaq -0x90(%rbp), %rdi
callq 0x2b210
jmp 0x20039
jmp 0x2003b
movq -0x170(%rbp), %rax
movq -0x170(%rbp), %rcx
movq 0x10(%rcx), %rcx
cmpq 0x18(%rcx), %rax
jne 0x2006d
movq -0x170(%rbp), %rax
movl 0x34(%rax), %esi
leaq -0x100(%rbp), %rdi
callq 0x2cf70
jmp 0x2006b
jmp 0x2006d
jmp 0x1ff6f
movl $0x48, %edi
callq 0x32e0
movq %rax, -0x218(%rbp)
jmp 0x20085
movq -0x218(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x8(%rax), %edx
incl %edx
leaq -0x90(%rbp), %rsi
callq 0x2aa20
jmp 0x200a3
movq -0x1f8(%rbp), %rax
movq -0x218(%rbp), %rcx
movq %rcx, 0x8(%rax)
movl $0x48, %edi
callq 0x32e0
movq %rax, -0x220(%rbp)
jmp 0x200c8
movq -0x220(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x2c5f0
jmp 0x200dd
movq -0x1f8(%rbp), %rax
movq -0x220(%rbp), %rcx
movq %rcx, 0x10(%rax)
movl -0x1c(%rbp), %edi
movl -0x20(%rbp), %eax
subl %eax, %edi
movl %edi, -0x228(%rbp)
decl %edi
callq 0x178e0
movl %eax, -0x224(%rbp)
jmp 0x2010c
movl -0x224(%rbp), %edx
movl -0x228(%rbp), %esi
leaq -0x1a0(%rbp), %rdi
callq 0x28e30
jmp 0x20126
movl -0x1c(%rbp), %eax
movl -0x20(%rbp), %edi
subl %edi, %eax
movl %eax, -0x230(%rbp)
callq 0x178e0
movl %eax, -0x22c(%rbp)
jmp 0x20141
movl -0x22c(%rbp), %edx
movl -0x230(%rbp), %esi
leaq -0x1c8(%rbp), %rdi
callq 0x28e30
jmp 0x2015b
movq -0x1f8(%rbp), %rax
movq 0x10(%rax), %rsi
leaq -0x1d8(%rbp), %rdi
callq 0x2c7d0
jmp 0x20174
jmp 0x20176
leaq -0x160(%rbp), %rdi
callq 0x77f0
movb %al, -0x231(%rbp)
jmp 0x2018a
movb -0x231(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x2019b
jmp 0x2024c
leaq -0x160(%rbp), %rdi
callq 0x76d0
jmp 0x201a9
jmp 0x20176
movq -0x218(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
movl $0x48, %esi
callq 0x32f0
jmp 0x204cc
movq -0x220(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
movl $0x48, %esi
callq 0x32f0
jmp 0x204cc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
jmp 0x204c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
jmp 0x204b4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x108(%rbp)
movl %eax, -0x10c(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0x2c7f0
jmp 0x204b4
movq -0x10(%rbp), %rax
movq %rax, -0x1e0(%rbp)
cmpq $0x0, -0x1e0(%rbp)
je 0x2028c
leaq -0x160(%rbp), %rdi
leaq -0x1e0(%rbp), %rsi
callq 0x7740
jmp 0x20276
jmp 0x20278
movq -0x1e0(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x1e0(%rbp)
jmp 0x20257
jmp 0x2028e
leaq -0x160(%rbp), %rdi
callq 0x76b0
movq %rax, -0x240(%rbp)
jmp 0x202a3
movq -0x240(%rbp), %rax
movq (%rax), %rax
cmpq -0x10(%rbp), %rax
je 0x20411
leaq -0x160(%rbp), %rdi
callq 0x76b0
movq %rax, -0x248(%rbp)
jmp 0x202cc
movq -0x248(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1e8(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x76d0
jmp 0x202eb
movq -0x1e8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x1f0(%rbp)
cmpq $0x0, -0x1f0(%rbp)
je 0x20332
leaq -0x160(%rbp), %rdi
leaq -0x1f0(%rbp), %rsi
callq 0x7740
jmp 0x2031c
jmp 0x2031e
movq -0x1f0(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x1f0(%rbp)
jmp 0x202fd
movq -0x1e8(%rbp), %rax
movq -0x1e8(%rbp), %rcx
movq 0x10(%rcx), %rcx
cmpq 0x18(%rcx), %rax
jne 0x203a3
movq -0x1e8(%rbp), %rax
movl 0x34(%rax), %esi
leaq -0x1d8(%rbp), %rdi
xorl %edx, %edx
callq 0x2c800
movl %eax, -0x24c(%rbp)
jmp 0x2036a
movl -0x24c(%rbp), %esi
decl %esi
leaq -0x1a0(%rbp), %rdi
callq 0x17bf0
jmp 0x20380
movq -0x1e8(%rbp), %rax
movq 0x10(%rax), %rax
movl 0x34(%rax), %esi
movl -0x20(%rbp), %eax
subl %eax, %esi
leaq -0x1a0(%rbp), %rdi
callq 0x179c0
jmp 0x203a1
jmp 0x203a3
movq -0x1e8(%rbp), %rax
movl 0x34(%rax), %eax
cmpl -0x20(%rbp), %eax
jb 0x2040c
movq -0x1e8(%rbp), %rax
cmpq $0x0, 0x28(%rax)
jne 0x203e2
movq -0x1f8(%rbp), %rdi
callq 0x79f0
movl %eax, -0x250(%rbp)
jmp 0x203d4
movl -0x250(%rbp), %eax
movl %eax, -0x254(%rbp)
jmp 0x203f6
movq -0x1e8(%rbp), %rax
movq 0x28(%rax), %rax
movl 0x34(%rax), %eax
movl %eax, -0x254(%rbp)
movl -0x254(%rbp), %esi
leaq -0x1c8(%rbp), %rdi
callq 0x179c0
jmp 0x2040a
jmp 0x2040c
jmp 0x2028e
leaq -0x1a0(%rbp), %rdi
callq 0x28fb0
movq %rax, -0x260(%rbp)
jmp 0x20426
movq -0x1f8(%rbp), %rax
movq -0x260(%rbp), %rcx
movq %rcx, 0x18(%rax)
leaq -0x1c8(%rbp), %rdi
callq 0x28fb0
movq %rax, -0x268(%rbp)
jmp 0x2044d
movq -0x1f8(%rbp), %rax
movq -0x268(%rbp), %rcx
movq %rcx, 0x20(%rax)
movb $0x1, 0x48(%rax)
leaq -0x1d8(%rbp), %rdi
callq 0x2c7f0
leaq -0x1c8(%rbp), %rdi
callq 0x28f70
leaq -0x1a0(%rbp), %rdi
callq 0x28f70
leaq -0x160(%rbp), %rdi
callq 0x79b0
leaq -0x100(%rbp), %rdi
callq 0x2cf50
leaq -0x90(%rbp), %rdi
callq 0x2b120
addq $0x270, %rsp            # imm = 0x270
popq %rbp
retq
leaq -0x1c8(%rbp), %rdi
callq 0x28f70
leaq -0x1a0(%rbp), %rdi
callq 0x28f70
leaq -0x160(%rbp), %rdi
callq 0x79b0
leaq -0x100(%rbp), %rdi
callq 0x2cf50
leaq -0x90(%rbp), %rdi
callq 0x2b120
movq -0x108(%rbp), %rdi
callq 0x3570
nopl (%rax)