cdb_make_put.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:2k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* "advanced" cdb_make_put routine
  2.  *
  3.  * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
  4.  * Public domain.
  5.  */
  6. #include "common/setup_before.h"
  7. #ifdef STDC_HEADERS
  8. # include <stdlib.h>
  9. #else
  10. # ifdef HAVE_MALLOC_H
  11. #  include <malloc.h>
  12. # endif
  13. #endif
  14. #include "cdb_int.h"
  15. #include "common/setup_after.h"
  16. int
  17. cdb_make_put(struct cdb_make *cdbmp,
  18.      const void *key, unsigned klen,
  19.      const void *val, unsigned vlen,
  20.      int flags)
  21. {
  22.   unsigned char rlen[8];
  23.   unsigned hval = cdb_hash(key, klen);
  24.   struct cdb_rl *rl;
  25.   int c, r;
  26.   switch(flags) {
  27.     case CDB_PUT_REPLACE:
  28.     case CDB_PUT_INSERT:
  29.     case CDB_PUT_WARN:
  30.       c = _cdb_make_find(cdbmp, key, klen, hval, &rl);
  31.       if (c < 0)
  32. return -1;
  33.       if (c) {
  34. if (flags == CDB_PUT_INSERT)
  35.   return errno = EEXIST, 1;
  36. else if (flags == CDB_PUT_REPLACE) {
  37.   --c;
  38.   r = 1;
  39.   break;
  40. }
  41. else
  42.   r = 1;
  43.       }
  44.       /* fall */
  45.     case CDB_PUT_ADD:
  46.       rl = cdbmp->cdb_rec[hval&255];
  47.       if (!rl || rl->cnt >= sizeof(rl->rec)/sizeof(rl->rec[0])) {
  48.   rl = (struct cdb_rl*)malloc(sizeof(struct cdb_rl));
  49. if (!rl)
  50.   return errno = ENOMEM, -1;
  51. rl->cnt = 0;
  52. rl->next = cdbmp->cdb_rec[hval&255];
  53. cdbmp->cdb_rec[hval&255] = rl;
  54.       }
  55.       c = rl->cnt;
  56.       r = 0;
  57.       break;
  58.     default:
  59.       return errno = EINVAL, -1;
  60.   }
  61.   if (klen > 0xffffffff - (cdbmp->cdb_dpos + 8) ||
  62.       vlen > 0xffffffff - (cdbmp->cdb_dpos + klen + 8))
  63.     return errno = ENOMEM, -1;
  64.   rl->rec[c].hval = hval;
  65.   rl->rec[c].rpos = cdbmp->cdb_dpos;
  66.   if ((unsigned)c == rl->cnt) {
  67.     ++rl->cnt;
  68.     ++cdbmp->cdb_rcnt;
  69.   }
  70.   cdb_pack(klen, rlen);
  71.   cdb_pack(vlen, rlen + 4);
  72.   if (_cdb_make_write(cdbmp, rlen, 8) < 0 ||
  73.       _cdb_make_write(cdbmp, key, klen) < 0 ||
  74.       _cdb_make_write(cdbmp, val, vlen) < 0)
  75.     return -1;
  76.   return r;
  77. }