// File: cdalitz[P]kdtree-cpp/kdtree.cpp
// Function: Kdtree::KdTree::k_nearest_neighbors(std::vector<double, std::allocator<double>> const&, unsigned long, std::vector<Kdtree::KdNode, std::allocator<Kdtree::KdNode>>*, Kdtree::KdNodePredicate*)
void KdTree::k_nearest_neighbors(const CoordPoint& point, size_t k,
                                 KdNodeVector* result,
                                 KdNodePredicate* pred /*=NULL*/) {
  size_t i;
  KdNode temp;
  searchpredicate = pred;

  result->clear();
  if (k < 1) return;
  if (point.size() != dimension)
    throw std::invalid_argument(
        "kdtree::k_nearest_neighbors(): point must be of same dimension as "
        "kdtree");

  // collect result of k values in neighborheap
  //std::priority_queue<nn4heap, std::vector<nn4heap>, compare_nn4heap>*
  //neighborheap = new std::priority_queue<nn4heap, std::vector<nn4heap>, compare_nn4heap>();
  SearchQueue* neighborheap = new SearchQueue();
  if (k > allnodes.size()) {
    // when more neighbors asked than nodes in tree, return everything
    k = allnodes.size();
    for (i = 0; i < k; i++) {
      if (!(searchpredicate && !(*searchpredicate)(allnodes[i])))
        neighborheap->push(
            nn4heap(i, distance->distance(allnodes[i].point, point)));
    }
  } else {
    neighbor_search(point, root, k, neighborheap);
  }

  // copy over result sorted by distance
  // (we must revert the vector for ascending order)
  while (!neighborheap->empty()) {
    i = neighborheap->top().dataindex;
    neighborheap->pop();
    result->push_back(allnodes[i]);
  }
  // beware that less than k results might have been returned
  k = result->size();
  for (i = 0; i < k / 2; i++) {
    temp = (*result)[i];
    (*result)[i] = (*result)[k - 1 - i];
    (*result)[k - 1 - i] = temp;
  }
  delete neighborheap;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x90(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x8820
movq -0x90(%rbp), %rax
movq -0x28(%rbp), %rcx
movq %rcx, 0x40(%rax)
movq -0x20(%rbp), %rdi
callq 0x3b10
cmpq $0x1, -0x18(%rbp)
jae 0x725e
movl $0x1, -0x5c(%rbp)
jmp 0x7609
movq -0x10(%rbp), %rdi
callq 0x37d0
movq -0x90(%rbp), %rcx
cmpq 0x60(%rcx), %rax
je 0x72e6
movl $0x10, %edi
callq 0x2080
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x98(%rbp)
leaq 0x70b1(%rip), %rsi      # 0xe343
callq 0x21a0
jmp 0x7299
movq -0x98(%rbp), %rdi
movq 0xdd39(%rip), %rsi      # 0x14fe0
movq 0xdd22(%rip), %rdx      # 0x14fd0
callq 0x2180
jmp 0x762d
movq -0x98(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
callq 0x20c0
jmp 0x761b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x761b
movl $0x20, %edi
callq 0x2110
movq %rax, -0xa0(%rbp)
jmp 0x72f9
movq -0xa0(%rbp), %rdi
callq 0x8850
jmp 0x7307
movq -0x90(%rbp), %rdi
movq -0xa0(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xa8(%rbp)
addq $0x48, %rdi
callq 0x3780
movq %rax, %rcx
movq -0xa8(%rbp), %rax
cmpq %rcx, %rax
jbe 0x747e
movq -0x90(%rbp), %rdi
addq $0x48, %rdi
callq 0x3780
movq %rax, -0x18(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x747c
movq -0x90(%rbp), %rax
cmpq $0x0, 0x40(%rax)
je 0x73c1
movq -0x90(%rbp), %rdi
movq 0x40(%rdi), %rax
movq %rax, -0xb8(%rbp)
addq $0x48, %rdi
movq -0x30(%rbp), %rsi
callq 0x3b30
movq -0xb8(%rbp), %rdi
movq %rax, %rsi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movb %al, -0xa9(%rbp)
jmp 0x73b2
movb -0xa9(%rbp), %al
testb $0x1, %al
jne 0x73c1
jmp 0x7469
movq -0x90(%rbp), %rdi
movq -0x78(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x30(%rbp), %rsi
movq %rsi, -0xd0(%rbp)
movq 0x38(%rdi), %rax
movq %rax, -0xc8(%rbp)
addq $0x48, %rdi
callq 0x3b30
movq -0xc8(%rbp), %rdi
movq %rax, %rsi
movq -0x10(%rbp), %rdx
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movsd %xmm0, -0xc0(%rbp)
jmp 0x7413
movsd -0xc0(%rbp), %xmm0
movq -0xd0(%rbp), %rsi
leaq -0x88(%rbp), %rdi
callq 0x88d0
jmp 0x7430
movq -0xd8(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x8880
jmp 0x7445
jmp 0x7469
movq -0xa0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
movl $0x20, %esi
callq 0x2120
jmp 0x761b
jmp 0x746b
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x735c
jmp 0x749e
movq -0x90(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq 0x68(%rdi), %rdx
movq -0x18(%rbp), %rcx
movq -0x78(%rbp), %r8
callq 0x7630
jmp 0x749c
jmp 0x749e
jmp 0x74a0
movq -0x78(%rbp), %rdi
callq 0x8900
movb %al, -0xd9(%rbp)
jmp 0x74b1
movb -0xd9(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x74bf
jmp 0x751c
movq -0x78(%rbp), %rdi
callq 0x8920
movq %rax, -0xe8(%rbp)
jmp 0x74d1
movq -0xe8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x78(%rbp), %rdi
callq 0x8940
jmp 0x74ea
movq -0x90(%rbp), %rdi
movq -0x20(%rbp), %rax
movq %rax, -0xf0(%rbp)
addq $0x48, %rdi
movq -0x30(%rbp), %rsi
callq 0x3b30
movq -0xf0(%rbp), %rdi
movq %rax, %rsi
callq 0x8990
jmp 0x751a
jmp 0x74a0
movq -0x20(%rbp), %rdi
callq 0x3780
movq %rax, -0x18(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x18(%rbp), %rcx
shrq %rcx
cmpq %rcx, %rax
jae 0x75d4
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x3b30
movq %rax, %rsi
leaq -0x58(%rbp), %rdi
callq 0x8a00
jmp 0x7560
movq -0x20(%rbp), %rdi
movq -0x18(%rbp), %rax
movq -0x30(%rbp), %rsi
notq %rsi
addq %rax, %rsi
callq 0x3b30
movq %rax, -0xf8(%rbp)
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x3b30
movq -0xf8(%rbp), %rsi
movq %rax, %rdi
callq 0x8a00
jmp 0x759c
movq -0x20(%rbp), %rdi
movq -0x18(%rbp), %rax
movq -0x30(%rbp), %rsi
notq %rsi
addq %rax, %rsi
callq 0x3b30
movq %rax, %rdi
leaq -0x58(%rbp), %rsi
callq 0x8a00
jmp 0x75c1
jmp 0x75c3
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x7531
movq -0x78(%rbp), %rax
movq %rax, -0x100(%rbp)
cmpq $0x0, %rax
je 0x7602
movq -0x100(%rbp), %rdi
callq 0x8a40
movq -0x100(%rbp), %rdi
movl $0x20, %esi
callq 0x2120
movl $0x0, -0x5c(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x39a0
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
leaq -0x58(%rbp), %rdi
callq 0x39a0
movq -0x68(%rbp), %rdi
callq 0x2190
nopl (%rax)