// File: cpottamus[P]btree_lab/disksystem.cc
// Function: DiskSystem::ModelAccess(unsigned int, unsigned int)
double DiskSystem::ModelAccess(const SIZE_T offblock, const SIZE_T numblock) 
{

  SIZE_T req_trackstart = (offblock) / (numheads*blockspertrack);
  SIZE_T req_sectorstart=  (offblock) % (numheads*blockspertrack);

  SIZE_T req_trackend = (offblock+numblock-1) / (numheads*blockspertrack);
  SIZE_T req_sectorend=  (offblock+numblock-1) % (numheads*blockspertrack);

  SIZE_T trackhop = (SIZE_T) fabs((double)req_trackstart-(double)last_track);
  double trackhopfrac = (double)trackhop/(double)numtracks;

  // This is a simplistic model.  
  double trackbytracktime = trackhop*trackseeklatency;
  double longseektime = (trackhopfrac/(0.5))*averageseeklatency;
  double timeinseek = trackbytracktime<longseektime ? trackbytracktime : longseektime;

  // Now we are on the first track and we need to wait for the first
  // sector to show up

  SIZE_T sectorhop = (req_sectorstart >= last_sector) ? (req_sectorstart-last_sector) : (blockspertrack - (last_sector - req_sectorstart));
  double sectorhopfrac = (double)sectorhop/(double)blockspertrack;
  double timeinrotation=rotationallatency*sectorhopfrac;

  // Now we've got to read numblockelements

  // The number of side by side tracks we'll deal with:
  SIZE_T numtrackbytrackhops = req_trackend-req_trackstart;
  double timeintrackbytrackhops = numtrackbytrackhops*trackseeklatency;

  // The total number of sectors read
  double timeinreadsectors = rotationallatency*((double)numblock/(double)blockspertrack);

  last_track=req_trackend;
  last_sector=req_sectorend;

  return timeinseek+timeinrotation+timeintrackbytrackhops+timeinreadsectors;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x18, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq -0x8(%rbp), %rsi
movq %rsi, -0x80(%rbp)
movl -0xc(%rbp), %eax
movl 0x54(%rsi), %ecx
movl 0x58(%rsi), %edx
imull %edx, %ecx
xorl %edx, %edx
movl %edx, -0x84(%rbp)
divl %ecx
movl -0x84(%rbp), %edx
movl %eax, -0x14(%rbp)
movl -0xc(%rbp), %eax
movl 0x54(%rsi), %ecx
movl 0x58(%rsi), %edi
imull %edi, %ecx
divl %ecx
movl %edx, %eax
movl -0x84(%rbp), %edx
movl %eax, -0x18(%rbp)
movl -0xc(%rbp), %edi
movl -0x10(%rbp), %eax
movl %eax, %ecx
movl %edi, %eax
leal -0x1(%rax,%rcx), %eax
movl 0x54(%rsi), %ecx
movl 0x58(%rsi), %edi
imull %edi, %ecx
divl %ecx
movl -0x84(%rbp), %edx
movl %eax, -0x1c(%rbp)
movl -0xc(%rbp), %edi
movl -0x10(%rbp), %eax
movl %eax, %ecx
movl %edi, %eax
leal -0x1(%rax,%rcx), %eax
movl 0x54(%rsi), %ecx
movl 0x58(%rsi), %esi
imull %esi, %ecx
divl %ecx
movq -0x80(%rbp), %rax
movl %edx, -0x20(%rbp)
movl -0x14(%rbp), %ecx
cvtsi2sd %rcx, %xmm0
movl 0x60(%rax), %ecx
cvtsi2sd %rcx, %xmm1
subsd %xmm1, %xmm0
movaps 0xa4f1(%rip), %xmm1     # 0x10230
pand %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
movl %ecx, -0x24(%rbp)
movl -0x24(%rbp), %ecx
cvtsi2sd %rcx, %xmm0
movl 0x5c(%rax), %ecx
cvtsi2sd %rcx, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
movl -0x24(%rbp), %ecx
cvtsi2sd %rcx, %xmm0
mulsd 0x70(%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movsd -0x30(%rbp), %xmm0
movsd 0xa49d(%rip), %xmm1     # 0x10220
divsd %xmm1, %xmm0
mulsd 0x68(%rax), %xmm0
movsd %xmm0, -0x40(%rbp)
movsd -0x38(%rbp), %xmm1
movsd -0x40(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x5db0
movsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
jmp 0x5dbd
movsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
movq -0x80(%rbp), %rcx
movsd -0x90(%rbp), %xmm0
movsd %xmm0, -0x48(%rbp)
movl -0x18(%rbp), %eax
cmpl 0x64(%rcx), %eax
jb 0x5de8
movq -0x80(%rbp), %rcx
movl -0x18(%rbp), %eax
subl 0x64(%rcx), %eax
movl %eax, -0x94(%rbp)
jmp 0x5dfd
movq -0x80(%rbp), %rcx
movl 0x58(%rcx), %eax
movl 0x64(%rcx), %ecx
subl -0x18(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0x94(%rbp)
movq -0x80(%rbp), %rax
movl -0x94(%rbp), %ecx
movl %ecx, -0x4c(%rbp)
movl -0x4c(%rbp), %ecx
cvtsi2sd %rcx, %xmm0
movl 0x58(%rax), %ecx
cvtsi2sd %rcx, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
movsd 0x78(%rax), %xmm0
movsd -0x58(%rbp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rbp)
movl -0x1c(%rbp), %ecx
movl -0x14(%rbp), %edx
subl %edx, %ecx
movl %ecx, -0x64(%rbp)
movl -0x64(%rbp), %ecx
cvtsi2sd %rcx, %xmm0
movsd 0x70(%rax), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x70(%rbp)
movsd 0x78(%rax), %xmm0
movl -0x10(%rbp), %ecx
cvtsi2sd %rcx, %xmm1
movl 0x58(%rax), %ecx
cvtsi2sd %rcx, %xmm2
divsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x78(%rbp)
movl -0x1c(%rbp), %ecx
movl %ecx, 0x60(%rax)
movl -0x20(%rbp), %ecx
movl %ecx, 0x64(%rax)
movsd -0x48(%rbp), %xmm0
addsd -0x60(%rbp), %xmm0
addsd -0x70(%rbp), %xmm0
addsd -0x78(%rbp), %xmm0
addq $0x18, %rsp
popq %rbp
retq
nop