// File: /workspace/github_c_makefile_star2_O3/jflatow[P]jfdb/src/db.c
// Function: JFDB_open
JFDB *JFDB_open(const char *path, int flags) {
  JFDB *db = calloc(1, sizeof(JFDB));
  int len = strlen(path);
  if (db == NULL)
    return NULL;
  if (len == 0 || len > JFDB_MAX_PATH)
    return JFDB_set_error(db, JFDB_EPATH, "invalid path ('%.32s')", path);
  if ((db->path = strdup(path)) == NULL)
    return JFDB_set_error(db, JFDB_ENOMEM, "out of memory");
  if ((db->scratch[0] = JFT_membuf()) == NULL)
    return JFDB_set_error(db, JFDB_ENOMEM, "out of memory");
  if ((db->scratch[1] = JFT_membuf()) == NULL)
    return JFDB_set_error(db, JFDB_ENOMEM, "out of memory");

  char fp[JFDB_MAX_PATH + 6];
  db->flags = flags;

  // load vals before keys, because we want to keep the tip from keys
  snprintf(fp, sizeof(fp), "%s.vals", path);
  db->vmap.fd = JFDB_file_open(db, fp);
  if (JFDB_has_error(db))
    return db;

  snprintf(fp, sizeof(fp), "%s.keys", path);
  db->kmap.fd = JFDB_file_open(db, fp);
  if (JFDB_has_error(db))
    return db;

  // we'll need the *actual* size of the keys file to ensure correctness
  struct stat kstat;
  if (fstat(db->kmap.fd, &kstat))
    return JFDB_set_error(db, JFDB_EFILE, "failed to fstat keys");

  // load the checkpoint
  JFDB_CheckPoint *cp = &db->tip.cp;

  // map the files accordingly
  cp->lengthVals = MAX(cp->lengthVals, sizeof(JFDB_Header));
  JFDB_mmap_file(db, JFDB_VALS, cp->lengthVals, 1);
  if (JFDB_has_error(db))
    return db;

  cp->lengthKeys = MAX(cp->lengthKeys, sizeof(JFDB_Header));
  JFDB_mmap_file(db, JFDB_KEYS, cp->lengthKeys, 1);
  if (JFDB_has_error(db))
    return db;

  // ensure that the last checkpoint was written correctly, otherwise recompact
  if (kstat.st_size > cp->lengthKeys)
    return JFDB_compact(db, NULL);
  if (cp->offset && db->kmap.map[cp->lengthKeys - 1] != '\n')
    return JFDB_compact(db, NULL);
  return db;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x498, %rsp            # imm = 0x498
movl %esi, %ebp
movq %rdi, %r14
movl $0x1, %edi
movl $0xd98, %esi            # imm = 0xD98
callq 0x1120
movq %rax, %rbx
testq %rax, %rax
je 0x1a60
movq %r14, %rdi
callq 0x10a0
testl %eax, %eax
setne %cl
cmpl $0x401, %eax            # imm = 0x401
setl %al
testb %al, %cl
jne 0x196d
leaq 0x4777(%rip), %rdx      # 0x60cd
movq %rbx, %rdi
movl $0x3, %esi
movq %r14, %rcx
xorl %eax, %eax
callq 0x1b19
jmp 0x1a60
movq %r14, %rdi
callq 0x11c0
movq %rax, (%rbx)
testq %rax, %rax
je 0x1a4a
xorl %eax, %eax
callq 0x5403
movq %rax, 0x988(%rbx)
testq %rax, %rax
je 0x1a4a
xorl %eax, %eax
callq 0x5403
movq %rax, 0x990(%rbx)
testq %rax, %rax
je 0x1a4a
movl %ebp, 0x8c(%rbx)
leaq 0x4709(%rip), %rdx      # 0x60c5
leaq 0x90(%rsp), %r15
movl $0x406, %esi            # imm = 0x406
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x10d0
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1bb0
movl %eax, 0xa8(%rbx)
cmpl $0x0, 0x88(%rbx)
jne 0x1a60
leaq 0x46c6(%rip), %rdx      # 0x60bd
leaq 0x90(%rsp), %r15
movl $0x406, %esi            # imm = 0x406
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x10d0
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1bb0
movl %eax, 0x90(%rbx)
cmpl $0x0, 0x88(%rbx)
jne 0x1a60
movq %rsp, %rsi
movl %eax, %edi
callq 0x11d0
testl %eax, %eax
je 0x1a71
leaq 0x46b2(%rip), %rdx      # 0x60f2
movq %rbx, %rdi
movl $0x4, %esi
jmp 0x1a59
leaq 0x4693(%rip), %rdx      # 0x60e4
movq %rbx, %rdi
movl $0x2, %esi
xorl %eax, %eax
callq 0x1b19
movq %rbx, %rax
addq $0x498, %rsp            # imm = 0x498
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movq 0x118(%rbx), %rdx
cmpq $0x71, %rdx
movl $0x70, %r14d
cmovbq %r14, %rdx
movq %rdx, 0x118(%rbx)
movq %rbx, %rdi
movl $0x2, %esi
movl $0x1, %ecx
callq 0x1c9b
cmpl $0x0, 0x88(%rbx)
jne 0x1a60
movq 0x110(%rbx), %rax
cmpq $0x71, %rax
cmovaeq %rax, %r14
movq %r14, 0x110(%rbx)
movq %rbx, %rdi
movl $0x1, %esi
movq %r14, %rdx
movl $0x1, %ecx
callq 0x1c9b
cmpl $0x0, 0x88(%rbx)
jne 0x1a60
movq 0x110(%rbx), %rax
cmpq %rax, 0x30(%rsp)
ja 0x1b0a
cmpq $0x0, 0x128(%rbx)
je 0x1a60
movq 0x98(%rbx), %rcx
cmpb $0xa, -0x1(%rcx,%rax)
je 0x1a60
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1d9f
jmp 0x1a60