// File: /workspace/github_cpp_makefile_star2_O2/cloudinary[P]fuif/encoding/../maniac/compound_enc.h
// Function: PropertySymbolCoder<SimpleBitChance, RacDummy<DummyIO>, 15>::find_leaf(std::vector<int, std::allocator<int>> const&)
CompoundSymbolChances<BitChance,bits> inline &find_leaf(const Properties &properties) {
        uint32_t pos = 0;
        Ranges current_ranges = range;
        while(inner_node[pos].property != -1) {
            if (properties[inner_node[pos].property] > inner_node[pos].splitval) {
                current_ranges[inner_node[pos].property].first = inner_node[pos].splitval + 1;
                pos = inner_node[pos].childID;
            } else {
                current_ranges[inner_node[pos].property].second = inner_node[pos].splitval;
                pos = inner_node[pos].childID+1;
            }
        }
//        CompoundSymbolChances<BitChance,bits> &result = leaf_node[inner_node[pos].leafID];
        CompoundSymbolChances<BitChance,bits> &result = leaf_node[inner_node[pos].childID];
        set_selection_and_update_property_sums(properties,result,current_ranges);

        // split leaf node if some virtual context is performing (significantly) better
        if(result.best_property != -1
           && result.realSize > result.virtSize[result.best_property] + split_threshold
           && leaf_node.size() < 0xFFFF && inner_node.size() < 0xFFFF
           && current_ranges[result.best_property].first < current_ranges[result.best_property].second) {

          int16_t p = result.best_property;
          PropertyVal splitval = compute_splitval(result,p,current_ranges);
//            printf("splitting on property %i, splitval %i (pos=%i)\n",p,splitval,pos);
/*
          PropertyVal splitval = div_down(result.virtPropSum[p],result.count);
          if (splitval >= current_ranges[result.best_property].second)
             splitval = current_ranges[result.best_property].second-1; // == does happen because of rounding and running average
*/

          uint32_t new_inner = inner_node.size();
          inner_node.push_back(inner_node[pos]);
          inner_node.push_back(inner_node[pos]);
          inner_node[pos].splitval = splitval;
//            fprintf(stdout,"Splitting on property %i, splitval=%i (count=%i)\n",p,inner_node[pos].splitval, (int)result.count);
          inner_node[pos].property = p;
//          if (result.count < INT16_MAX) inner_node[pos].count = result.count;
//          else inner_node[pos].count = INT16_MAX;
          uint32_t new_leaf = leaf_node.size();
          result.resetCounters();
          leaf_node.push_back(CompoundSymbolChances<BitChance,bits>(result));
//          uint32_t old_leaf = inner_node[pos].leafID;
          uint32_t old_leaf = inner_node[pos].childID;
          inner_node[pos].childID = new_inner;
//          inner_node[new_inner].leafID = old_leaf;
//          inner_node[new_inner+1].leafID = new_leaf;
          inner_node[new_inner].childID = old_leaf;
          inner_node[new_inner+1].childID = new_leaf;
//          leaf_node[old_leaf].range[p].first = splitval+1;
//          leaf_node[new_leaf].range[p].second = splitval;
          if (properties[p] > inner_node[pos].splitval) {
                return leaf_node[old_leaf];
          } else {
                return leaf_node[new_leaf];
          }
        }
        return result;
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x4018(%rdi), %rsi
leaq 0x18(%rsp), %r15
movq %r15, %rdi
callq 0x12cce
movq 0x4050(%rbx), %rax
movq (%rax), %rax
movq (%r14), %rcx
xorl %r13d, %r13d
movq (%r15), %rdx
movswq (%rax,%r13,8), %rsi
cmpq $-0x1, %rsi
je 0x13c09
movl 0x4(%rax,%r13,8), %edi
cmpl %edi, (%rcx,%rsi,4)
jle 0x13bfa
incl %edi
movl %edi, (%rdx,%rsi,8)
movzwl 0x2(%rax,%r13,8), %r13d
jmp 0x13bd8
movl %edi, 0x4(%rdx,%rsi,8)
movzwl 0x2(%rax,%r13,8), %r13d
incq %r13
jmp 0x13bd8
movzwl 0x2(%rax,%r13,8), %eax
imulq $0x98, %rax, %r15
addq 0x4038(%rbx), %r15
leaq 0x18(%rsp), %rcx
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x13e36
movswq 0x94(%r15), %r12
cmpq $-0x1, %r12
je 0x13db1
movq 0x60(%r15), %rax
movslq 0x4080(%rbx), %rcx
addq (%rax,%r12,8), %rcx
cmpq %rcx, 0x58(%r15)
jbe 0x13db1
movq 0x4040(%rbx), %rax
subq 0x4038(%rbx), %rax
movl $0x98, %ecx
cqto
idivq %rcx
cmpq $0xfffe, %rax           # imm = 0xFFFE
ja 0x13db1
movq 0x4050(%rbx), %rax
movq 0x8(%rax), %rcx
subq (%rax), %rcx
cmpq $0x7fff7, %rcx          # imm = 0x7FFF7
ja 0x13db1
movq 0x18(%rsp), %rax
movl (%rax,%r12,8), %ecx
cmpl 0x4(%rax,%r12,8), %ecx
jge 0x13db1
movswl %r12w, %edx
leaq 0x18(%rsp), %rcx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x13ed2
movl %eax, 0x8(%rsp)
movq 0x4050(%rbx), %rdi
movq (%rdi), %rax
movq 0x8(%rdi), %rbp
movq %rax, 0x10(%rsp)
leaq (%rax,%r13,8), %rsi
callq 0x13f24
movq 0x4050(%rbx), %rdi
leaq (,%r13,8), %rsi
addq (%rdi), %rsi
callq 0x13f24
movq 0x4050(%rbx), %rax
movq (%rax), %rax
movl 0x8(%rsp), %ecx
movl %ecx, 0x4(%rax,%r13,8)
movw %r12w, (%rax,%r13,8)
movq 0x4040(%rbx), %rax
subq 0x4038(%rbx), %rax
movl $0x98, %ecx
cqto
idivq %rcx
movq %rax, 0x8(%rsp)
movq %r15, %rdi
callq 0x13f42
leaq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0x138b6
leaq 0x4038(%rbx), %rdi
leaq 0x30(%rsp), %rsi
callq 0x142e8
subq 0x10(%rsp), %rbp
sarq $0x3, %rbp
leaq 0x30(%rsp), %rdi
callq 0x12e8c
movq 0x4050(%rbx), %rax
movq (%rax), %rcx
movzwl 0x2(%rcx,%r13,8), %eax
movw %bp, 0x2(%rcx,%r13,8)
movl %ebp, %edx
movw %ax, 0x2(%rcx,%rdx,8)
incl %ebp
movq 0x8(%rsp), %rsi
movw %si, 0x2(%rcx,%rbp,8)
movq (%r14), %rdx
movl (%rdx,%r12,4), %edx
movq 0x4038(%rbx), %r15
cmpl 0x4(%rcx,%r13,8), %edx
jg 0x13da7
movl %esi, %eax
imulq $0x98, %rax, %rax
addq %rax, %r15
leaq 0x18(%rsp), %rdi
callq 0xc00e
movq %r15, %rax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x12e8c
jmp 0x13dea
jmp 0x13de7
jmp 0x13de7
jmp 0x13de7
jmp 0x13de7
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0xc00e
movq %rbx, %rdi
callq 0x35d0