// File: cegme[P]vose/VoseTree.cc
// Function: VoseTree::add(marble)
double VoseTree::add(marble m) {
  
  // Update the new weight
  total_weight += m.weight;
  double contribution = (double) m.weight / total_weight;

  // Add the marble to another branch
  if(!branches.empty()) {
    double new_total = branches.back() + m.weight;
    branches.push_back(new_total);
  }
  else {
    branches.push_back(m.weight);
  }
    
  // Add this marble to the free marble list
  vosetreenode vtn;
  vtn.isBag = false;
  vtn.ball = m;
  nodes.push_back(vtn);

  // Shrink data structure if necessary
  if (branches.size() - last_bag > max_marbles) {
    // Compress the marbles to make a new bag
    Vose v;
    for(size_t i = last_bag; i != nodes.size(); ++i) {
      v.add(nodes[i].ball);
    }
    v.init();
    vosetreenode vtn2 (v);

    nodes[last_bag] = vtn2;
    nodes.resize(last_bag+1);
    
    branches.resize(last_bag+1);
    branches[last_bag] = total_weight;

    ++last_bag;
    if (last_bag > max_bags) {
      // Merge all the bags into one bag
      Vose z;
      z = merge_bags();
      nodes.resize(1);
      nodes[0] = z;

      // Update the branch and bag locations
      last_bag = 1;
      total_weight = z.weight();

      branches.resize(1);
      branches[0] = total_weight;
    } 
  } 
  
  // Update a random number generator to new range
  std::default_random_engine generator(VoseUtil::RANDOM_SEED);
  std::uniform_real_distribution<double>
    real_distribution(0, total_weight);
  random_branch = std::bind(real_distribution, generator);

  return contribution;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x610, %rsp            # imm = 0x610
movq %rsi, -0x5d8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x5d0(%rbp)
movq (%rsi), %rax
addq 0x58(%rdi), %rax
movq %rax, 0x58(%rdi)
cvtsi2sdq (%rsi), %xmm0
cvtsi2sdq 0x58(%rdi), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x18(%rbp)
addq $0x20, %rdi
callq 0x4220
testb $0x1, %al
jne 0x2668
movq -0x5d0(%rbp), %rdi
addq $0x20, %rdi
callq 0x4260
movq -0x5d8(%rbp), %rcx
movq -0x5d0(%rbp), %rdi
movq (%rax), %rax
addq (%rcx), %rax
cvtsi2sd %rax, %xmm0
movsd %xmm0, -0x20(%rbp)
addq $0x20, %rdi
cvttsd2si -0x20(%rbp), %rax
movq %rax, -0x28(%rbp)
leaq -0x28(%rbp), %rsi
callq 0x42a0
jmp 0x267f
movq -0x5d8(%rbp), %rsi
movq -0x5d0(%rbp), %rdi
addq $0x20, %rdi
callq 0x42d0
leaq -0xf0(%rbp), %rdi
callq 0x4340
movq -0x5d8(%rbp), %rsi
movb $0x0, -0xf0(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x43a0
jmp 0x26a7
movq -0x5d0(%rbp), %rdi
addq $0x38, %rdi
leaq -0xf0(%rbp), %rsi
callq 0x43f0
jmp 0x26c0
movq -0x5d0(%rbp), %rdi
addq $0x20, %rdi
callq 0x4460
movq -0x5d0(%rbp), %rcx
subq 0x50(%rcx), %rax
cmpq 0x60(%rcx), %rax
jbe 0x2ad0
leaq -0x190(%rbp), %rdi
callq 0x4480
jmp 0x26f3
movq -0x5d0(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x198(%rbp)
movq -0x5d0(%rbp), %rdi
movq -0x198(%rbp), %rax
movq %rax, -0x5e0(%rbp)
addq $0x38, %rdi
callq 0x4520
movq %rax, %rcx
movq -0x5e0(%rbp), %rax
cmpq %rcx, %rax
je 0x27eb
movq -0x5d0(%rbp), %rdi
addq $0x38, %rdi
movq -0x198(%rbp), %rsi
callq 0x4550
movq %rax, %rsi
addq $0x8, %rsi
leaq -0x1c8(%rbp), %rdi
callq 0x41b0
jmp 0x2762
leaq -0x190(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x10ce0
jmp 0x2777
leaq -0x1c8(%rbp), %rdi
callq 0x4200
movq -0x198(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x198(%rbp)
jmp 0x2705
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf8(%rbp)
movl %eax, -0xfc(%rbp)
jmp 0x2b5e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf8(%rbp)
movl %eax, -0xfc(%rbp)
jmp 0x2abf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf8(%rbp)
movl %eax, -0xfc(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x4200
jmp 0x2abf
leaq -0x190(%rbp), %rdi
callq 0x10d30
jmp 0x27f9
leaq -0x320(%rbp), %rdi
leaq -0x190(%rbp), %rsi
callq 0x4570
jmp 0x280e
leaq -0x290(%rbp), %rdi
leaq -0x320(%rbp), %rsi
callq 0x4680
jmp 0x2823
leaq -0x320(%rbp), %rdi
callq 0x46f0
movq -0x5d0(%rbp), %rax
movq %rax, %rdi
addq $0x38, %rdi
movq 0x50(%rax), %rsi
callq 0x4550
movq %rax, %rdi
leaq -0x290(%rbp), %rsi
callq 0x4750
jmp 0x2857
movq -0x5d0(%rbp), %rax
movq %rax, %rdi
addq $0x38, %rdi
movq 0x50(%rax), %rsi
incq %rsi
callq 0x47b0
jmp 0x2873
movq -0x5d0(%rbp), %rax
movq %rax, %rdi
addq $0x20, %rdi
movq 0x50(%rax), %rsi
incq %rsi
callq 0x4840
jmp 0x288f
movq -0x5d0(%rbp), %rax
movq 0x58(%rax), %rcx
movq %rcx, -0x5e8(%rbp)
movq %rax, %rdi
addq $0x20, %rdi
movq 0x50(%rax), %rsi
callq 0x48d0
movq -0x5e8(%rbp), %rdx
movq -0x5d0(%rbp), %rcx
movq %rdx, (%rax)
movq 0x50(%rcx), %rax
addq $0x1, %rax
movq %rax, 0x50(%rcx)
movq 0x50(%rcx), %rax
cmpq 0x68(%rcx), %rax
jbe 0x2a99
leaq -0x3b0(%rbp), %rdi
callq 0x4480
jmp 0x28ea
movq -0x5d0(%rbp), %rsi
leaq -0x440(%rbp), %rdi
callq 0x2b80
jmp 0x28ff
leaq -0x3b0(%rbp), %rdi
leaq -0x440(%rbp), %rsi
movq %rsi, -0x5f0(%rbp)
callq 0x48f0
movq -0x5f0(%rbp), %rdi
callq 0x46f0
movq -0x5d0(%rbp), %rdi
addq $0x38, %rdi
movl $0x1, %esi
callq 0x47b0
jmp 0x293c
leaq -0x598(%rbp), %rdi
leaq -0x3b0(%rbp), %rsi
callq 0x4570
jmp 0x2951
leaq -0x508(%rbp), %rdi
leaq -0x598(%rbp), %rsi
callq 0x4680
jmp 0x2966
movq -0x5d0(%rbp), %rdi
addq $0x38, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4550
movq %rax, %rdi
leaq -0x508(%rbp), %rsi
movq %rsi, -0x600(%rbp)
callq 0x4980
movq -0x600(%rbp), %rdi
callq 0x49e0
leaq -0x598(%rbp), %rdi
callq 0x46f0
movq -0x5d0(%rbp), %rax
movq $0x1, 0x50(%rax)
leaq -0x3b0(%rbp), %rdi
callq 0x4a10
movq %rax, -0x5f8(%rbp)
jmp 0x29cc
movq -0x5d0(%rbp), %rdi
movq -0x5f8(%rbp), %rax
movq %rax, 0x58(%rdi)
addq $0x20, %rdi
movl $0x1, %esi
callq 0x4840
jmp 0x29ee
movq -0x5d0(%rbp), %rdi
movq 0x58(%rdi), %rax
movq %rax, -0x608(%rbp)
addq $0x20, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x48d0
movq -0x608(%rbp), %rcx
movq %rcx, (%rax)
leaq -0x3b0(%rbp), %rdi
callq 0x46f0
jmp 0x2a99
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf8(%rbp)
movl %eax, -0xfc(%rbp)
leaq -0x320(%rbp), %rdi
callq 0x46f0
jmp 0x2abf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf8(%rbp)
movl %eax, -0xfc(%rbp)
jmp 0x2ab3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf8(%rbp)
movl %eax, -0xfc(%rbp)
jmp 0x2a8b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf8(%rbp)
movl %eax, -0xfc(%rbp)
leaq -0x598(%rbp), %rdi
callq 0x46f0
leaq -0x3b0(%rbp), %rdi
callq 0x46f0
jmp 0x2ab3
leaq -0x290(%rbp), %rdi
callq 0x49e0
leaq -0x190(%rbp), %rdi
callq 0x46f0
jmp 0x2ad0
leaq -0x290(%rbp), %rdi
callq 0x49e0
leaq -0x190(%rbp), %rdi
callq 0x46f0
jmp 0x2b5e
movq 0x286d1(%rip), %rsi     # 0x2b1a8
leaq -0x5a0(%rbp), %rdi
callq 0x4a30
jmp 0x2ae5
movq -0x5d0(%rbp), %rax
cvtsi2sdq 0x58(%rax), %xmm1
leaq -0x5b0(%rbp), %rdi
xorps %xmm0, %xmm0
callq 0x4a60
jmp 0x2b03
leaq -0x5c8(%rbp), %rdi
leaq -0x5b0(%rbp), %rsi
leaq -0x5a0(%rbp), %rdx
callq 0x4a90
jmp 0x2b1f
movq -0x5d0(%rbp), %rdi
leaq -0x5c8(%rbp), %rsi
callq 0x4ad0
jmp 0x2b34
movsd -0x18(%rbp), %xmm0
movsd %xmm0, -0x610(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x49e0
movsd -0x610(%rbp), %xmm0
addq $0x610, %rsp            # imm = 0x610
popq %rbp
retq
leaq -0xf0(%rbp), %rdi
callq 0x49e0
movq -0xf8(%rbp), %rdi
callq 0x22f0
nopw %cs:(%rax,%rax)