// File: /workspace/github_c_makefile_star2_O0/jflatow[P]jfdb/src/db.c
// Function: JFDB_write
JFDB *JFDB_write(JFDB *db, const JFT *tx, int flags) {
  // bump the level, merge all the levels up to this one
  // if we are at or beyond the file level: compact everything into a new file
  JFDB_CheckPoint *cp = &db->tip.cp;
  if (++cp->levels >= (1LLU << db->tip.level))
    return JFDB_compact(db, tx);

  // the caller can force a flush using the flags
  if (flags & JFDB_FLUSH)
    db->oughtFlush = True;
  db->isModified = True;

  // walk back N levels from prior - merge tries into a new trie
  JFT_Offset prior = cp->offset;
  JFT *trie = JFDB_get_trie(db, prior);
  JFT_Amount N = ffsll(cp->levels) - 1;
  JFT_Cursor cursors[N + 1];
  cursors[0] = JFT_cursor((JFT *)tx);
  for (int i = 1; i <= N; i++) {
    cursors[i] = JFT_cursor(trie);
    trie = JFDB_get_trie(db, JFT_parent_offset(trie));
  }

  // make the new trie
  JFT_Buffer *buf = db->scratch[0];
  JFT *next = JFT_cursor_merge_new(cursors, N + 1, buf, 0);
  if (!next)
    return JFDB_set_error(db, JFDB_ETRIE, "failed to merge keys");

  // set the parent: if we merged than that of the last trie, otherwise the prior
  JFT_set_parent_offset(next, N ? JFT_parent_offset(cursors[N].root) : prior);

  // as soon as we change the file size, our last checkpoint becomes stale
  if (ftruncate(db->kmap.fd, cp->lengthKeys + buf->mark + 1))
    return JFDB_set_error(db, JFDB_EFILE, "failed to truncate keys");

  if (pwrite(db->kmap.fd, buf->data, buf->mark, cp->lengthKeys) < buf->mark)
    return JFDB_set_error(db, JFDB_EFILE, "failed to append to keys");
  if (pwrite(db->kmap.fd, "\n", 1, cp->lengthKeys + buf->mark) < 1)
    return JFDB_set_error(db, JFDB_EFILE, "failed to append keys separator");

  cp->offset = cp->lengthKeys;
  cp->lengthKeys += buf->mark + 1;

  // remap to cover the newly appended trie
  JFDB_mmap_file(db, JFDB_KEYS, cp->lengthKeys, 2);
  if (JFDB_has_error(db))
    return db;

  // now mark everything that was changed as dirty
  JFDB_mark_dirty(db, tx, prior);
  if (JFDB_has_error(db))
    return db;

  // flush if we need to flush
  if (db->oughtFlush)
    JFDB_flush(db);
  return db;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq -0x10(%rbp), %rax
addq $0xc0, %rax
addq $0x10, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rcx
movq 0x50(%rcx), %rax
addq $0x1, %rax
movq %rax, 0x50(%rcx)
movq -0x10(%rbp), %rcx
movzbl 0xc8(%rcx), %ecx
movl %ecx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
cmpq %rcx, %rax
jb 0x307b
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x26f0
movq %rax, -0x8(%rbp)
jmp 0x346b
movl -0x1c(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x3094
movq -0x10(%rbp), %rax
movl $0x1, 0x984(%rax)
movq -0x10(%rbp), %rax
movl $0x1, 0x980(%rax)
movq -0x28(%rbp), %rax
movq 0x58(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x3480
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movq 0x50(%rax), %rdx
tzcntq %rdx, %rax
incl %eax
xorl %ecx, %ecx
testq %rdx, %rdx
cmovel %ecx, %eax
decl %eax
cltq
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rcx
movq %rcx, %rax
incq %rax
movq %rsp, %rdx
movq %rdx, -0x48(%rbp)
imulq $0x38, %rcx, %rdx
addq $0x47, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0xe8(%rbp)
movq %rcx, %rsp
movq %rax, -0x50(%rbp)
movq -0x18(%rbp), %rsi
leaq -0x88(%rbp), %rdi
callq 0x34a0
movq -0xe8(%rbp), %rdi
leaq -0x88(%rbp), %rsi
movl $0x38, %edx
callq 0x1140
movl $0x1, -0x8c(%rbp)
movslq -0x8c(%rbp), %rax
cmpq -0x40(%rbp), %rax
ja 0x31cd
movq -0xe8(%rbp), %rax
movslq -0x8c(%rbp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xf8(%rbp)
movq -0x38(%rbp), %rsi
leaq -0xc8(%rbp), %rdi
callq 0x34a0
movq -0xf8(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
movl $0x38, %edx
callq 0x1140
movq -0x10(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0x38(%rbp), %rdi
callq 0x34f0
movq -0xf0(%rbp), %rdi
movq %rax, %rsi
callq 0x3480
movq %rax, -0x38(%rbp)
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x3141
movq -0xe8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x988(%rax), %rax
movq %rax, -0xd0(%rbp)
movq -0x40(%rbp), %rsi
addq $0x1, %rsi
movq -0xd0(%rbp), %rdx
xorl %ecx, %ecx
callq 0x5840
movq %rax, -0xd8(%rbp)
cmpq $0x0, -0xd8(%rbp)
jne 0x3237
movq -0x10(%rbp), %rdi
movl $0x6, %esi
leaq 0x5eff(%rip), %rdx      # 0x911c
movb $0x0, %al
callq 0x2320
movq %rax, -0x8(%rbp)
movl $0x1, -0xdc(%rbp)
jmp 0x3464
movq -0xd8(%rbp), %rax
movq %rax, -0x100(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x326c
movq -0xe8(%rbp), %rax
imulq $0x38, -0x40(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rdi
callq 0x34f0
movq %rax, -0x108(%rbp)
jmp 0x3277
movq -0x30(%rbp), %rax
movq %rax, -0x108(%rbp)
movq -0x100(%rbp), %rdi
movq -0x108(%rbp), %rsi
callq 0x3510
movq -0x10(%rbp), %rax
movl 0x90(%rax), %edi
movq -0x28(%rbp), %rax
movq 0x40(%rax), %rsi
movq -0xd0(%rbp), %rax
addq 0x10(%rax), %rsi
addq $0x1, %rsi
callq 0x10e0
cmpl $0x0, %eax
je 0x32df
movq -0x10(%rbp), %rdi
movl $0x4, %esi
leaq 0x5e6c(%rip), %rdx      # 0x9131
movb $0x0, %al
callq 0x2320
movq %rax, -0x8(%rbp)
movl $0x1, -0xdc(%rbp)
jmp 0x3464
movq -0x10(%rbp), %rax
movl 0x90(%rax), %edi
movq -0xd0(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0xd0(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x28(%rbp), %rax
movq 0x40(%rax), %rcx
callq 0x1180
movq -0xd0(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jae 0x3343
movq -0x10(%rbp), %rdi
movl $0x4, %esi
leaq 0x5e20(%rip), %rdx      # 0x9149
movb $0x0, %al
callq 0x2320
movq %rax, -0x8(%rbp)
movl $0x1, -0xdc(%rbp)
jmp 0x3464
movq -0x10(%rbp), %rax
movl 0x90(%rax), %edi
movq -0x28(%rbp), %rax
movq 0x40(%rax), %rcx
movq -0xd0(%rbp), %rax
addq 0x10(%rax), %rcx
leaq 0x5cbd(%rip), %rsi      # 0x9024
movl $0x1, %edx
callq 0x1180
cmpq $0x1, %rax
jge 0x33a1
movq -0x10(%rbp), %rdi
movl $0x4, %esi
leaq 0x5ddb(%rip), %rdx      # 0x9162
movb $0x0, %al
callq 0x2320
movq %rax, -0x8(%rbp)
movl $0x1, -0xdc(%rbp)
jmp 0x3464
movq -0x28(%rbp), %rax
movq 0x40(%rax), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x58(%rax)
movq -0xd0(%rbp), %rax
movq 0x10(%rax), %rcx
addq $0x1, %rcx
movq -0x28(%rbp), %rax
addq 0x40(%rax), %rcx
movq %rcx, 0x40(%rax)
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rax
movq 0x40(%rax), %rdx
movl $0x1, %esi
movl $0x2, %ecx
callq 0x2570
movq -0x10(%rbp), %rdi
callq 0x2540
cmpl $0x0, %eax
je 0x3409
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0xdc(%rbp)
jmp 0x3464
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x3550
movq -0x10(%rbp), %rdi
callq 0x2540
cmpl $0x0, %eax
je 0x343c
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0xdc(%rbp)
jmp 0x3464
movq -0x10(%rbp), %rax
cmpl $0x0, 0x984(%rax)
je 0x3452
movq -0x10(%rbp), %rdi
callq 0x2d10
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0xdc(%rbp)
movq -0x48(%rbp), %rax
movq %rax, %rsp
movq -0x8(%rbp), %rax
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)