Chinaunix首页 | 论坛 | 博客
  • 博客访问: 192008
  • 博文数量: 27
  • 博客积分: 725
  • 博客等级: 上士
  • 技术积分: 347
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-04 09:01
文章分类

全部博文(27)

文章存档

2012年(15)

2011年(12)

分类: C/C++

2012-03-27 19:11:26

不知道算不算是存储引擎,当时是因为要处理很多种类型数据的读写,所以觉得底层的存储细节太繁琐了,干脆自己写了一个文件存储接口屏蔽这些繁琐的细节,而可以更专心地考虑上层的逻辑设计。因为年代久远,代码风格不太好,略显稚嫩了,请大家多多包涵。

  1. #ifndef STORE_ENGINE_H_INCLUDED
  2. #define STORE_ENGINE_H_INCLUDED

  3. typedef void * database_handle;
  4. typedef void * database_iterator;

  5. database_handle    database_open(const char *filepath);
  6.     
  7. int    database_register_type(database_handle, const char *tpname);

  8. database_iterator    database_iterator_init        (database_handle, const char *tpname);
  9. database_iterator    database_iterator_head        (database_iterator);
  10. database_iterator    database_iterator_next        (database_iterator);
  11. database_iterator    database_iterator_prev        (database_iterator);
  12. database_iterator    database_iterator_tail        (database_iterator);

  13. #define database_write_ptr(handle, tpname, ptr)    \
  14.     database_write(handle, tpname, ptr, sizeof *(ptr))

  15. int    database_write    (database_handle, const char *tpname, void *ptr, int size);
  16. int    database_read     (database_handle, database_iterator , void *ptr, int *size);
  17. int database_delete    (database_handle, database_iterator);

  18. int    database_close(database_handle);


  19. void show_handle(FILE *fp, database_handle handle);

  20. void show_database(const char *filepath);

  21. #endif // STORE_ENGINE_H_INCLUDED


  1. #include "c.h"
  2. #include "list.h"
  3. #include "memmgr2.h"
  4. #include "store_engine.h"

  5. #define DISABLE_MSG

  6. #define DEBUG1
  7. #include "debug.h"

  8. #define PAGE_SIZE_MASK    12
  9. #define PAGE_SIZE (1 << PAGE_SIZE_MASK)
  10. #define MIN_BLKSZ_MASK    5
  11. #define MIN_BLOCK_SIZE (1 << MIN_BLKSZ_MASK)

  12. #define MAX_BLOCK_SIZE PAGE_SIZE
  13. #define MAX_NAME_LEN     32

  14. ///////////////////////////////////////////////////////////////////////////////
  15. ///////////////////////////////////////////////////////////////////////////////
  16. struct type_object {
  17.     char tpname[MAX_NAME_LEN];
  18. };
  19. typedef struct type_object tp_obj_t;
  20. #define tpobj_size    (sizeof(tp_obj_t))

  21. struct page_object {
  22.     int        szid;
  23.     int        pgid;
  24. };
  25. typedef struct page_object pg_obj_t;
  26. #define pgobj_size    (sizeof(pg_obj_t))

  27. struct data_object {
  28.     int        tpid;
  29.     int        size;
  30. };
  31. typedef struct data_object dat_obj_t;
  32. #define datobj_size    (sizeof(dat_obj_t))

  33. #define TPOBJ_ARRLEN 8

  34. struct engine_object {
  35.     int        pgcnt;
  36.     struct type_object    tpobj[TPOBJ_ARRLEN];
  37. };
  38. typedef struct engine_object eng_obj_t;
  39. #define engobj_size    (sizeof(eng_obj_t))
  40. ///////////////////////////////////////////////////////////////////////////////
  41. ///////////////////////////////////////////////////////////////////////////////
  42. #define FREOBJ_ARRLEN    8
  43. struct engine{
  44.     struct    engine_object    object;
  45.     FILE                    *fpos;
  46.     int                        tpcnt;
  47.     int                        datcnt;
  48.     struct    list_head        pghead;
  49.     struct    list_head        freelist[FREOBJ_ARRLEN];
  50.     struct    type            *tp[TPOBJ_ARRLEN];
  51. };
  52. typedef struct engine engine_t;

  53. struct type {
  54.     struct    type_object    object;
  55.     struct     engine        *engine;
  56.     struct    list_head        dathead;
  57.     char                     *tpname;
  58.     int                        tpid;
  59.     int                        datcnt;
  60. };
  61. typedef struct type type_t;

  62. struct page {
  63.     struct    page_object    object;
  64.     struct     engine        *engine;
  65.     struct list_head    list;
  66.     struct data        **data_array;
  67.     int                    blksize;
  68.     int                    blkcnt;
  69.     int                    datcnt;

  70. };
  71. typedef struct page page_t;

  72. struct data {
  73.     struct    data_object        object;
  74.     struct     type            *type;
  75.     struct    page            *page;
  76.     struct    list_head        list;
  77.     long                    seek;
  78.     int                        index;
  79. };
  80. typedef struct data data_t;
  81. ///////////////////////////////////////////////////////////////////////////////
  82. ///////////////////////////////////////////////////////////////////////////////
  83. static inline int size_to_index(int size)
  84. {
  85.     static char array[] = {
  86.         0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
  87.         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  88.         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  89.         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  90.         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  91.         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  92.         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  93.         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  94.     };
  95.     int k = ((size + MIN_BLOCK_SIZE - 1) >> MIN_BLKSZ_MASK) - 1;
  96.     return *(array + k);
  97. }

  98. static inline int index_to_size(int index)
  99. {
  100.     return 32 << index;
  101. }

  102. static inline int page_blk_cnt(int szid)
  103. {
  104.     return ((PAGE_SIZE >> MIN_BLKSZ_MASK) >> szid) - 1;
  105. }

  106. static int page_blk_size(int szid)
  107. {
  108.     return index_to_size(szid);
  109. }

  110. static inline int blk_offset(int szid, int index)
  111. {
  112.     return sizeof(pg_obj_t) + page_blk_size(szid) * index;
  113. }

  114. static inline int dat_offset(int szid, int index)
  115. {
  116.     return blk_offset(szid, index) + sizeof(dat_obj_t);
  117. }

  118. static inline int phy_page_start(int pgid)
  119. {
  120.     return pgid << PAGE_SIZE_MASK;
  121. }

  122. static inline char *mem_blk_start(char *pgbuf, int szid, int index)
  123. {
  124.     return pgbuf + blk_offset(szid, index);
  125. }

  126. static inline char *mem_dat_start(char *pgbuf, int szid, int index)
  127. {
  128.     return pgbuf + dat_offset(szid, index);
  129. }

  130. static inline long phy_dat_start(int pgid, int szid, int index)
  131. {
  132.     return phy_page_start(pgid) + dat_offset(szid, index);
  133. }

  134. static inline long phy_blk_start(int pgid, int szid, int index)
  135. {
  136.     return phy_page_start(pgid) + blk_offset(szid, index);
  137. }

  138. ///////////////////////////////////////////////////////////////////////////////////////
  139. ///////////////////////////////////////////////////////////////////////////////////////
  140. #define fcntl_read_pointer(fp, seek, ptr) \
  141.     fcntl_read(fp, seek, ptr, sizeof *(ptr))

  142. #define fcntl_write_pointer(fp, seek, ptr) \
  143.     fcntl_write(fp, seek, ptr, sizeof *(ptr))
  144.     
  145. static void fcntl_read(FILE *fp, long seek, void *ptr, int size)
  146. {
  147.     rewind(fp);
  148.     Bzero(ptr, size);
  149.     fseek(fp, seek, SEEK_SET);
  150.     fread(ptr, size, 1, fp);
  151. }

  152. static void fcntl_write(FILE *fp, long seek, void *ptr, int size)
  153. {
  154.     rewind(fp);
  155.     fseek(fp, seek, SEEK_SET);
  156.     fwrite(ptr, size, 1, fp);
  157. }

  158. static FILE * file_create(const char *filepath)
  159. {
  160.     return_val_if_fail(filepath != NULL,
  161.         NULL, "Filepath null");
  162.     FILE *fp = fopen(filepath, "wb+");
  163.     return_val_if_fail(fp != NULL, NULL,
  164.         "Create file failed: %s", filepath);
  165.     return fp;
  166. }

  167. static struct engine * engine_new(void)
  168. {
  169.     struct engine *engine = NEWP(engine);
  170.     return_val_if_fail(engine != NULL, NULL,
  171.         "Engine alloc failed");
  172.     LIST_HEAD_INIT(engine, pghead);
  173.     int i;
  174.     for (i = 0; i < FREOBJ_ARRLEN; i++)
  175.         init_list_head(engine->freelist + i);
  176.     return engine;
  177. }

  178. static struct engine * database_create(const char *filepath)
  179. {
  180.     FILE *fpos = file_create(filepath);
  181.     return_val_if_fail(fpos != NULL, NULL,
  182.         "Create file failed: %s", filepath);
  183.     struct engine *engine = engine_new();
  184.     return_val_if_fail(engine != NULL, NULL,
  185.         "Engine alloc failed");
  186.     engine->fpos = fpos;
  187.     return engine;
  188. }

  189. static struct type *type_new(void)
  190. {
  191.     struct type *tp = NEWP(tp);
  192.     return_val_if_fail(tp != NULL,
  193.         NULL, "Type alloc failed");
  194.     LIST_HEAD_INIT(tp, dathead);
  195.     return tp;
  196. }

  197. static int database_type_initialize(struct engine *engine)
  198. {
  199.     return_val_if_fail(engine != NULL, -1,
  200.         "Engine pointer null");
  201.     int i;
  202.     struct type_object *tpobj = engine->object.tpobj;
  203.     for (i = 0; i < TPOBJ_ARRLEN; i++) {
  204.         if (strlen(tpobj[i].tpname) <= 0) break;
  205.         struct type *tp = type_new();
  206.         return_val_if_fail(tp != NULL, -1, "Type alloc failed");
  207.         tp->tpid = engine->tpcnt;
  208.         engine->tp[tp->tpid] = tp;
  209.         engine->tpcnt++;
  210.         tp->engine = engine;
  211.         tp->tpname = tp->object.tpname;
  212.         strcpy(tp->tpname, tpobj[i].tpname);
  213.     }
  214.     return 0;
  215. }

  216. static struct data *data_new(void)
  217. {
  218.     struct data * dat = NEWP(dat);
  219.     return_val_if_fail(dat != NULL,
  220.         NULL, "Data alloc failed");
  221.     LIST_HEAD_INIT(dat, list);
  222.     return dat;
  223. }

  224. static int database_data_initialize(struct page *page, char *pgbuf)
  225. {
  226.     return_val_if_fail(page != NULL, -1);
  227.     return_val_if_fail(pgbuf != NULL, -1);
  228.     int i;
  229.     struct engine * engine = page->engine;
  230.     int szid = page->object.szid;
  231.     for (i = 0; i < page->blkcnt; i++) {
  232.         struct data_object * datobj =
  233.             (dat_obj_t *)mem_blk_start(
  234.                 pgbuf, szid, i
  235.             );
  236.         struct data * data = data_new();
  237.         return_val_if_fail(data != NULL,
  238.             -1, "Data alloc failed");
  239.         data->object.tpid = datobj->tpid;
  240.         data->object.size = datobj->size;
  241.         data->page = page;
  242.         data->index = i;
  243.         data->seek = phy_dat_start(
  244.             page->object.pgid, page->object.szid, i
  245.         );
  246.         if (datobj->size == 0) {
  247.             list_add_tail(&data->list, engine->freelist + szid);
  248.             continue;
  249.         }

  250.         int tpid = datobj->tpid;
  251.         return_val_if_fail(tpid >=0 && tpid < TPOBJ_ARRLEN,
  252.             -1, "type id invalid: %d", tpid);
  253.         data->type = engine->tp[tpid];
  254.         list_add_tail(&data->list, &data->type->dathead);
  255.         data->type->datcnt++;

  256.         page->datcnt++;
  257.         engine->datcnt++;
  258.         page->data_array[i] = data;
  259.     }
  260.     return 0;
  261. }

  262. static struct page * page_new(int szidx)
  263. {
  264.     int blkcnt = page_blk_cnt(szidx);
  265.     int alloc_size = blkcnt * sizeof(struct data *);
  266.     alloc_size += sizeof(struct page);
  267.     struct page *page = NEW(alloc_size);
  268.     return_val_if_fail(page != NULL,
  269.         NULL, "Alloc page failed");
  270.     page->data_array = (struct data**)(page + 1);
  271.        return page;
  272. }

  273. static int database_page_initialize(struct engine *engine)
  274. {
  275.     return_val_if_fail(engine != NULL, -1,
  276.         "Engine pointer null");
  277.     int i;
  278.     for (i = 1; i <= engine->object.pgcnt; i++) {
  279.         char pgbuf[PAGE_SIZE];
  280.         fcntl_read(engine->fpos, phy_page_start(i), pgbuf, PAGE_SIZE);
  281.         struct page_object *pgobj = (pg_obj_t *)pgbuf;

  282.         int szid = pgobj->szid;
  283.         int pgid = pgobj->pgid;
  284.         return_val_if_fail(pgid == i, -1,
  285.             "Invalid param: not match");
  286.         int blkcnt = page_blk_cnt(szid);
  287.         struct page * page = page_new(szid);
  288.         return_val_if_fail(page != NULL, -1,
  289.             "Page alloc failed");

  290.         page->engine = engine;
  291.         page->blkcnt = blkcnt;

  292.         page->object.szid = pgobj->szid;
  293.         page->object.pgid = pgobj->pgid;
  294.         page->blksize = index_to_size(szid);

  295.         list_add_tail(&page->list, &engine->pghead);

  296.         return_val_if_fail(page->object.pgid == i,
  297.             -1, "Invalid Param");

  298.         database_data_initialize(page, pgbuf);
  299. //        Show_Value(page->datcnt, d);
  300.     }
  301.     
  302.     return 0;
  303. }

  304. static struct engine * database_initialize(FILE *fp)
  305. {
  306.     return_val_if_fail(fp != NULL,
  307.         NULL, "File pointer null");
  308.     struct engine * engine = engine_new();
  309.     return_val_if_fail(engine != NULL,
  310.         NULL, "Engine alloc failed");
  311.     engine->fpos = fp;
  312.     fcntl_read_pointer(fp, 0, &engine->object);
  313.     int ret = database_type_initialize(engine);
  314.     debug_if_fail(ret != -1) {
  315.         FREE(engine);
  316.         return NULL;
  317.     }
  318.     database_page_initialize(engine);
  319.     return engine;
  320. }

  321. static struct engine * _database_open(const char *filepath)
  322. {
  323.     FILE *fp = fopen(filepath, "rb+");
  324.     if (fp == NULL)
  325.         return database_create(filepath);
  326.     return database_initialize(fp);
  327. }

  328. static int tpname_to_tpid(struct engine *engine, const char *tpname)
  329. {
  330.     return_val_if_fail(engine != NULL, -1);
  331.     return_val_if_fail(tpname != NULL, -1);
  332.     return_val_if_fail(strlen(tpname) < MAX_NAME_LEN,
  333.         -1, "Type name too long: %s", tpname);
  334.     int i;
  335.     for (i = 0; i < engine->tpcnt; i++) {
  336.         return_val_if_fail(engine->tp[i] != NULL, -1);
  337.         if (strcmp(engine->tp[i]->tpname, tpname) == 0)
  338.             return i;
  339.     }
  340.     return -1;
  341. }

  342. static struct type * tpname_to_tpptr(struct engine *engine, const char *tpname)
  343. {
  344.     return_val_if_fail(engine != NULL, NULL);
  345.     return_val_if_fail(tpname != NULL, NULL);
  346.     return_val_if_fail(strlen(tpname) < MAX_NAME_LEN,
  347.         NULL, "Type name too long: %s", tpname);
  348.     int tpid = tpname_to_tpid(engine, tpname);
  349.     return tpid != -1 ? engine->tp[tpid] : NULL;
  350. }
  351. ///////////////////////////////////////////////////////////////////////////////////////
  352. ///////////////////////////////////////////////////////////////////////////////////////
  353. static inline struct data * list_entry_data(struct list_head *list)
  354. {
  355.     return list ? list_entry(list, struct data *, list) : NULL;
  356. }

  357. static inline struct page * list_entry_page(struct list_head *list)
  358. {
  359.     return list ? list_entry(list, struct page *, list) : NULL;
  360. }

  361. static inline struct data * entry_data_head(struct list_head *head)
  362. {
  363.     if (head == NULL || list_empty_careful(head)) return NULL;
  364.     return list_entry_data(head->next);
  365. }

  366. static inline struct data * entry_data_tail(struct list_head *head)
  367. {
  368.     if (head == NULL || list_empty_careful(head)) return NULL;
  369.     return list_entry_data(head->prev);
  370. }

  371. static inline struct page * entry_page_tail(struct list_head *head)
  372. {
  373.     if (head == NULL || list_empty_careful(head)) return NULL;
  374.     return list_entry_page(head->prev);
  375. }

  376. static inline struct page *entry_page_head(struct list_head *head)
  377. {
  378.     if (head == NULL || list_empty_careful(head)) return NULL;
  379.     return list_entry_page(head->next);
  380. }

  381. static inline struct data *_entry_data_next(struct list_head *list)
  382. {
  383.     return list_entry_data(list->next);
  384. }

  385. static inline struct data *entry_data_next(struct data *data)
  386. {
  387.     return _entry_data_next(&data->list);
  388. }

  389. static inline struct data *_entry_data_prev(struct list_head *list)
  390. {
  391.     return list_entry_data(list->prev);
  392. }

  393. static inline struct data *entry_data_prev(struct data *data)
  394. {
  395.     return _entry_data_prev(&data->list);
  396. }

  397. static inline struct page *_entry_page_next(struct list_head *list)
  398. {
  399.     return list_entry_page(list->next);
  400. }

  401. static inline struct page *entry_page_next(struct page *page)
  402. {
  403.     return _entry_page_next(&page->list);
  404. }

  405. static inline struct page *_entry_page_prev(struct list_head *list)
  406. {
  407.     return list_entry_page(list->prev);
  408. }

  409. static inline struct page *entry_page_prev(struct page *page)
  410. {
  411.     return _entry_page_prev(&page->list);
  412. }
  413. ///////////////////////////////////////////////////////////////////////////////////////
  414. ///////////////////////////////////////////////////////////////////////////////////////
  415. struct data * _database_iterator_init(struct engine * engine, const char *tpname)
  416. {
  417.     int tpid = tpname_to_tpid(engine, tpname);
  418.     if (tpid == -1) return NULL;
  419.     return entry_data_head(&engine->tp[tpid]->dathead);
  420. }

  421. struct data * _database_iterator_head(struct data *iter)
  422. {
  423.     return_val_if_fail(iter != NULL, NULL, "Param iter null");
  424.     return entry_data_head(&iter->type->dathead);
  425. }

  426. struct data * _database_iterator_next(struct data *iter)
  427. {
  428.     return_val_if_fail(iter != NULL, NULL, "Param iter null");
  429.     return_val_if_fail(iter->type != NULL, NULL);
  430.     struct list_head *head = &iter->type->dathead;
  431.     if (iter->list.next == head) return NULL;
  432.     return entry_data_next(iter);
  433. }

  434. struct data *_database_iterator_prev(struct data *iter)
  435. {
  436.     return_val_if_fail(iter != NULL, NULL, "Param iter null");
  437.     return_val_if_fail(iter->type != NULL, NULL);
  438.     struct list_head *head = &iter->type->dathead;
  439.     if (iter->list.prev == head) return NULL;
  440.     return entry_data_prev(iter);
  441. }

  442. struct data * _database_iterator_tail(struct data *iter)
  443. {
  444.     return_val_if_fail(iter != NULL, NULL, "Param iter null");
  445.     return entry_data_tail(&iter->type->dathead);
  446. }
  447. ///////////////////////////////////////////////////////////////////////////////////////
  448. ///////////////////////////////////////////////////////////////////////////////////////
  449. static int _database_register_type(struct engine *engine, const char *tpname)
  450. {
  451.     return_val_if_fail(strlen(tpname) < MAX_NAME_LEN,
  452.         -1, "Type name too long: %s", tpname);
  453.     
  454.     /*
  455.      * return 0 means succedd even exist same type
  456.     */
  457.     int tpid = tpname_to_tpid(engine, tpname);
  458.     if (tpid != -1) return 0;
  459.     
  460.     return_val_if_fail(engine->tpcnt < TPOBJ_ARRLEN,
  461.         -1, "Type count reach upper limit");
  462.         
  463.     tpid = engine->tpcnt;
  464.     engine->tpcnt++;
  465.     struct type *tp = type_new();
  466.     return_val_if_fail(tp != NULL, -1,
  467.         "Type alloc failed");
  468.     tp->tpid = tpid;
  469.     tp->engine = engine;
  470.     strcpy(tp->object.tpname, tpname);
  471.     tp->tpname = tp->object.tpname;
  472.     engine->tp[tpid] = tp;
  473.     strcpy(engine->object.tpobj[tpid].tpname, tpname);
  474.     fcntl_write_pointer(engine->fpos, 0, &engine->object);
  475.     return 0;
  476. }

  477. static struct data * _get_free_space(struct engine *engine, int szidx)
  478. {
  479.     struct list_head * head = engine->freelist + szidx;
  480.     struct data *dat = entry_data_head(head);
  481.     if (dat == NULL) return dat;
  482.     list_del_init(&dat->list);
  483.     return dat;
  484. }

  485. static int database_add_new_page(struct engine *engine, int szid)
  486. {
  487.     return_val_if_fail(engine != NULL,
  488.         -1, "Engine null pointer");
  489.     return_val_if_fail(szid >= 0 &&
  490.         szid < FREOBJ_ARRLEN, -1);
  491.     struct page *page = page_new(szid);
  492.     return_val_if_fail(page != NULL,
  493.         -1, "Alloc page failed");
  494.     list_add_tail(&page->list, &engine->pghead);
  495.     engine->object.pgcnt++;
  496.     page->object.szid = szid;
  497.     page->object.pgid = engine->object.pgcnt;
  498.     page->engine = engine;
  499.     page->blksize = index_to_size(szid);
  500.     page->blkcnt = page_blk_cnt(szid);
  501.     int i;
  502.     for (i = 0; i < page->blkcnt; i++) {
  503.         struct data *data = data_new();
  504.         page->data_array[i] = data;
  505.         page->data_array[i]->page = page;
  506.         page->data_array[i]->index = i;
  507.         int pgid = page->object.pgid;
  508.         int szid = page->object.szid;
  509.         page->data_array[i]->seek = phy_dat_start(pgid, szid, i);
  510.         list_add_tail(&data->list, engine->freelist + szid);
  511.     }
  512.     long pgseek = phy_page_start(page->object.pgid);
  513.     fcntl_write_pointer(engine->fpos, pgseek, &page->object);
  514.     fcntl_write_pointer(engine->fpos, 0, &engine->object);
  515.     return 0;
  516. }

  517. static struct data * get_free_space(struct engine *engine, int totalsize)
  518. {
  519.     return_val_if_fail(engine != NULL,
  520.         NULL, "Engine null pointer");
  521.     return_val_if_fail(totalsize > 0, NULL,
  522.         "Invalid totalsize: %d", totalsize);
  523.     int szidx = size_to_index(totalsize);
  524.     return_val_if_fail(szidx >= 0 &&
  525.         szidx <FREOBJ_ARRLEN, NULL);
  526.     struct data *dat = _get_free_space(engine, szidx);
  527.     if (dat != NULL) return dat;
  528.     database_add_new_page(engine, szidx);
  529.     dat = _get_free_space(engine, szidx);
  530.     return_val_if_fail(dat != NULL, NULL,
  531.         "Get free space failed");
  532.     return dat;
  533. }

  534. static int _database_write(struct engine *engine, const char *tpname, void *ptr, int size)
  535. {
  536.     struct type *tp = tpname_to_tpptr(engine, tpname);
  537.     return_val_if_fail(tp != NULL,
  538.         -1, "Type not exist: %s", tpname);
  539.     int totalsize = size + datobj_size;
  540.     struct data * data = get_free_space(engine, totalsize);
  541.     return_val_if_fail(data != NULL, -1,
  542.         "Get free space failed: %d", totalsize);
  543.     data->type = tp;
  544.     list_add_tail(&data->list, &tp->dathead);
  545.     data->type->datcnt++;
  546.     data->page->datcnt++;
  547.     engine->datcnt++;
  548.     
  549.     data->object.tpid = tp->tpid;
  550.     data->object.size = size;
  551.     long blkseek = data->seek - sizeof(dat_obj_t);
  552.     fcntl_write_pointer(engine->fpos, blkseek, &data->object);
  553.     fcntl_write(engine->fpos, data->seek, ptr, size);
  554.     return 0;
  555. }

  556. static int _database_read(struct engine *engine, struct data * dat, void *ptr, int *psize)
  557. {
  558.     int realsize = dat->object.size;
  559.     if (realsize > *psize) {
  560.         *psize = realsize;
  561.         return_val_if_fail(realsize <= *psize,
  562.             -1, "Buffer pointer size %d < %d",
  563.             *psize, realsize);
  564.         assert(0);
  565.     }
  566.     fcntl_read(engine->fpos, dat->seek, ptr, realsize);
  567.     return 0;
  568. }

  569. static int _database_delete(struct engine *engine, struct data *dat)
  570. {
  571.     dat->object.tpid = 0;
  572.     dat->object.size = 0;
  573.     
  574.     long blkseek = dat->seek - datobj_size;
  575.     fcntl_write_pointer(engine->fpos, blkseek, &dat->object);
  576.     
  577.     list_del_init(&dat->list);
  578.     dat->type->datcnt--;
  579.     dat->page->datcnt--;
  580.     engine->datcnt--;
  581.     
  582.     dat->type = NULL;
  583.     
  584.     int szid = dat->page->object.szid;
  585.     struct list_head *head = engine->freelist + szid;
  586.     list_add_tail(&dat->list, head);
  587.     
  588.     return 0;
  589. }

  590. static int _database_close(struct engine *engine)
  591. {
  592.     fcntl_write_pointer(engine->fpos, 0, &engine->object);
  593.     fclose(engine->fpos);
  594.     return 0;
  595. }
  596. ///////////////////////////////////////////////////////////////////////////////////////
  597. ///////////////////////////////////////////////////////////////////////////////////////
  598. database_handle database_open(const char *filepath)
  599. {
  600.     return_val_if_fail(filepath != NULL, NULL, "Filepath Null");
  601.     atexit(memory_leaking_check);
  602.     return (database_handle)_database_open(filepath);
  603. }

  604. int    database_close(database_handle handle)
  605. {
  606.     return_val_if_fail(handle != NULL, -1, "Database handle null");
  607.     return _database_close((engine_t *)handle);
  608. }

  609. int    database_register_type(database_handle handle, const char *tpname)
  610. {
  611.     return_val_if_fail(handle != NULL, -1, "Database handle null");
  612.     return_val_if_fail(tpname != NULL, -1, "Typename null");
  613.     int ret = _database_register_type((engine_t *)handle, tpname);
  614.     msg(stdout, "\ndatabase register type: %s %s!!\n",
  615.         tpname, ret == 0 ? "success" : "failed");
  616.     return ret;
  617. }

  618. database_iterator database_iterator_init(database_handle handle, const char *tpname)
  619. {
  620.     return_val_if_fail(handle != NULL, NULL, "Database handle null");
  621.     return_val_if_fail(tpname != NULL, NULL, "Typename null");
  622.     return (database_iterator)_database_iterator_init((engine_t *)handle, tpname);
  623. }

  624. database_iterator database_iterator_head(database_iterator iterator)
  625. {
  626.     return_val_if_fail(iterator != NULL, NULL, "Database iterator null");
  627.     return (database_iterator)_database_iterator_head((data_t *)iterator);
  628. }

  629. database_iterator database_iterator_next(database_iterator iterator)
  630. {
  631.     return_val_if_fail(iterator != NULL, NULL, "Database iterator null");
  632.     return (database_iterator)_database_iterator_next((data_t *)iterator);
  633. }

  634. database_iterator database_iterator_prev(database_iterator iterator)
  635. {
  636.     return_val_if_fail(iterator != NULL, NULL, "Database iterator null");
  637.     return (database_iterator)_database_iterator_prev((data_t *)iterator);
  638. }

  639. database_iterator database_iterator_tail(database_iterator iterator)
  640. {
  641.     return_val_if_fail(iterator != NULL, NULL, "Database iterator null");
  642.     return (database_iterator)_database_iterator_tail((data_t *)iterator);
  643. }

  644. int    database_write(database_handle handle, const char *tpname, void *ptr, int size)
  645. {
  646.     return_val_if_fail(handle != NULL, -1, "Database handle null");
  647.     return_val_if_fail(tpname != NULL, -1, "Typename null");
  648.     return_val_if_fail(ptr != NULL, -1, "Buffer pointer null");
  649.     return_val_if_fail(size > 0, -1, "Buffer size invalid: %d", size);
  650.     return _database_write((engine_t *)handle, tpname, ptr, size);
  651. }

  652. int    database_read(database_handle handle, database_iterator iterator, void *ptr, int *psize)
  653. {
  654.     return_val_if_fail(handle != NULL, -1, "Database handle null");
  655.     return_val_if_fail(iterator != NULL, -1, "Database iterator null");
  656.     return_val_if_fail(ptr != NULL, -1, "Buffer pointer null");
  657.     return_val_if_fail(psize != NULL && *psize > 0, -1, "Buffer size invalid: %d", *psize);
  658.     return _database_read((engine_t *)handle, (data_t *)iterator, ptr, psize);
  659. }

  660. int database_delete(database_handle handle, database_iterator iterator)
  661. {
  662.     return_val_if_fail(handle != NULL, -1, "Database handle null");
  663.     return_val_if_fail(iterator != NULL, -1, "Database iterator null");
  664.     return _database_delete((engine_t *)handle, (data_t *)iterator);
  665. }
  666. ///////////////////////////////////////////////////////////////////////////////////////
  667. ///////////////////////////////////////////////////////////////////////////////////////
  668. static void show_data(FILE *fp, struct engine *engine)
  669. {
  670.     return_if_fail(fp != NULL);
  671.     return_if_fail(engine != NULL);
  672.     struct page *page;
  673.     int i;
  674.     list_for_each_entry(page, &engine->pghead, list){
  675.         for (i = 0; i < page->blkcnt; i++) {
  676.             struct data *data = page->data_array[i];
  677.             if (data != NULL) {
  678.                 msg(fp, "\n\nshow data: %p", data);
  679.                 msg(fp, "\ntype id: %d", data->object.tpid);
  680.                 msg(fp, "\ndata size: %d", data->object.size);
  681.                 msg(fp, "\ntype pointer: %p", data->type);
  682.                 msg(fp, "\npage pointer: %p", data->page);
  683.                 msg(fp, "\ndata seek: %ld", data->seek);
  684.             }
  685.         }
  686.     }
  687.     msg(fp, "\n");
  688. }

  689. static void show_type(FILE *fp, struct engine *engine)
  690. {
  691.     return_if_fail(fp != NULL);
  692.     return_if_fail(engine != NULL);
  693.     int i;
  694.     for (i = 0; i < TPOBJ_ARRLEN; i++) {
  695.         if (engine->tp[i] == NULL) break;
  696.         struct type *type = engine->tp[i];
  697.         msg(fp, "\n\nshow type %d: %p", i, type);
  698.         msg(fp, "\ntype name: %s", type->object.tpname);
  699.         return_if_fail(type->tpname == type->object.tpname);
  700.         msg(fp, "\nengine: %p", type->engine);
  701.         msg(fp, "\ntype id: %d", type->tpid);
  702.         msg(fp, "\ndata count: %d", type->datcnt);
  703.         struct data *data;
  704.         int k = 1;
  705.         list_for_each_entry(data, &type->dathead, list) {
  706.             if (k++ % 5 == 1)
  707.                 msg(fp, "\ndata list: ");
  708.             msg(fp, "%p\t", data);
  709.         }
  710.     }
  711.     msg(fp, "\n");
  712. }

  713. static void show_page(FILE *fp, struct engine *engine)
  714. {
  715.     return_if_fail(fp != NULL);
  716.     return_if_fail(engine != NULL);
  717.     struct page *page;
  718.     list_for_each_entry(page, &engine->pghead, list) {
  719.         msg(fp, "\nshow page %d: %p", page->object.pgid, page);
  720.         msg(fp, "\npage size idx: %d", page->object.szid);
  721.         msg(fp, "\nengine: %p", page->engine);
  722.         msg(fp, "\nbulk size: %d", page->blksize);
  723.         msg(fp, "\nbulk count: %d", page->blkcnt);
  724.         msg(fp, "\ndata count: %d", page->datcnt);
  725.         int i, k = 1;
  726.         for (i = 0; i < page->blkcnt; i++) {
  727.             if (page->data_array[i] != NULL) {
  728.                 if (k++ % 5 == 1)
  729.                     msg(fp, "\nshow data: ");
  730.                 msg(fp, "%p\t", page->data_array[i]);
  731.             }
  732.         }
  733.     }
  734.     msg(fp, "\n");
  735. }

  736. static void show_engine(FILE *fp, struct engine *engine)
  737. {
  738.     return_if_fail(fp != NULL);
  739.     return_if_fail(engine != NULL);
  740.     
  741.     msg(fp, "engine object: %p", engine);
  742.     msg(fp, "\npage count: %d", engine->object.pgcnt);
  743.     int i, k = 1;
  744.     for(i = 0; i < TPOBJ_ARRLEN; i++)
  745.         msg(fp, "\ntype name %d: %s", i, engine->object.tpobj[i].tpname);
  746.     
  747.     struct page *page;
  748.     list_for_each_entry(page, &engine->pghead, list){
  749.         if (k++ % 5 == 1)
  750.             msg(fp, "\nengine page:");
  751.         msg(fp, "%p\t", page);
  752.     }
  753.     
  754.     for (i = 0; i < FREOBJ_ARRLEN; i++) {
  755.         struct data *data;
  756.         k = 1;
  757.         int j = 0;
  758.         list_for_each_entry(data, engine->freelist + i, list) {
  759.             if (k++ % 5 == 1)
  760.                 msg(fp, "\nengine freelist %d - %d\t: ", i, j++);
  761.             msg(fp, "%p\t", data);
  762.         }
  763.     }
  764.     
  765.     k = 1;
  766.     for (i = 0; i < TPOBJ_ARRLEN; i++) {
  767.         if (k++ % 5 == 1)
  768.             msg(fp, "\nengine type: ");
  769.         msg(fp, "%p\t", engine->tp[i]);
  770.     }
  771.     
  772.     msg(fp, "\nengine fpos: %p", engine->fpos);
  773.     msg(fp, "\nengine type count: %d", engine->tpcnt);
  774.     msg(fp, "\nengine data count: %d", engine->datcnt);
  775.     msg(fp, "\n");
  776. }

  777. void show_handle(FILE *fp, database_handle handle)
  778. {
  779.     msg(fp,"\n\n\n");
  780.     show_engine(fp, (struct engine *)handle);
  781.     show_type(fp, (struct engine *)handle);
  782.     show_page(fp, (struct engine *)handle);
  783.     show_data(fp, (struct engine *)handle);
  784. }

  785. void show_pagebuf(char *pgbuf)
  786. {
  787.     int *p = (int*)pgbuf;
  788.     char *end = pgbuf + PAGE_SIZE;
  789.     int k = 1;
  790.     printf("\n\n");
  791.     while ((char*)p - end < 0) {
  792.         printf("%x\t", *p++);
  793.         if (k++ % 8 == 0) printf("\n");
  794.     }
  795.     printf("\n\n");
  796. }

  797. void show_database(const char *filepath)
  798. {
  799.     FILE *fp = fopen(filepath, "rb");
  800.     return_if_fail(fp != NULL, "database open failed");
  801.     struct engine_object engine;
  802.     fcntl_read_pointer(fp, 0, &engine);
  803.     msg(stdout, "\npgcnt    : %d", engine.pgcnt);
  804.     int i;
  805.     struct type_object *tpobj = engine.tpobj;
  806.     for (i = 0; strlen(tpobj[i].tpname) > 0; i++) {
  807.         msg(stdout, "\ntype %d: %s", i, tpobj[i].tpname);
  808.     }
  809.     msg(stdout, "\n\n");
  810.     char pgbuf[PAGE_SIZE];
  811.     for (i = 1; i <= engine.pgcnt; i++) {
  812.         memset(pgbuf, 0, PAGE_SIZE);
  813.         fcntl_read(fp, phy_page_start(i), pgbuf, PAGE_SIZE);
  814. //        show_pagebuf(pgbuf);
  815.         struct page_object *pgobj = (pg_obj_t *)pgbuf;
  816.         msg(stdout, "\npage : szid = %d, pgid = %d", pgobj->szid, pgobj->pgid);
  817.         int j;
  818.         for (j = 0; j < page_blk_cnt(pgobj->szid); j++) {
  819.             struct data_object *datobj = (dat_obj_t *)mem_blk_start(pgbuf, pgobj->szid, j);
  820.             msg(stdout, "\ndata %d : tpid = %x, size = %x", j, datobj->tpid, datobj->size);
  821.         }
  822.     }
  823.     
  824.     msg(stdout, "\n\n");
  825.     fclose(fp);
  826. }

阅读(1777) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~