// File: /workspace/github_c_makefile_star2_O0/jflatow[P]jfdb/src/db.c
// Function: JFDB_compact
JFDB *JFDB_compact(JFDB *db, const JFT *tx) {
  JFDB_CheckPoint *cp = &db->tip.cp;

  // merge all tries into a new trie - at this level there should be at most N
  // allow one additional trie (as argument), in case we are performing a write
  JFT_Amount N = db->tip.level, i = 0;
  JFT_Cursor cursors[N + 1];
  if (tx)
    cursors[i++] = JFT_cursor((JFT *)tx);

  // walk backwards from the latest checkpoint for as far as we can, one cursor per trie
  JFT *trie;
  for (JFT_Offset pos = db->tip.cp.offset; pos; pos = JFT_parent_offset(trie)) {
    trie = JFDB_get_trie(db, pos);
    cursors[i++] = JFT_cursor(trie);
  }

  // if there's nothing to merge (empty db), we are done
  if (i == 0)
    return db;

  JFT_Buffer *buf = db->scratch[0];
  JFT *next = JFT_cursor_merge_new(cursors, i, buf, 0);

  if (!next)
    return JFDB_set_error(db, JFDB_ETRIE, "failed to merge keys");

  JFDB_calculate_gaps(db, next);
  if (JFDB_has_error(db))
    return JFDB_set_error(db, JFDB_ETRIE, "failed to calculate gaps");

  // release the old file
  JFDB_mmap_release(db, JFDB_KEYS);

  // produce the new file
  char fp[JFDB_MAX_PATH + 6];
  char tp[JFDB_MAX_PATH + 10];
  snprintf(fp, sizeof(fp), "%s.keys", db->path);
  snprintf(tp, sizeof(tp), "%s.keys.tmp", db->path);
  db->kmap.fd = JFDB_file_open(db, tp);
  if (JFDB_has_error(db))
    return db;

  // write the new header: base the level on the # primary keys
  db->tip.level = flsll(((JFT_Root *)next)->numPrimary);
  cp->lengthKeys = sizeof(JFDB_Header) + buf->mark + 1;
  cp->levels = 1;
  cp->offset = sizeof(JFDB_Header);
  if (pwrite(db->kmap.fd, &db->tip, sizeof(JFDB_Header), 0) < sizeof(JFDB_Header))
    return JFDB_set_error(db, JFDB_EFILE, "failed to write compact keys header");

  // write the trie, sync to disk, rename the file
  if (pwrite(db->kmap.fd, buf->data, buf->mark, sizeof(JFDB_Header)) < buf->mark)
    return JFDB_set_error(db, JFDB_EFILE, "failed to write compact keys");
  if (pwrite(db->kmap.fd, "\n", 1, sizeof(JFDB_Header) + buf->mark) < 1)
    return JFDB_set_error(db, JFDB_EFILE, "failed to append keys separator");
  if (JFDB_fsync(db->kmap.fd))
    return JFDB_set_error(db, JFDB_EFILE, "failed to fsync compact keys");
  if (rename(tp, fp))
    return JFDB_set_error(db, JFDB_EFILE, "failed to rename compact keys");

  // map the new file
  JFDB_mmap_file(db, JFDB_KEYS, cp->lengthKeys, 1);
  if (JFDB_has_error(db))
    return db;

  // clear the between flush state
  db->freeList.size = 0;
  db->isModified = False;
  db->oughtFlush = False;

  // XXX: if we wanted to release some memory we could shrink buf (flag on open?)

  return db;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x910, %rsp            # imm = 0x910
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
addq $0xd0, %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movzbl 0xc8(%rax), %eax
movq %rax, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x28(%rbp), %rcx
movq %rcx, %rax
incq %rax
movq %rsp, %rdx
movq %rdx, -0x38(%rbp)
imulq $0x38, %rcx, %rdx
addq $0x47, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x8f8(%rbp)
movq %rcx, %rsp
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x27a6
movq -0x8f8(%rbp), %rax
movq -0x30(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x30(%rbp)
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x900(%rbp)
movq -0x18(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x34a0
movq -0x900(%rbp), %rdi
leaq -0x78(%rbp), %rsi
movl $0x38, %edx
callq 0x1140
movq -0x10(%rbp), %rax
movq 0x128(%rax), %rax
movq %rax, -0x88(%rbp)
cmpq $0x0, -0x88(%rbp)
je 0x2837
movq -0x10(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x3480
movq %rax, %rcx
movq -0x8f8(%rbp), %rax
movq %rcx, -0x80(%rbp)
movq -0x30(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x30(%rbp)
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x908(%rbp)
movq -0x80(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
callq 0x34a0
movq -0x908(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
movl $0x38, %edx
callq 0x1140
movq -0x80(%rbp), %rdi
callq 0x34f0
movq %rax, -0x88(%rbp)
jmp 0x27b8
cmpq $0x0, -0x30(%rbp)
jne 0x2855
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x2c16
movq -0x8f8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x988(%rax), %rax
movq %rax, -0xd0(%rbp)
movq -0x30(%rbp), %rsi
movq -0xd0(%rbp), %rdx
xorl %ecx, %ecx
callq 0x5840
movq %rax, -0xd8(%rbp)
cmpq $0x0, -0xd8(%rbp)
jne 0x28bb
movq -0x10(%rbp), %rdi
movl $0x6, %esi
leaq 0x687b(%rip), %rdx      # 0x911c
movb $0x0, %al
callq 0x2320
movq %rax, -0x8(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x2c16
movq -0x10(%rbp), %rdi
movq -0xd8(%rbp), %rsi
callq 0x4040
movq -0x10(%rbp), %rdi
callq 0x2540
cmpl $0x0, %eax
je 0x2903
movq -0x10(%rbp), %rdi
movl $0x6, %esi
leaq 0x6939(%rip), %rdx      # 0x9222
movb $0x0, %al
callq 0x2320
movq %rax, -0x8(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x2c16
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x2f30
leaq -0x4e0(%rbp), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rcx
movl $0x406, %esi            # imm = 0x406
leaq 0x6792(%rip), %rdx      # 0x90bd
movb $0x0, %al
callq 0x10d0
leaq -0x8f0(%rbp), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rcx
movl $0x40a, %esi            # imm = 0x40A
leaq 0x68ef(%rip), %rdx      # 0x923b
movb $0x0, %al
callq 0x10d0
movq -0x10(%rbp), %rdi
leaq -0x8f0(%rbp), %rsi
callq 0x23d0
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x90(%rax)
movq -0x10(%rbp), %rdi
callq 0x2540
cmpl $0x0, %eax
je 0x2994
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x2c16
movq -0xd8(%rbp), %rax
cmpl $0x0, 0x20(%rax)
jne 0x29ac
xorl %eax, %eax
movq %rax, -0x910(%rbp)
jmp 0x29ce
movq -0xd8(%rbp), %rax
movl 0x20(%rax), %eax
bsrl %eax, %eax
xorl $0x1f, %eax
movslq %eax, %rcx
movl $0x20, %eax
subq %rcx, %rax
movq %rax, -0x910(%rbp)
movq -0x910(%rbp), %rax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0xc8(%rax)
movq -0xd0(%rbp), %rax
movq 0x10(%rax), %rcx
addq $0x70, %rcx
addq $0x1, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x20(%rbp), %rax
movq $0x1, 0x50(%rax)
movq -0x20(%rbp), %rax
movq $0x70, 0x58(%rax)
movq -0x10(%rbp), %rax
movl 0x90(%rax), %edi
movq -0x10(%rbp), %rsi
addq $0xc0, %rsi
movl $0x70, %edx
xorl %eax, %eax
movl %eax, %ecx
callq 0x1180
cmpq $0x70, %rax
jae 0x2a67
movq -0x10(%rbp), %rdi
movl $0x4, %esi
leaq 0x67fa(%rip), %rdx      # 0x9247
movb $0x0, %al
callq 0x2320
movq %rax, -0x8(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x2c16
movq -0x10(%rbp), %rax
movl 0x90(%rax), %edi
movq -0xd0(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0xd0(%rbp), %rax
movq 0x10(%rax), %rdx
movl $0x70, %ecx
callq 0x1180
movq -0xd0(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jae 0x2ac8
movq -0x10(%rbp), %rdi
movl $0x4, %esi
leaq 0x67bd(%rip), %rdx      # 0x926b
movb $0x0, %al
callq 0x2320
movq %rax, -0x8(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x2c16
movq -0x10(%rbp), %rax
movl 0x90(%rax), %edi
movq -0xd0(%rbp), %rax
movq 0x10(%rax), %rcx
addq $0x70, %rcx
leaq 0x653c(%rip), %rsi      # 0x9024
movl $0x1, %edx
callq 0x1180
cmpq $0x1, %rax
jge 0x2b22
movq -0x10(%rbp), %rdi
movl $0x4, %esi
leaq 0x665a(%rip), %rdx      # 0x9162
movb $0x0, %al
callq 0x2320
movq %rax, -0x8(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x2c16
movq -0x10(%rbp), %rax
movl 0x90(%rax), %edi
callq 0x1050
cmpl $0x0, %eax
je 0x2b60
movq -0x10(%rbp), %rdi
movl $0x4, %esi
leaq 0x6742(%rip), %rdx      # 0x9288
movb $0x0, %al
callq 0x2320
movq %rax, -0x8(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x2c16
leaq -0x8f0(%rbp), %rdi
leaq -0x4e0(%rbp), %rsi
callq 0x11b0
cmpl $0x0, %eax
je 0x2b9f
movq -0x10(%rbp), %rdi
movl $0x4, %esi
leaq 0x671d(%rip), %rdx      # 0x92a5
movb $0x0, %al
callq 0x2320
movq %rax, -0x8(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x2c16
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x40(%rax), %rdx
movl $0x1, %ecx
movl %ecx, %esi
callq 0x2570
movq -0x10(%rbp), %rdi
callq 0x2540
cmpl $0x0, %eax
je 0x2bd9
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x2c16
movq -0x10(%rbp), %rax
movq $0x0, 0x138(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x980(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x984(%rax)
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0xc4(%rbp)
movq -0x38(%rbp), %rax
movq %rax, %rsp
movq -0x8(%rbp), %rax
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)