// File: 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:
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x158(%rsp)
movq %rsi, 0x150(%rsp)
movq 0x158(%rsp), %rsi
movq %rsi, 0x60(%rsp)
movl $0x0, 0x14c(%rsp)
addq $0x4018, %rsi           # imm = 0x4018
leaq 0x130(%rsp), %rdi
callq 0x2c4a0
movq 0x60(%rsp), %rax
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movswl (%rax), %eax
cmpl $-0x1, %eax
je 0x3044c
movq 0x60(%rsp), %rax
movq 0x150(%rsp), %rcx
movq %rcx, 0x50(%rsp)
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movq 0x50(%rsp), %rdi
movswq (%rax), %rsi
callq 0x13560
movq %rax, %rcx
movq 0x60(%rsp), %rax
movl (%rcx), %ecx
movl %ecx, 0x5c(%rsp)
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movq %rax, %rcx
movl 0x5c(%rsp), %eax
cmpl 0x4(%rcx), %eax
jle 0x303c6
movq 0x60(%rsp), %rax
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movq %rax, %rcx
movq 0x60(%rsp), %rax
movl 0x4(%rcx), %ecx
addl $0x1, %ecx
movl %ecx, 0x4c(%rsp)
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movswq (%rax), %rsi
leaq 0x130(%rsp), %rdi
callq 0x13420
movl 0x4c(%rsp), %edx
movq %rax, %rcx
movq 0x60(%rsp), %rax
movl %edx, (%rcx)
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movzwl 0x2(%rax), %eax
movl %eax, 0x14c(%rsp)
jmp 0x30447
movq 0x60(%rsp), %rax
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movq %rax, %rcx
movq 0x60(%rsp), %rax
movl 0x4(%rcx), %ecx
movl %ecx, 0x48(%rsp)
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movswq (%rax), %rsi
leaq 0x130(%rsp), %rdi
callq 0x13420
movl 0x48(%rsp), %edx
movq %rax, %rcx
movq 0x60(%rsp), %rax
movl %edx, 0x4(%rcx)
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movzwl 0x2(%rax), %eax
addl $0x1, %eax
movl %eax, 0x14c(%rsp)
jmp 0x302b3
movq 0x60(%rsp), %rax
movq %rax, %rcx
addq $0x4038, %rcx           # imm = 0x4038
movq %rcx, 0x40(%rsp)
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movq 0x40(%rsp), %rdi
movzwl 0x2(%rax), %eax
movl %eax, %esi
callq 0x309b0
movq 0x60(%rsp), %rdi
movq %rax, 0x128(%rsp)
movq 0x150(%rsp), %rsi
movq 0x128(%rsp), %rdx
leaq 0x130(%rsp), %rcx
callq 0x309d0
jmp 0x304b1
movq 0x128(%rsp), %rax
movswl 0x94(%rax), %eax
cmpl $-0x1, %eax
je 0x308ba
movq 0x128(%rsp), %rax
movq 0x58(%rax), %rax
movq %rax, 0x38(%rsp)
movq 0x128(%rsp), %rdi
addq $0x60, %rdi
movq 0x128(%rsp), %rax
movswq 0x94(%rax), %rsi
callq 0x30af0
movq 0x60(%rsp), %rdx
movq %rax, %rcx
movq 0x38(%rsp), %rax
movq (%rcx), %rcx
movslq 0x4080(%rdx), %rdx
addq %rdx, %rcx
cmpq %rcx, %rax
jbe 0x308ba
movq 0x60(%rsp), %rdi
addq $0x4038, %rdi           # imm = 0x4038
callq 0x30b10
cmpq $0xffff, %rax           # imm = 0xFFFF
jae 0x308ba
movq 0x60(%rsp), %rax
movq 0x4050(%rax), %rdi
callq 0x30b30
cmpq $0xffff, %rax           # imm = 0xFFFF
jae 0x308ba
movq 0x128(%rsp), %rax
movswq 0x94(%rax), %rsi
leaq 0x130(%rsp), %rdi
callq 0x13420
movl (%rax), %eax
movl %eax, 0x34(%rsp)
movq 0x128(%rsp), %rax
movswq 0x94(%rax), %rsi
leaq 0x130(%rsp), %rdi
callq 0x13420
movq %rax, %rcx
movl 0x34(%rsp), %eax
cmpl 0x4(%rcx), %eax
jge 0x308ba
movq 0x60(%rsp), %rdi
movq 0x128(%rsp), %rax
movw 0x94(%rax), %ax
movw %ax, 0x11a(%rsp)
movq 0x128(%rsp), %rsi
movswl 0x11a(%rsp), %edx
leaq 0x130(%rsp), %rcx
callq 0x30b50
movl %eax, 0x30(%rsp)
jmp 0x305e7
movq 0x60(%rsp), %rax
movl 0x30(%rsp), %ecx
movl %ecx, 0x114(%rsp)
movq 0x4050(%rax), %rdi
callq 0x30b30
movq %rax, %rcx
movq 0x60(%rsp), %rax
movl %ecx, 0x110(%rsp)
movq 0x4050(%rax), %rdi
movq %rdi, 0x28(%rsp)
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movq 0x28(%rsp), %rdi
movq %rax, %rsi
callq 0x30c30
jmp 0x3063b
movq 0x60(%rsp), %rax
movq 0x4050(%rax), %rdi
movq %rdi, 0x20(%rsp)
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movq 0x20(%rsp), %rdi
movq %rax, %rsi
callq 0x30c30
jmp 0x30669
movq 0x60(%rsp), %rax
movl 0x114(%rsp), %ecx
movl %ecx, 0x18(%rsp)
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movl 0x18(%rsp), %edx
movq %rax, %rcx
movq 0x60(%rsp), %rax
movl %edx, 0x4(%rcx)
movw 0x11a(%rsp), %cx
movw %cx, 0x1e(%rsp)
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movw 0x1e(%rsp), %cx
movq 0x60(%rsp), %rdi
movw %cx, (%rax)
addq $0x4038, %rdi           # imm = 0x4038
callq 0x30b10
movl %eax, 0x10c(%rsp)
movq 0x128(%rsp), %rdi
callq 0x30ca0
jmp 0x306ee
movq 0x60(%rsp), %rax
addq $0x4038, %rax           # imm = 0x4038
movq %rax, 0x10(%rsp)
movq 0x128(%rsp), %rsi
leaq 0x70(%rsp), %rdi
callq 0x2ec50
jmp 0x30712
movq 0x10(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x30d40
jmp 0x30723
leaq 0x70(%rsp), %rdi
callq 0x2c850
movq 0x60(%rsp), %rax
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movq %rax, %rcx
movq 0x60(%rsp), %rax
movzwl 0x2(%rcx), %ecx
movl %ecx, 0x6c(%rsp)
movl 0x110(%rsp), %ecx
movw %cx, 0x6(%rsp)
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movw 0x6(%rsp), %dx
movq %rax, %rcx
movq 0x60(%rsp), %rax
movw %dx, 0x2(%rcx)
movl 0x6c(%rsp), %ecx
movw %cx, 0x8(%rsp)
movq 0x4050(%rax), %rdi
movl 0x110(%rsp), %eax
movl %eax, %esi
callq 0x30990
movw 0x8(%rsp), %dx
movq %rax, %rcx
movq 0x60(%rsp), %rax
movw %dx, 0x2(%rcx)
movl 0x10c(%rsp), %ecx
movw %cx, 0xa(%rsp)
movq 0x4050(%rax), %rdi
movl 0x110(%rsp), %eax
addl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x30990
movw 0xa(%rsp), %cx
movw %cx, 0x2(%rax)
movq 0x150(%rsp), %rdi
movswq 0x11a(%rsp), %rsi
callq 0x13560
movq %rax, %rcx
movq 0x60(%rsp), %rax
movl (%rcx), %ecx
movl %ecx, 0xc(%rsp)
movq 0x4050(%rax), %rdi
movl 0x14c(%rsp), %eax
movl %eax, %esi
callq 0x30990
movq %rax, %rcx
movl 0xc(%rsp), %eax
cmpl 0x4(%rcx), %eax
jle 0x3088e
movq 0x60(%rsp), %rdi
addq $0x4038, %rdi           # imm = 0x4038
movl 0x6c(%rsp), %eax
movl %eax, %esi
callq 0x309b0
movq %rax, 0x160(%rsp)
movl $0x1, 0x68(%rsp)
jmp 0x308d2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x120(%rsp)
movl %eax, 0x11c(%rsp)
jmp 0x308ef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x120(%rsp)
movl %eax, 0x11c(%rsp)
leaq 0x70(%rsp), %rdi
callq 0x2c850
jmp 0x308ef
movq 0x60(%rsp), %rdi
addq $0x4038, %rdi           # imm = 0x4038
movl 0x10c(%rsp), %eax
movl %eax, %esi
callq 0x309b0
movq %rax, 0x160(%rsp)
movl $0x1, 0x68(%rsp)
jmp 0x308d2
movq 0x128(%rsp), %rax
movq %rax, 0x160(%rsp)
movl $0x1, 0x68(%rsp)
leaq 0x130(%rsp), %rdi
callq 0x134e0
movq 0x160(%rsp), %rax
addq $0x168, %rsp            # imm = 0x168
retq
leaq 0x130(%rsp), %rdi
callq 0x134e0
movq 0x120(%rsp), %rdi
callq 0x36a0
nopl (%rax)