// File: /workspace/github_c_makefile_star2_O2/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
pushq $0x1
popq %rdi
movl $0xd98, %esi            # imm = 0xD98
callq 0x1120
movq %rax, %rbx
testq %rax, %rax
je 0x1a48
movq %r14, %rdi
callq 0x10a0
testl %eax, %eax
setne %cl
cmpl $0x401, %eax            # imm = 0x401
setl %al
testb %al, %cl
jne 0x195d
leaq 0x3785(%rip), %rdx      # 0x50cd
pushq $0x3
popq %rsi
movq %rbx, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x1af6
jmp 0x1a48
movq %r14, %rdi
callq 0x11c0
movq %rax, (%rbx)
testq %rax, %rax
je 0x1a34
xorl %eax, %eax
callq 0x47cd
movq %rax, 0x988(%rbx)
testq %rax, %rax
je 0x1a34
xorl %eax, %eax
callq 0x47cd
movq %rax, 0x990(%rbx)
testq %rax, %rax
je 0x1a34
movl %ebp, 0x8c(%rbx)
leaq 0x3719(%rip), %rdx      # 0x50c5
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 0x1b8d
movl %eax, 0xa8(%rbx)
cmpl $0x0, 0x88(%rbx)
jne 0x1a48
leaq 0x36d6(%rip), %rdx      # 0x50bd
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 0x1b8d
movl %eax, 0x90(%rbx)
cmpl $0x0, 0x88(%rbx)
jne 0x1a48
movq %rsp, %rsi
movl %eax, %edi
callq 0x11d0
testl %eax, %eax
je 0x1a59
leaq 0x36c2(%rip), %rdx      # 0x50f2
pushq $0x4
jmp 0x1a3d
leaq 0x36a9(%rip), %rdx      # 0x50e4
pushq $0x2
popq %rsi
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1af6
movq %rbx, %rax
addq $0x498, %rsp            # imm = 0x498
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movq 0x118(%rbx), %rdx
cmpq $0x71, %rdx
pushq $0x70
popq %r14
cmovbq %r14, %rdx
movq %rdx, 0x118(%rbx)
pushq $0x2
popq %rsi
pushq $0x1
popq %rcx
movq %rbx, %rdi
callq 0x1c70
cmpl $0x0, 0x88(%rbx)
jne 0x1a48
movq 0x110(%rbx), %rax
cmpq $0x71, %rax
cmovaeq %rax, %r14
movq %r14, 0x110(%rbx)
pushq $0x1
popq %rcx
movq %rbx, %rdi
movl %ecx, %esi
movq %r14, %rdx
callq 0x1c70
cmpl $0x0, 0x88(%rbx)
jne 0x1a48
movq 0x110(%rbx), %rax
cmpq %rax, 0x30(%rsp)
ja 0x1ae7
cmpq $0x0, 0x128(%rbx)
je 0x1a48
movq 0x98(%rbx), %rcx
cmpb $0xa, -0x1(%rcx,%rax)
je 0x1a48
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1d6d
jmp 0x1a48