// File: cpottamus[P]btree_lab/btree.cc
// Function: BTreeIndex::LookupOrUpdateInternal(unsigned int const&, BTreeOp, Block const&, Block&)
ERROR_T BTreeIndex::LookupOrUpdateInternal(const SIZE_T &node,
  const BTreeOp op,
  const KEY_T &key,
  VALUE_T &value)
{
  BTreeNode b;
  ERROR_T rc;
  SIZE_T offset;
  KEY_T testkey;
  SIZE_T ptr;

  rc= b.Unserialize(buffercache,node);

  if (rc!=ERROR_NOERROR) { 
    return rc;
  }

  switch (b.info.nodetype) { 
    case BTREE_ROOT_NODE:
    case BTREE_INTERIOR_NODE:
    // Scan through key/ptr pairs
    //and recurse if possible
    for (offset=0;offset<b.info.numkeys;offset++) { 
      rc=b.GetKey(offset,testkey);
      if (rc) {  return rc; }
      if (key<testkey || key==testkey) { //STRUCTURED SO EQUIVALENT KEY VALUES ARE TO THE LEFT
	// OK, so we now have the first key that's larger
	// so we ned to recurse on the ptr immediately previous to 
	// this one, if it exists
       rc=b.GetPtr(offset,ptr);
       if (rc) { return rc; }
       return LookupOrUpdateInternal(ptr,op,key,value);
     }
   }
    // if we got here, we need to go to the next pointer, if it exists
   if (b.info.numkeys>0) { 
    rc=b.GetPtr(b.info.numkeys,ptr);
    if (rc) { return rc; }
    return LookupOrUpdateInternal(ptr,op,key,value);
  } else {
      // There are no keys at all on this node, so nowhere to go
    return ERROR_NONEXISTENT;
  }
  break;
  case BTREE_LEAF_NODE:
    // Scan through keys looking for matching value
  for (offset=0;offset<b.info.numkeys;offset++) { 
    rc=b.GetKey(offset,testkey);
    if (rc) {  return rc; }
    if (testkey==key) { 
     if (op==BTREE_OP_LOOKUP) { 
       return b.GetVal(offset,value);
     } else { 
      rc =  b.SetVal(offset, value);
      if(rc) {return rc;}
      rc = b.Serialize(buffercache, node);
      return rc;
    }
  }
}
return ERROR_NONEXISTENT;
break;
default:
    // We can't be looking at anything other than a root, internal, or leaf
return ERROR_INSANE;
break;
}  

return ERROR_INSANE;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xa8(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xee80
leaq -0x88(%rbp), %rdi
callq 0x43e0
jmp 0xa4d0
movq -0xa8(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x18(%rbp), %rax
movl (%rax), %edx
leaq -0x58(%rbp), %rdi
callq 0xf1a0
movl %eax, -0xac(%rbp)
jmp 0xa4f2
movl -0xac(%rbp), %eax
movl %eax, -0x5c(%rbp)
cmpl $0x0, -0x5c(%rbp)
je 0xa550
movl -0x5c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0xa890
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0xa8b1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x46e0
jmp 0xa8b1
movl -0x58(%rbp), %eax
movl %eax, -0xb0(%rbp)
addl $-0x2, %eax
subl $0x2, %eax
jb 0xa577
jmp 0xa563
movl -0xb0(%rbp), %eax
subl $0x4, %eax
je 0xa737
jmp 0xa87f
movl $0x0, -0x60(%rbp)
movl -0x60(%rbp), %eax
cmpl -0x40(%rbp), %eax
jae 0xa69e
movl -0x60(%rbp), %esi
leaq -0x58(%rbp), %rdi
leaq -0x88(%rbp), %rdx
callq 0xf5d0
movl %eax, -0xb4(%rbp)
jmp 0xa5a5
movl -0xb4(%rbp), %eax
movl %eax, -0x5c(%rbp)
cmpl $0x0, -0x5c(%rbp)
je 0xa5c9
movl -0x5c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0xa890
movq -0x28(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x47c0
movb %al, -0xb5(%rbp)
jmp 0xa5e1
movb -0xb5(%rbp), %al
testb $0x1, %al
jne 0xa611
jmp 0xa5ed
movq -0x28(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x4830
movb %al, -0xb6(%rbp)
jmp 0xa605
movb -0xb6(%rbp), %al
testb $0x1, %al
jne 0xa611
jmp 0xa68e
movl -0x60(%rbp), %esi
leaq -0x58(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0xf650
movl %eax, -0xbc(%rbp)
jmp 0xa62c
movl -0xbc(%rbp), %eax
movl %eax, -0x5c(%rbp)
cmpl $0x0, -0x5c(%rbp)
je 0xa650
movl -0x5c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0xa890
movq -0xa8(%rbp), %rdi
movl -0x1c(%rbp), %edx
movq -0x28(%rbp), %rcx
movq -0x30(%rbp), %r8
leaq -0x98(%rbp), %rsi
callq 0xa490
movl %eax, -0xc0(%rbp)
jmp 0xa676
movl -0xc0(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0xa890
jmp 0xa690
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0xa57e
cmpl $0x0, -0x40(%rbp)
jbe 0xa721
movl -0x40(%rbp), %esi
leaq -0x58(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0xf650
movl %eax, -0xc4(%rbp)
jmp 0xa6bf
movl -0xc4(%rbp), %eax
movl %eax, -0x5c(%rbp)
cmpl $0x0, -0x5c(%rbp)
je 0xa6e3
movl -0x5c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0xa890
movq -0xa8(%rbp), %rdi
movl -0x1c(%rbp), %edx
movq -0x28(%rbp), %rcx
movq -0x30(%rbp), %r8
leaq -0x98(%rbp), %rsi
callq 0xa490
movl %eax, -0xc8(%rbp)
jmp 0xa709
movl -0xc8(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0xa890
movl $0xfffffff7, -0x4(%rbp) # imm = 0xFFFFFFF7
movl $0x1, -0x9c(%rbp)
jmp 0xa890
movl $0x0, -0x60(%rbp)
movl -0x60(%rbp), %eax
cmpl -0x40(%rbp), %eax
jae 0xa86c
movl -0x60(%rbp), %esi
leaq -0x58(%rbp), %rdi
leaq -0x88(%rbp), %rdx
callq 0xf5d0
movl %eax, -0xcc(%rbp)
jmp 0xa765
movl -0xcc(%rbp), %eax
movl %eax, -0x5c(%rbp)
cmpl $0x0, -0x5c(%rbp)
je 0xa789
movl -0x5c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0xa890
movq -0x28(%rbp), %rsi
leaq -0x88(%rbp), %rdi
callq 0x4830
movb %al, -0xcd(%rbp)
jmp 0xa7a1
movb -0xcd(%rbp), %al
testb $0x1, %al
jne 0xa7b0
jmp 0xa85c
cmpl $0x3, -0x1c(%rbp)
jne 0xa7e6
movl -0x60(%rbp), %esi
movq -0x30(%rbp), %rdx
leaq -0x58(%rbp), %rdi
callq 0xf6a0
movl %eax, -0xd4(%rbp)
jmp 0xa7ce
movl -0xd4(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0xa890
movl -0x60(%rbp), %esi
movq -0x30(%rbp), %rdx
leaq -0x58(%rbp), %rdi
callq 0xf840
movl %eax, -0xd8(%rbp)
jmp 0xa7fe
movl -0xd8(%rbp), %eax
movl %eax, -0x5c(%rbp)
cmpl $0x0, -0x5c(%rbp)
je 0xa81f
movl -0x5c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0xa890
movq -0xa8(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x18(%rbp), %rax
movl (%rax), %edx
leaq -0x58(%rbp), %rdi
callq 0xf080
movl %eax, -0xdc(%rbp)
jmp 0xa841
movl -0xdc(%rbp), %eax
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0xa890
jmp 0xa85e
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0xa73e
movl $0xfffffff7, -0x4(%rbp) # imm = 0xFFFFFFF7
movl $0x1, -0x9c(%rbp)
jmp 0xa890
movl $0xfffffff1, -0x4(%rbp) # imm = 0xFFFFFFF1
movl $0x1, -0x9c(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x46e0
leaq -0x58(%rbp), %rdi
callq 0xeea0
movl -0x4(%rbp), %eax
addq $0xe0, %rsp
popq %rbp
retq
leaq -0x58(%rbp), %rdi
callq 0xeea0
movq -0x90(%rbp), %rdi
callq 0x3400
nopw %cs:(%rax,%rax)