cache/req.c
changeset 31 12d5361e7472
parent 30 33e464fd6773
child 33 b750e8865127
equal deleted inserted replaced
30:33e464fd6773 31:12d5361e7472
       
     1 #include <stdlib.h>
       
     2 #include <string.h>
       
     3 #include <assert.h>
     1 
     4 
     2 #include "../cache.h"
     5 #include "../cache.h"
       
     6 #include "cache.h"
     3 #include "req.h"
     7 #include "req.h"
     4 #include "op.h"
     8 #include "op.h"
     5 #include "common.h"
     9 #include "engine.h"
       
    10 #include "../common.h"
     6 
    11 
     7 struct cache_req *cache_request (struct cache *cache, struct cache_key *key, cache_callback cb_func, void *cb_data) {
    12 void _cache_req_free (struct cache_req *req) {
       
    13     free(req->key_copy.buf);
       
    14     free(req);
       
    15 }
       
    16 
       
    17 struct cache_req *cache_req (struct cache *cache, const struct cache_key *key, cache_callback cb_func, void *cb_data) {
     8     struct cache_req *req = NULL;
    18     struct cache_req *req = NULL;
     9 
    19 
    10     // calloc the req info
    20     // calloc the req info
    11     if ((req = calloc(1, sizeof(*req))) == NULL)
    21     if ((req = calloc(1, sizeof(*req))) == NULL)
    12         ERROR("calloc");
    22         ERROR("calloc");
    13     
    23     
    14     // set up basic state
    24     // set up basic state
    15     req->key = key;
       
    16     req->cb_func = cb_func;
    25     req->cb_func = cb_func;
    17     req->cb_data = cb_data;
    26     req->cb_data = cb_data;
    18     req->is_write = 0;
    27     req->is_write = 0;
    19 
    28 
       
    29     // copy the key
       
    30     if (key->length == 0)
       
    31         req->key_copy.length = strlen(key->buf) + 1;
       
    32     else
       
    33         req->key_copy.length = key->length;
       
    34 
       
    35     if (req->key_copy.length == 0)
       
    36         ERROR("zero-length key");
       
    37 
       
    38     if ((req->key_copy.buf = malloc(req->key_copy.length)) == NULL)
       
    39         ERROR("malloc");
       
    40 
       
    41     memcpy(req->key_copy.buf, key->buf, req->key_copy.length);
       
    42     
       
    43     req->key = &req->key_copy;
       
    44 
    20     // look for an existing cache_op for this key
    45     // look for an existing cache_op for this key
    21     if ((req->op = cache_op_find(cache, key)) == NULL) {
    46     if ((req->op = cache_op_find(cache, req->key)) == NULL) {
    22 
    47 
    23         // none available, start a new cache op
    48         // none available, start a new cache op
    24         if (cache->engine->fn_op_start(cache, &req->op, key))
    49         if (cache->engine->fn_op_start(cache, &req->op, req->key))
    25             goto error;
    50             goto error;
    26 
    51 
    27         // since we were the one that created it, we take care of writing it
    52         // since we were the one that created it, we take care of writing it
    28         req->is_write = 1;
    53         req->is_write = 1;
    29         
    54         
    30     } else {
    55     } else {
    31         // we found an existing cache_op, we can just use that
    56         // we found an existing cache_op, we can just use that
    32         
    57         
    33     }
    58     }
    34     
    59     
       
    60     // engine may forget to update the op_ptr
       
    61     assert(req->op);
       
    62     
    35     // register
    63     // register
    36     if (cache_op_reigster(req->op, req))
    64     if (cache_op_register(req->op, req))
    37         goto error;
    65         goto error;
    38 
    66 
    39     // hurray, we now have an active cache_op \o/
    67     // hurray, we now have an active cache_op \o/
    40     return 0;
    68     return req;
    41 
    69 
    42 error:
    70 error:
    43     free(req);
    71     _cache_req_free(req);
    44 
    72 
    45     return -1;
    73     return NULL;
    46 }
    74 }
    47 
    75 
    48 int _cache_req_notify (struct cache_req *req, enum cache_req_event event) {
    76 /*int _cache_req_notify (struct cache_req *req, enum cache_req_event event) { */
    49     if (req->cb_func(req, event, req->cb_arg)) {
    77 int _cache_req_notify (struct cache_req *req) {
       
    78     if (req->cb_func(req, req->cb_data)) {
    50         // XXX: handle errors
    79         // XXX: handle errors
    51         assert(0);
    80         assert(0);
    52     }
    81     }
    53     
    82     
    54     return 0;
    83     return 0;
    55 }
    84 }
    56 
    85 
    57 int cache_req_notify (struct cache_req *req) {
    86 int cache_req_notify (struct cache_req *req) {
       
    87 /*
    58     switch (req->op->state) {
    88     switch (req->op->state) {
    59         case OP_STATE_INVALID:
    89         case OP_STATE_INVALID:
    60         case OP_STATE_LOOKUP:
    90         case OP_STATE_LOOKUP:
    61             assert(0);
    91             assert(0);
    62 
    92 
    72             if (_cache_req_notify(req, CACHE_EVENT_MISS))
   102             if (_cache_req_notify(req, CACHE_EVENT_MISS))
    73                 goto error;
   103                 goto error;
    74             
   104             
    75             break;
   105             break;
    76         
   106         
       
   107         case OP_STATE_WRITE:
       
   108             if (_cache_req_notify(req, req->is_write ? CACHE_EVENT_BEGIN_WRITE : CACHE_EVENT_BEGIN_READ))
       
   109                 goto error;
       
   110 
       
   111             break;
       
   112 
    77         default:
   113         default:
    78             assert(0);
   114             assert(0);
    79 
   115 
    80             break;
   116             break;
    81     }
   117     }
    82 
   118 
    83     return 0;
   119     return 0;
    84 
   120 
    85 error:
   121 error:
    86     return -1;
   122     return -1;
       
   123 */
       
   124     
       
   125     return _cache_req_notify(req);
    87 }
   126 }
    88 
   127 
    89 enum cache_req_state cache_request_state (struct cache_req *req) {
   128 enum cache_req_state cache_req_state (struct cache_req *req) {
    90      switch (req->op->state) {
   129      switch (req->op->state) {
    91         case OP_STATE_INVALID:
   130         case OP_STATE_INVALID:
    92             return CACHE_STATE_INVALID;
   131             return CACHE_STATE_INVALID;
    93 
   132 
    94         case OP_STATE_LOOKUP:
   133         case OP_STATE_LOOKUP:
    95             return CACHE_STATE_LOOKUP;
   134             return CACHE_STATE_LOOKUP;
    96         
   135         
    97         case OP_STATE_HIT:
   136         case OP_STATE_HIT:
       
   137             return CACHE_STATE_READ_BEGIN;
       
   138 
    98         case OP_STATE_MISS:
   139         case OP_STATE_MISS:
    99             return CACHE_STATE_OPEN;
   140             return req->is_write ? CACHE_STATE_WRITE_BEGIN : CACHE_STATE_READ_BEGIN;
   100         
   141         
       
   142         case OP_STATE_WRITE:
       
   143             return req->is_write ? CACHE_STATE_WRITE : CACHE_STATE_READ;
       
   144 
   101         default:
   145         default:
   102             assert(0);
   146             assert(0);
   103     }
   147     }
   104 }
   148 }
   105 
   149 
       
   150 const struct cache_key *cache_req_key (struct cache_req *req) {
       
   151     return req->key;
       
   152 }
       
   153 
       
   154 int cache_req_begin_write(struct cache_req *req, size_t hint) {
       
   155     if (req->op->state != OP_STATE_MISS || !req->is_write)
       
   156         ERROR("req not in pre-write mode");
       
   157 
       
   158     return cache_op_begin_write(req->op, hint);
       
   159 
       
   160 error:
       
   161     return -1;
       
   162 }
       
   163 
       
   164 int cache_req_push (struct cache_req *req, int fd, size_t *size) {
       
   165     if (req->op->state != OP_STATE_WRITE || !req->is_write)
       
   166         ERROR("req not in write mode");
       
   167     
       
   168     return cache_op_push(req->op, fd, size); 
       
   169 
       
   170 error:
       
   171     return -1;
       
   172 }
       
   173