--- /dev/null
+/*
+ * resindexhash.c
+ *
+ * Copyright (c) 2010 project bchan
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+#include "resindexhash.h"
+
+#include <bstdio.h>
+#include <bstdlib.h>
+#include <bsys/queue.h>
+
+#ifdef BCHAN_CONFIG_DEBUG
+# define DP(arg) printf arg
+# define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
+#else
+# define DP(arg) /**/
+# define DP_ER(msg, err) /**/
+#endif
+
+LOCAL resindexhash_node_t* resindexhash_node_new(W index, UW attr, COLOR color)
+{
+ resindexhash_node_t *node;
+
+ node = (resindexhash_node_t*)malloc(sizeof(resindexhash_node_t));
+ if (node == NULL) {
+ return NULL;
+ }
+
+ QueInit(&(node->queue));
+ node->index = index;
+ node->attr = attr;
+ node->color = color;
+
+ return node;
+}
+
+LOCAL VOID resindexhash_node_delete(resindexhash_node_t *hashnode)
+{
+ QueRemove(&(hashnode->queue));
+ free(hashnode);
+}
+
+LOCAL W resindexhash_calchashvalue(W index)
+{
+ return index % RESINDEXHASH_BASE;
+}
+
+LOCAL resindexhash_node_t* resindexhash_searchnode(resindexhash_t *resindexhash, W index)
+{
+ W hashval;
+ resindexhash_node_t *node, *buf;
+
+ if (resindexhash->datanum == 0) {
+ return NULL;
+ }
+
+ hashval = resindexhash_calchashvalue(index);
+ buf = resindexhash->tbl + hashval;
+
+ for (node = (resindexhash_node_t *)buf->queue.next; node != buf; node = (resindexhash_node_t *)node->queue.next) {
+ if (node->index == index) {
+ return node;
+ }
+ }
+
+ return NULL;
+}
+
+EXPORT W resindexhash_adddata(resindexhash_t *resindexhash, W index, UW attr, COLOR color)
+{
+ resindexhash_node_t *hashnode, *buf;
+ W hashval;
+
+ hashnode = resindexhash_searchnode(resindexhash, index);
+ if (hashnode != NULL) {
+ hashnode->attr = attr;
+ hashnode->color = color;
+ return 0;
+ }
+
+ hashval = resindexhash_calchashvalue(index);
+ buf = resindexhash->tbl + hashval;
+
+ hashnode = resindexhash_node_new(index, attr, color);
+ if (hashnode == NULL) {
+ return -1; /* TODO */
+ }
+
+ QueInsert(&(hashnode->queue), &(buf->queue));
+ resindexhash->datanum++;
+
+ return 0;
+}
+
+EXPORT W resindexhash_searchdata(resindexhash_t *resindexhash, W index, UW *attr, COLOR *color)
+{
+ resindexhash_node_t *hashnode;
+
+ hashnode = resindexhash_searchnode(resindexhash, index);
+ if (hashnode == NULL) {
+ return RESINDEXHASH_SEARCHDATA_NOTFOUND;
+ }
+
+ *attr = hashnode->attr;
+ *color = hashnode->color;
+ return RESINDEXHASH_SEARCHDATA_FOUND;
+}
+
+EXPORT VOID resindexhash_removedata(resindexhash_t *resindexhash, W index)
+{
+ resindexhash_node_t *hashnode;
+
+ hashnode = resindexhash_searchnode(resindexhash, index);
+ if (hashnode == NULL) {
+ return;
+ }
+ resindexhash_node_delete(hashnode);
+ resindexhash->datanum--;
+}
+
+EXPORT W resindexhash_datanum(resindexhash_t *resindexhash)
+{
+ return resindexhash->datanum;
+}
+
+EXPORT W resindexhash_initialize(resindexhash_t *resindexhash)
+{
+ W i;
+ for (i=0; i < RESINDEXHASH_BASE;i++) {
+ QueInit(&(resindexhash->tbl[i].queue));
+ }
+ return 0;
+}
+
+EXPORT VOID resindexhash_finalize(resindexhash_t *resindexhash)
+{
+ W i;
+ resindexhash_node_t *buf,*buf_next;
+ Bool empty;
+
+ for(i = 0; i < RESINDEXHASH_BASE; i++){
+ buf = resindexhash->tbl + i;
+ for(;;){
+ empty = isQueEmpty(&(buf->queue));
+ if (empty == True) {
+ break;
+ }
+ buf_next = (resindexhash_node_t*)buf->queue.next;
+ resindexhash_node_delete(buf_next);
+ }
+ }
+}
+
+EXPORT Bool resindexhash_iterator_next(resindexhash_iterator_t *iter, W *index, W *attr, W *color)
+{
+ resindexhash_t *hash;
+ resindexhash_node_t *node;
+
+ hash = iter->resindexhash;
+
+ if (iter->tbl_index == RESINDEXHASH_BASE) {
+ return False;
+ }
+
+ *index = iter->node->index;
+ *attr = iter->node->attr;
+ *color = iter->node->color;
+
+ for (;;) {
+ node = (resindexhash_node_t*)iter->node->queue.next;
+ if (hash->tbl + iter->tbl_index != node) {
+ iter->node = node;
+ break;
+ }
+ iter->tbl_index++;
+ if (iter->tbl_index == RESINDEXHASH_BASE) {
+ break;
+ }
+ iter->node = hash->tbl + iter->tbl_index;
+ }
+
+ return True;
+}
+
+EXPORT VOID resindexhash_iterator_initialize(resindexhash_iterator_t *iter, resindexhash_t *target)
+{
+ resindexhash_node_t *node;
+
+ iter->resindexhash = target;
+ iter->tbl_index = 0;
+ iter->node = (resindexhash_node_t*)iter->resindexhash->tbl;
+ for (;;) {
+ node = (resindexhash_node_t*)iter->node->queue.next;
+ if (iter->resindexhash->tbl + iter->tbl_index != node) {
+ iter->node = node;
+ break;
+ }
+ iter->tbl_index++;
+ if (iter->tbl_index == RESINDEXHASH_BASE) {
+ break;
+ }
+ iter->node = iter->resindexhash->tbl + iter->tbl_index;
+ }
+}
+
+EXPORT VOID resindexhash_iterator_finalize(resindexhash_iterator_t *iter)
+{
+}
--- /dev/null
+/*
+ * test_resindexhash.c
+ *
+ * Copyright (c) 2010 project bchan
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+#include <btron/btron.h>
+#include <bstdio.h>
+#include <bstring.h>
+
+#include "test.h"
+
+#include "resindexhash.h"
+
+LOCAL TEST_RESULT test_resindexhash_1()
+{
+ resindexhash_t resindexhash;
+ W ret;
+
+ ret = resindexhash_initialize(&resindexhash);
+ if (ret < 0) {
+ printf("resindexhash_initialize fail\n");
+ return TEST_RESULT_FAIL;
+ }
+ resindexhash_finalize(&resindexhash);
+
+ return TEST_RESULT_PASS;
+}
+
+LOCAL TEST_RESULT test_resindexhash_2()
+{
+ resindexhash_t resindexhash;
+ W index = 1;
+ W ret;
+ UW attr;
+ COLOR color;
+ TEST_RESULT result = TEST_RESULT_PASS;
+
+ ret = resindexhash_initialize(&resindexhash);
+ if (ret < 0) {
+ printf("resindexhash_initialize fail\n");
+ return TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_searchdata(&resindexhash, index, &attr, &color);
+ if (ret != RESINDEXHASH_SEARCHDATA_NOTFOUND) {
+ printf("resindexhash_searchdata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ resindexhash_finalize(&resindexhash);
+
+ return result;
+}
+
+LOCAL TEST_RESULT test_resindexhash_3()
+{
+ resindexhash_t resindexhash;
+ W index = 1;
+ W ret;
+ UW attr, attr1 = 0x01010101;
+ COLOR color, color1 = 0x10FF00FF;
+ TEST_RESULT result = TEST_RESULT_PASS;
+
+ ret = resindexhash_initialize(&resindexhash);
+ if (ret < 0) {
+ printf("resindexhash_initialize fail\n");
+ return TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_adddata(&resindexhash, index, attr1, color1);
+ if (ret < 0) {
+ printf("resindexhash_adddata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_searchdata(&resindexhash, index, &attr, &color);
+ if (ret != RESINDEXHASH_SEARCHDATA_FOUND) {
+ printf("resindexhash_searchdata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ if (attr != attr1) {
+ printf("resindexhash_searchdata result fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ if (color != color1) {
+ printf("resindexhash_searchdata result fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ resindexhash_finalize(&resindexhash);
+
+ return result;
+}
+
+LOCAL TEST_RESULT test_resindexhash_4()
+{
+ resindexhash_t resindexhash;
+ W index = 1;
+ W ret;
+ UW attr, attr1 = 0x01010101, attr2 = 0x10101010;
+ COLOR color, color1 = 0x10FF00FF, color2 = 0x1000FF00;
+ TEST_RESULT result = TEST_RESULT_PASS;
+
+ ret = resindexhash_initialize(&resindexhash);
+ if (ret < 0) {
+ printf("resindexhash_initialize fail\n");
+ return TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_adddata(&resindexhash, index, attr1, color1);
+ if (ret < 0) {
+ printf("resindexhash_adddata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_adddata(&resindexhash, index, attr2, color2);
+ if (ret < 0) {
+ printf("resindexhash_adddata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_searchdata(&resindexhash, index, &attr, &color);
+ if (ret != RESINDEXHASH_SEARCHDATA_FOUND) {
+ printf("resindexhash_searchdata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ if (attr != attr2) {
+ printf("resindexhash_searchdata result fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ if (color != color2) {
+ printf("resindexhash_searchdata result fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ resindexhash_finalize(&resindexhash);
+
+ return result;
+}
+
+LOCAL TEST_RESULT test_resindexhash_5()
+{
+ resindexhash_t resindexhash;
+ W index = 1;
+ W ret;
+ UW attr, attr1 = 0x01010101;
+ COLOR color, color1 = 0x10FF00FF;
+ TEST_RESULT result = TEST_RESULT_PASS;
+
+ ret = resindexhash_initialize(&resindexhash);
+ if (ret < 0) {
+ printf("resindexhash_initialize fail\n");
+ return TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_adddata(&resindexhash, index, attr1, color1);
+ if (ret < 0) {
+ printf("resindexhash_adddata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ resindexhash_removedata(&resindexhash, index);
+ ret = resindexhash_searchdata(&resindexhash, index, &attr, &color);
+ if (ret != RESINDEXHASH_SEARCHDATA_NOTFOUND) {
+ printf("resindexhash_searchdata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ resindexhash_finalize(&resindexhash);
+
+ return result;
+}
+
+LOCAL TEST_RESULT test_resindexhash_6()
+{
+ resindexhash_t resindexhash;
+ W index = 1;
+ W ret;
+ TEST_RESULT result = TEST_RESULT_PASS;
+
+ ret = resindexhash_initialize(&resindexhash);
+ if (ret < 0) {
+ printf("resindexhash_initialize fail\n");
+ return TEST_RESULT_FAIL;
+ }
+ resindexhash_removedata(&resindexhash, index);
+ resindexhash_finalize(&resindexhash);
+
+ return result;
+}
+
+LOCAL TEST_RESULT test_resindexhash_7()
+{
+ resindexhash_t resindexhash;
+ W index1 = 1, index2 = 34;
+ W ret;
+ UW attr, attr1 = 0x01010101, attr2 = 0x10101010;
+ COLOR color, color1 = 0x10FF00FF, color2 = 0x1000FF00;
+ TEST_RESULT result = TEST_RESULT_PASS;
+
+ ret = resindexhash_initialize(&resindexhash);
+ if (ret < 0) {
+ printf("resindexhash_initialize fail\n");
+ return TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_adddata(&resindexhash, index1, attr1, color1);
+ if (ret < 0) {
+ printf("resindexhash_adddata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_adddata(&resindexhash, index2, attr2, color2);
+ if (ret < 0) {
+ printf("resindexhash_adddata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_searchdata(&resindexhash, index1, &attr, &color);
+ if (ret != RESINDEXHASH_SEARCHDATA_FOUND) {
+ printf("resindexhash_searchdata 1 fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ if (attr != attr1) {
+ printf("resindexhash_searchdata 1 result fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ if (color != color1) {
+ printf("resindexhash_searchdata 1 result fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_searchdata(&resindexhash, index2, &attr, &color);
+ if (ret != RESINDEXHASH_SEARCHDATA_FOUND) {
+ printf("resindexhash_searchdata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ if (attr != attr2) {
+ printf("resindexhash_searchdata 2 result fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ if (color != color2) {
+ printf("resindexhash_searchdata 2 result fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ resindexhash_finalize(&resindexhash);
+
+ return result;
+}
+
+LOCAL TEST_RESULT test_resindexhash_8()
+{
+ resindexhash_t resindexhash;
+ resindexhash_iterator_t iterator;
+ W index;
+ W ret, num;
+ UW attr;
+ COLOR color;
+ Bool next;
+ TEST_RESULT result = TEST_RESULT_PASS;
+
+ ret = resindexhash_initialize(&resindexhash);
+ if (ret < 0) {
+ printf("resindexhash_initialize fail\n");
+ return TEST_RESULT_FAIL;
+ }
+
+
+ resindexhash_iterator_initialize(&iterator, &resindexhash);
+ num = 0;
+ for (;;) {
+ next = resindexhash_iterator_next(&iterator, &index, &attr, &color);
+ if (next == False) {
+ break;
+ }
+ num++;
+ }
+ if (num != 0) {
+ printf("resindexhash_iterator unexpected length\n");
+ result = TEST_RESULT_FAIL;
+ }
+ resindexhash_iterator_finalize(&iterator);
+
+
+ resindexhash_finalize(&resindexhash);
+
+ return result;
+}
+
+LOCAL TEST_RESULT test_resindexhash_9()
+{
+ resindexhash_t resindexhash;
+ resindexhash_iterator_t iterator;
+ W index, index1 = 1;
+ W ret, num;
+ UW attr, attr1 = 0x01010101;
+ COLOR color, color1 = 0x10FF00FF;
+ Bool next;
+ TEST_RESULT result = TEST_RESULT_PASS;
+
+ ret = resindexhash_initialize(&resindexhash);
+ if (ret < 0) {
+ printf("resindexhash_initialize fail\n");
+ return TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_adddata(&resindexhash, index1, attr1, color1);
+ if (ret < 0) {
+ printf("resindexhash_adddata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+
+
+ resindexhash_iterator_initialize(&iterator, &resindexhash);
+ num = 0;
+ for (;;) {
+ next = resindexhash_iterator_next(&iterator, &index, &attr, &color);
+ if (next == False) {
+ break;
+ }
+ num++;
+ if (index == index1) {
+ if (attr != attr1) {
+ result = TEST_RESULT_FAIL;
+ }
+ if (color != color1) {
+ result = TEST_RESULT_FAIL;
+ }
+ } else {
+ result = TEST_RESULT_FAIL;
+ }
+ }
+ if (num != 1) {
+ printf("resindexhash_iterator unexpected length\n");
+ result = TEST_RESULT_FAIL;
+ }
+ resindexhash_iterator_finalize(&iterator);
+
+
+ resindexhash_finalize(&resindexhash);
+
+ return result;
+}
+
+LOCAL TEST_RESULT test_resindexhash_10()
+{
+ resindexhash_t resindexhash;
+ resindexhash_iterator_t iterator;
+ W index1 = 1, index2 = 34;
+ W ret, num, index;
+ UW attr, attr1 = 0x01010101, attr2 = 0x10101010;
+ COLOR color, color1 = 0x10FF00FF, color2 = 0x1000FF00;
+ Bool next;
+ TEST_RESULT result = TEST_RESULT_PASS;
+
+ ret = resindexhash_initialize(&resindexhash);
+ if (ret < 0) {
+ printf("resindexhash_initialize fail\n");
+ return TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_adddata(&resindexhash, index1, attr1, color1);
+ if (ret < 0) {
+ printf("resindexhash_adddata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+ ret = resindexhash_adddata(&resindexhash, index2, attr2, color2);
+ if (ret < 0) {
+ printf("resindexhash_adddata fail\n");
+ result = TEST_RESULT_FAIL;
+ }
+
+
+ resindexhash_iterator_initialize(&iterator, &resindexhash);
+ num = 0;
+ for (;;) {
+ next = resindexhash_iterator_next(&iterator, &index, &attr, &color);
+ if (next == False) {
+ break;
+ }
+ num++;
+ if (index == index1) {
+ if (attr != attr1) {
+ result = TEST_RESULT_FAIL;
+ }
+ if (color != color1) {
+ result = TEST_RESULT_FAIL;
+ }
+ } else if (index == index2) {
+ if (attr != attr2) {
+ result = TEST_RESULT_FAIL;
+ }
+ if (color != color2) {
+ result = TEST_RESULT_FAIL;
+ }
+ } else {
+ result = TEST_RESULT_FAIL;
+ }
+ }
+ if (num != 2) {
+ printf("resindexhash_iterator unexpected length\n");
+ result = TEST_RESULT_FAIL;
+ }
+ resindexhash_iterator_finalize(&iterator);
+
+
+ resindexhash_finalize(&resindexhash);
+
+ return result;
+}
+
+LOCAL VOID test_resindexhash_printresult(TEST_RESULT (*proc)(), B *test_name)
+{
+ TEST_RESULT result;
+
+ printf("test_resindexhash: %s\n", test_name);
+ printf("---------------------------------------------\n");
+ result = proc();
+ if (result == TEST_RESULT_PASS) {
+ printf("--pass---------------------------------------\n");
+ } else {
+ printf("--fail---------------------------------------\n");
+ }
+ printf("---------------------------------------------\n");
+}
+
+EXPORT VOID test_resindexhash_main()
+{
+ test_resindexhash_printresult(test_resindexhash_1, "test_resindexhash_1");
+ test_resindexhash_printresult(test_resindexhash_2, "test_resindexhash_2");
+ test_resindexhash_printresult(test_resindexhash_3, "test_resindexhash_3");
+ test_resindexhash_printresult(test_resindexhash_4, "test_resindexhash_4");
+ test_resindexhash_printresult(test_resindexhash_5, "test_resindexhash_5");
+ test_resindexhash_printresult(test_resindexhash_6, "test_resindexhash_6");
+ test_resindexhash_printresult(test_resindexhash_7, "test_resindexhash_7");
+ test_resindexhash_printresult(test_resindexhash_8, "test_resindexhash_8");
+ test_resindexhash_printresult(test_resindexhash_9, "test_resindexhash_9");
+ test_resindexhash_printresult(test_resindexhash_10, "test_resindexhash_10");
+}