// File: adamnovak[P]rlcsa/bits/array.cpp
// Function: CSA::Array::Array(CSA::ArrayEncoder&)
Array::Array(Encoder& encoder) :
  items(encoder.items),
  delete_array(true),
  block_size(encoder.block_size),
  number_of_blocks(encoder.blocks),
  item_index(0)
{
  usint* array_buffer = new usint[this->block_size * this->number_of_blocks];
  this->array = array_buffer;
  this->buffer = new ReadBuffer(this->array, this->block_size);

  this->integer_bits = length(this->items);
  WriteBuffer sample_buffer(this->number_of_blocks + 1, this->integer_bits);

  // Copy & linearize the array.
  usint pos = 0;
  for(std::list<usint*>::iterator iter = encoder.array_blocks.begin(); iter != encoder.array_blocks.end(); iter++)
  {
    memcpy(array_buffer + pos, *iter, encoder.superblock_bytes);
    pos += encoder.block_size * encoder.blocks_in_superblock;
  }
  memcpy(array_buffer + pos, encoder.array, encoder.current_blocks * encoder.block_size * sizeof(usint));

  // Compress the samples.
  for(std::list<usint*>::iterator iter = encoder.sample_blocks.begin(); iter != encoder.sample_blocks.end(); iter++)
  {
    usint* buf = *iter;
    for(usint i = 0; i < encoder.samples_in_superblock; i++)
    {
      sample_buffer.writeItem(buf[i]);
    }
  }
  for(usint i = 0; i < encoder.current_samples; i++)
  {
    sample_buffer.writeItem(encoder.samples[i]);
  }
  sample_buffer.writeItem(this->items);

  this->samples = sample_buffer.getReadBuffer();

  this->buildIndex();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0xb0(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, (%rcx)
movb $0x1, 0x18(%rcx)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, 0x1c(%rcx)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, 0x20(%rcx)
movq $0x0, 0x38(%rcx)
movl 0x1c(%rcx), %eax
movl 0x20(%rcx), %ecx
imull %ecx, %eax
movl %eax, %edi
shlq $0x2, %rdi
callq 0x3030
movq %rax, %rcx
movq -0xb0(%rbp), %rax
movq %rcx, -0x18(%rbp)
movq -0x18(%rbp), %rcx
movq %rcx, 0x10(%rax)
movl $0x28, %edi
callq 0x32c0
movq %rax, %rdi
movq -0xb0(%rbp), %rax
movq %rdi, %rcx
movq %rcx, -0xa8(%rbp)
movq 0x10(%rax), %rsi
movl 0x1c(%rax), %edx
callq 0x1e130
jmp 0x1c97c
movq -0xb0(%rbp), %rax
movq -0xa8(%rbp), %rcx
movq %rcx, 0x8(%rax)
movl (%rax), %edi
callq 0x14da0
movl %eax, %ecx
movq -0xb0(%rbp), %rax
movl %ecx, 0x30(%rax)
movl 0x20(%rax), %esi
addl $0x1, %esi
movl 0x30(%rax), %edx
leaq -0x50(%rbp), %rdi
callq 0x1e430
movl $0x0, -0x54(%rbp)
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0x1d4e0
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0x1d540
movq %rax, -0x68(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x1d510
testb $0x1, %al
jne 0x1c9ef
jmp 0x1ca6d
movq -0x18(%rbp), %rax
movl -0x54(%rbp), %ecx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, -0xb8(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x1d570
movq -0xb8(%rbp), %rdi
movq (%rax), %rsi
movq -0x10(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, %edx
callq 0x3240
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x10(%rbp), %rcx
imull 0x38(%rcx), %eax
addl -0x54(%rbp), %eax
movl %eax, -0x54(%rbp)
leaq -0x60(%rbp), %rdi
xorl %esi, %esi
callq 0x1d590
movq %rax, -0x70(%rbp)
jmp 0x1c9cb
movq -0xa8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x28, %esi
callq 0x32d0
jmp 0x1cbfd
movq -0x18(%rbp), %rdi
movl -0x54(%rbp), %eax
shlq $0x2, %rax
addq %rax, %rdi
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x3c(%rax), %eax
movq -0x10(%rbp), %rcx
imull 0x8(%rcx), %eax
movl %eax, %eax
movl %eax, %edx
shlq $0x2, %rdx
callq 0x3240
movq -0x10(%rbp), %rdi
addq $0x40, %rdi
callq 0x1d4e0
movq %rax, -0x78(%rbp)
movq -0x10(%rbp), %rdi
addq $0x40, %rdi
callq 0x1d540
movq %rax, -0x80(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x1d510
testb $0x1, %al
jne 0x1cad7
jmp 0x1cb64
leaq -0x78(%rbp), %rdi
callq 0x1d570
movq (%rax), %rax
movq %rax, -0x88(%rbp)
movl $0x0, -0x8c(%rbp)
movl -0x8c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x60(%rcx), %eax
jae 0x1cb4b
movq -0x88(%rbp), %rax
movl -0x8c(%rbp), %ecx
movl (%rax,%rcx,4), %esi
leaq -0x50(%rbp), %rdi
callq 0x14e80
jmp 0x1cb1e
jmp 0x1cb20
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x1caf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x1e570
jmp 0x1cbfd
jmp 0x1cb4d
leaq -0x78(%rbp), %rdi
xorl %esi, %esi
callq 0x1d590
movq %rax, -0x98(%rbp)
jmp 0x1cab0
movl $0x0, -0x9c(%rbp)
movl -0x9c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x64(%rcx), %eax
jae 0x1cbac
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movl -0x9c(%rbp), %ecx
movl (%rax,%rcx,4), %esi
leaq -0x50(%rbp), %rdi
callq 0x14e80
jmp 0x1cb99
jmp 0x1cb9b
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x1cb6e
movq -0xb0(%rbp), %rax
movl (%rax), %esi
leaq -0x50(%rbp), %rdi
callq 0x14e80
jmp 0x1cbc0
leaq -0x50(%rbp), %rdi
callq 0x1e5b0
movq %rax, -0xc0(%rbp)
jmp 0x1cbd2
movq -0xb0(%rbp), %rdi
movq -0xc0(%rbp), %rax
movq %rax, 0x28(%rdi)
callq 0x1c590
jmp 0x1cbeb
leaq -0x50(%rbp), %rdi
callq 0x1e570
addq $0xc0, %rsp
popq %rbp
retq
movq -0x20(%rbp), %rdi
callq 0x3530
nopw %cs:(%rax,%rax)