// File: mh0fm4[P]SCDC/src/lib/redirect/redirect/redirect_cache.cc
// Function: redirect_cache_check
void redirect_cache_check(redirect_cache_t *rch, scdc_dataset_t ds, const char *uri, char *state, rdint_t *n)
{
  TRACE_F("ds: %" scdc_dataset_fmt ", uri: %s", ds, uri);

  char cmd[REDIRECT_CALL_URI_MAX_SIZE + REDIRECT_CALL_OP_MAX_SIZE + REDIRECT_CALL_CACHE_REQUEST_MAX_SIZE];
  rdint_t cmd_size = 0;

  if (ds == SCDC_DATASET_NULL) cmd_size += sprintf(cmd, "%s ", uri);

  rdint_t i, j;

  cmd_size += sprintf(cmd + cmd_size, "cache_check %" rdint_fmt ":", rch->nparams);
  for (i = 0; i < rch->nparams; ++i) cmd_size += sprintf(cmd + cmd_size, "t%d:s%" rdint_fmt ":", rch->params[i].type, rch->params[i].size);

  TRACE_F("cmd: '%s'", cmd);

  if (scdc_dataset_cmd(ds, cmd, 0, 0) != SCDC_SUCCESS)
  {
    TRACE_F("failed");
    return;
  }

  const char *s = scdc_last_result();
  rdint_t state_size = 0;

  for (i = 0; i < rch->nparams; ++i)
  {
    rdint_t nentries = 0;
    sscanf(s, "%" rdint_fmt, &nentries);
    s = strchr(s, ':') + 1;

    TRACE_F("param %" rdint_fmt ": type: %d, size: %" rdint_fmt, i, rch->params[i].type, rch->params[i].size);

    rch->params[i].entry_index = -1;

    if (nentries > 0)
    {
      /* compute parameter hash */
      redirect_param_dense_t p;
      p.buf = rch->params[i].buf;
      p.size = rch->params[i].size;
      rch->params[i].hash = redirect_param_hash_dense(&p);

      TRACE_F("param %" rdint_fmt ": hash %" redirect_param_hash_fmt, i, rch->params[i].hash);

      /* check against server hashes */
      for (j = 0; j < nentries; ++j)
      {
        redirect_param_hash_t entry_hash;
        rdint_t entry_index = -1;
        sscanf(s, "%" redirect_param_hash_fmt_scanf ":%" rdint_fmt, &entry_hash, &entry_index);
        s = strchr(s, ':') + 1;
        s = strchr(s, ':') + 1;

        if (entry_hash == rch->params[i].hash)
        {
          rch->params[i].entry_index = entry_index;
        }
      }
    }

    if (rch->params[i].entry_index >= 0) TRACE_F("param %" rdint_fmt ": matching cache entry %" rdint_fmt, i, rch->params[i].entry_index);
    else TRACE_F("param %" rdint_fmt ": no matching cache entry", i);


    state_size += sprintf(state + state_size, "%" rdint_fmt ":", rch->params[i].entry_index);
  }

  *n = state_size;

  TRACE_F("return: state: '%.*s'", static_cast<int>(*n), state);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2c0, %rsp            # imm = 0x2C0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq 0xc37fa(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94db7(%rip), %rsi     # 0xa5577
leaq 0x94e32(%rip), %rdx     # 0xa55f9
movb $0x0, %al
callq 0xc9a0
movq 0xc37db(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
leaq 0x94e27(%rip), %rsi     # 0xa560e
movb $0x0, %al
callq 0xc9a0
movq 0xc37bb(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x950a9(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
movq $0x0, -0x278(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x10841
leaq -0x270(%rbp), %rdi
movq -0x18(%rbp), %rdx
leaq 0x95190(%rip), %rsi     # 0xa59ba
movb $0x0, %al
callq 0xc0f0
cltq
addq -0x278(%rbp), %rax
movq %rax, -0x278(%rbp)
leaq -0x270(%rbp), %rdi
addq -0x278(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdx
leaq 0x94dc0(%rip), %rsi     # 0xa561e
movb $0x0, %al
callq 0xc0f0
cltq
addq -0x278(%rbp), %rax
movq %rax, -0x278(%rbp)
movq $0x0, -0x280(%rbp)
movq -0x280(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jge 0x108fd
leaq -0x270(%rbp), %rdi
addq -0x278(%rbp), %rdi
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rcx
addq %rcx, %rax
movl (%rax), %edx
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rcx
addq %rcx, %rax
movq 0x8(%rax), %rcx
leaq 0x94d5d(%rip), %rsi     # 0xa562f
movb $0x0, %al
callq 0xc0f0
cltq
addq -0x278(%rbp), %rax
movq %rax, -0x278(%rbp)
movq -0x280(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x280(%rbp)
jmp 0x10880
jmp 0x108ff
movq 0xc36aa(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94c67(%rip), %rsi     # 0xa5577
leaq 0x94ce2(%rip), %rdx     # 0xa55f9
movb $0x0, %al
callq 0xc9a0
movq 0xc368b(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq -0x270(%rbp), %rdx
leaq 0x94d03(%rip), %rsi     # 0xa5639
movb $0x0, %al
callq 0xc9a0
movq 0xc366c(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94f5a(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
movq -0x10(%rbp), %rdi
leaq -0x270(%rbp), %rsi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
movb $0x0, %al
callq 0x23d80
cmpq $0x1, %rax
je 0x109ca
jmp 0x10976
movq 0xc3633(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94bf0(%rip), %rsi     # 0xa5577
leaq 0x94c6b(%rip), %rdx     # 0xa55f9
movb $0x0, %al
callq 0xc9a0
movq 0xc3614(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x97568(%rip), %rsi     # 0xa7f0e
movb $0x0, %al
callq 0xc9a0
movq 0xc35fc(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94eea(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
jmp 0x10e3d
callq 0x21ec0
movq %rax, -0x290(%rbp)
movq $0x0, -0x298(%rbp)
movq $0x0, -0x280(%rbp)
movq -0x280(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jge 0x10dd3
movq $0x0, -0x2a0(%rbp)
movq -0x290(%rbp), %rdi
leaq 0x9546b(%rip), %rsi     # 0xa5e85
leaq -0x2a0(%rbp), %rdx
movb $0x0, %al
callq 0xc640
movq -0x290(%rbp), %rdi
movl $0x3a, %esi
callq 0xc220
addq $0x1, %rax
movq %rax, -0x290(%rbp)
movq 0xc3565(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94b22(%rip), %rsi     # 0xa5577
leaq 0x94b9d(%rip), %rdx     # 0xa55f9
movb $0x0, %al
callq 0xc9a0
movq 0xc3546(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
movq -0x280(%rbp), %rdx
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rcx
addq %rcx, %rax
movl (%rax), %ecx
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rsi
addq %rsi, %rax
movq 0x8(%rax), %r8
leaq 0x94b9c(%rip), %rsi     # 0xa5643
movb $0x0, %al
callq 0xc9a0
movq 0xc34fb(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94de9(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rcx
addq %rcx, %rax
movq $-0x1, 0x20(%rax)
cmpq $0x0, -0x2a0(%rbp)
jle 0x10c97
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movq %rax, -0x2b0(%rbp)
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq %rax, -0x2a8(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x21b90
movl %eax, %ecx
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rdx
addq %rdx, %rax
movl %ecx, 0x18(%rax)
movq 0xc345a(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94a17(%rip), %rsi     # 0xa5577
leaq 0x94a92(%rip), %rdx     # 0xa55f9
movb $0x0, %al
callq 0xc9a0
movq 0xc343b(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
movq -0x280(%rbp), %rdx
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rcx
addq %rcx, %rax
movl 0x18(%rax), %ecx
leaq 0x94ac6(%rip), %rsi     # 0xa5662
movb $0x0, %al
callq 0xc9a0
movq 0xc3406(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94cf4(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
movq $0x0, -0x288(%rbp)
movq -0x288(%rbp), %rax
cmpq -0x2a0(%rbp), %rax
jge 0x10c95
movq $-0x1, -0x2c0(%rbp)
movq -0x290(%rbp), %rdi
leaq 0x94a84(%rip), %rsi     # 0xa5677
leaq -0x2b4(%rbp), %rdx
leaq -0x2c0(%rbp), %rcx
movb $0x0, %al
callq 0xc640
movq -0x290(%rbp), %rdi
movl $0x3a, %esi
callq 0xc220
addq $0x1, %rax
movq %rax, -0x290(%rbp)
movq -0x290(%rbp), %rdi
movl $0x3a, %esi
callq 0xc220
addq $0x1, %rax
movq %rax, -0x290(%rbp)
movl -0x2b4(%rbp), %eax
movq -0x8(%rbp), %rcx
addq $0x18, %rcx
imulq $0x28, -0x280(%rbp), %rdx
addq %rdx, %rcx
cmpl 0x18(%rcx), %eax
jne 0x10c7c
movq -0x2c0(%rbp), %rcx
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rdx
addq %rdx, %rax
movq %rcx, 0x20(%rax)
jmp 0x10c7e
movq -0x288(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x288(%rbp)
jmp 0x10bc6
jmp 0x10c97
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rcx
addq %rcx, %rax
cmpq $0x0, 0x20(%rax)
jl 0x10d22
jmp 0x10cb3
movq 0xc32f6(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x948b3(%rip), %rsi     # 0xa5577
leaq 0x9492e(%rip), %rdx     # 0xa55f9
movb $0x0, %al
callq 0xc9a0
movq 0xc32d7(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
movq -0x280(%rbp), %rdx
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rcx
addq %rcx, %rax
movq 0x20(%rax), %rcx
leaq 0x9497d(%rip), %rsi     # 0xa567e
movb $0x0, %al
callq 0xc9a0
movq 0xc32a1(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94b8f(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
jmp 0x10d7c
jmp 0x10d24
movq 0xc3285(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94842(%rip), %rsi     # 0xa5577
leaq 0x948bd(%rip), %rdx     # 0xa55f9
movb $0x0, %al
callq 0xc9a0
movq 0xc3266(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
movq -0x280(%rbp), %rdx
leaq 0x94947(%rip), %rsi     # 0xa56a2
movb $0x0, %al
callq 0xc9a0
movq 0xc3247(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94b35(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
jmp 0x10d7c
movq -0x20(%rbp), %rdi
addq -0x298(%rbp), %rdi
movq -0x8(%rbp), %rax
addq $0x18, %rax
imulq $0x28, -0x280(%rbp), %rcx
addq %rcx, %rax
movq 0x20(%rax), %rdx
leaq 0x94885(%rip), %rsi     # 0xa562a
movb $0x0, %al
callq 0xc0f0
cltq
addq -0x298(%rbp), %rax
movq %rax, -0x298(%rbp)
movq -0x280(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x280(%rbp)
jmp 0x109ec
movq -0x298(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq 0xc31c8(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94785(%rip), %rsi     # 0xa5577
leaq 0x94800(%rip), %rdx     # 0xa55f9
movb $0x0, %al
callq 0xc9a0
movq 0xc31a9(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
movq -0x28(%rbp), %rax
movq (%rax), %rax
movl %eax, %edx
movq -0x20(%rbp), %rcx
leaq 0x948a7(%rip), %rsi     # 0xa56c5
movb $0x0, %al
callq 0xc9a0
movq 0xc3184(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x94a72(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
addq $0x2c0, %rsp            # imm = 0x2C0
popq %rbp
retq
nopw %cs:(%rax,%rax)