Permalink
Browse files

add map and test

  • Loading branch information...
1 parent 86d6058 commit 3c5524fa2613dffe1920f42550d878d3112ef888 @cloudwu committed Apr 15, 2011
Showing with 355 additions and 9 deletions.
  1. +1 −0 Makefile
  2. +3 −1 mk/build.mk
  3. +1 −1 mk/build_init.mk
  4. +30 −0 mk/build_test.mk
  5. +1 −0 mk/clean.mk
  6. +2 −0 mk/defines.mk
  7. +7 −3 src/core/atom.c
  8. +3 −1 src/core/atom.h
  9. +235 −0 src/core/map.c
  10. +26 −0 src/core/map.h
  11. +0 −3 src/core/memory.c
  12. +46 −0 src/test/map.c
View
1 Makefile
@@ -7,6 +7,7 @@ else
include mk/clean.mk
else
include mk/build.mk
+ include mk/build_test.mk
include mk/mkdir.mk
endif
endif
View
4 mk/build.mk
@@ -4,12 +4,14 @@ all :
LIBSRCS := \
src/core/memory.c \
- src/core/atom.c
+ src/core/atom.c \
+ src/core/map.c
include mk/build_o.mk
include mk/build_init.mk
LIBTAR := libwindsoul.a
include mk/build_a.mk
+
View
2 mk/build_init.mk
@@ -1,6 +1,6 @@
MKDIRS := $(MKDIRS) $(BUILD_TOOLS)
-GENINIT := $(BUILD_TOOLS)/geninit.exe
+GENINIT := $(BUILD_TOOLS)/geninit$(EXE)
$(GENINIT) : | $(BUILD_TOOLS)
$(GENINIT) : build_tools/geninit.c
View
30 mk/build_test.mk
@@ -0,0 +1,30 @@
+.PHONY : test
+
+test :
+
+TESTSRCS := \
+ src/test/map.c
+
+INC := src/core
+INC := $(addprefix -I,$(INC))
+
+MKDIRS := $(MKDIRS) $(BUILD_TOP)/test $(TEST_DIR)
+
+define TEST_temp
+ TAR_O := $(BUILD_TOP)/test/$(notdir $(basename $(1)))
+ $$(TAR_O).o : | $(BUILD_TOP)/test
+ -include $$(TAR).d
+ $$(TAR_O).o : $(1)
+ $(CC) -c -o $$@ $(CFLAGS) $(INC) -MMD $$<
+ TAR_EXE := $(TEST_DIR)/$(notdir $(basename $(1)))$(EXE)
+ test : $$(TAR_EXE)
+ $$(TAR_EXE) : | $(TEST_DIR)
+ $$(TAR_EXE) : $$(TAR_O).o $(LIBTAR)
+ $(CC) -o $$@ $(LDFLAGS) $$(TAR_O).o -L$(LIB_DIR) -lwindsoul
+endef
+
+$(foreach s,$(TESTSRCS),$(eval $(call TEST_temp,$(s))))
+
+
+
+
View
1 mk/clean.mk
@@ -2,3 +2,4 @@ clean :
-$(RMDIR) $(BUILD_TOP)
-$(RMDIR) $(BUILD_TOOLS)
-$(RMDIR) $(LIB_DIR)
+ -$(RMDIR) $(TEST_DIR)
View
2 mk/defines.mk
@@ -1,6 +1,7 @@
BUILD_TOP := $(WINDSOUL)/build
LIB_DIR := $(WINDSOUL)/lib
BUILD_TOOLS := $(WINDSOUL)/build_tools
+TEST_DIR := $(WINDSOUL)/test
CC := gcc
AR := ar rc
@@ -9,6 +10,7 @@ RMDIR := rm -r -f
MKDIR := mkdir -p
DEBUG ?= -g -O0
TOUCH := touch
+EXE ?=.exe
ifeq ($(filter -g,$(DEBUG)),-g)
LDFLAGS := -g -Wall
View
10 src/core/atom.c
@@ -192,9 +192,13 @@ atomBuildSep(const char *str,const char *sep,size_t *outlen)
{
size_t len=0;
const char *tmp=str;
- while (*tmp!='\0' && !strchr(sep,*tmp)) {
- ++tmp;
- ++len;
+ if (sep[0] == '\0') {
+ len = strlen(str);
+ } else {
+ while (*tmp!='\0' && !strchr(sep,*tmp)) {
+ ++tmp;
+ ++len;
+ }
}
if (outlen) {
*outlen = len;
View
4 src/core/atom.h
@@ -10,7 +10,9 @@ atom atomBuild(const void *data, size_t sz);
atom atomBuildSep(const char *str, const char *sep, size_t *len);
size_t atomLength(atom);
-#define atomString(a) ((const char *)(a))
+#define atomLiteral(s) atomBuild("" s, (sizeof(s)/sizeof(char))-1)
+#define atomString(s) atomBuildSep(s,"",NULL)
+#define atomToString(a) ((const char *)(a))
#endif
View
235 src/core/map.c
@@ -0,0 +1,235 @@
+#include "memory.h"
+#include "map.h"
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+
+struct key;
+struct value;
+
+#define KEY(op) ((struct key *)((op)->key.p))
+#define VALUE(op) ((struct value *)((op)->value))
+
+struct node {
+ struct value *value;
+ struct key *key;
+ struct node *next;
+};
+
+struct map {
+ int freenode;
+ int size;
+ struct node* buffer;
+};
+
+static inline void
+init_table(struct map *m)
+{
+ memset(m->buffer,0,m->size*sizeof(struct node));
+}
+
+struct map*
+mapCreate(void)
+{
+ struct map *m=(struct map*)memoryAlloc(sizeof(struct map));
+ m->size=2;
+ m->freenode=0;
+ m->buffer=(struct node*)memoryAlloc(sizeof(struct node)*m->size);
+ init_table(m);
+
+ return m;
+}
+
+void
+mapRelease(struct map *m)
+{
+ if (m) {
+ memoryFree(m->buffer);
+ memoryFree(m);
+ }
+}
+
+static inline size_t
+hash(struct map *m,struct key *key)
+{
+ intptr_t k=(intptr_t)key;
+ return (size_t)(((k>>3)^k)&(m->size-1));
+}
+
+static struct node*
+map_find(struct map *m,struct key *key)
+{
+ size_t k=hash(m,key);
+ struct node *temp=m->buffer+k;
+ do {
+ if (temp->key==key)
+ return temp;
+ temp=temp->next;
+ } while (temp);
+ return 0;
+}
+
+static struct node *
+map_begin(struct map *m)
+{
+ int i;
+ for (i=0;i<m->size;i++) {
+ if (m->buffer[i].value!=0) {
+ return &(m->buffer[i]);
+ }
+ }
+ return 0;
+}
+
+static struct node *
+map_next(struct map *m,struct node *next)
+{
+ for (;;) {
+ ++next;
+ if (next-m->buffer>=m->size) {
+ return 0;
+ }
+ else if (next->value!=0) {
+ return next;
+ }
+ }
+}
+
+static struct node *
+expand_search(struct map *m,struct key *key);
+
+static struct node *
+map_search(struct map *m,struct key *key)
+{
+ int i;
+ size_t k=hash(m,key);
+ struct node *temp=m->buffer+k;
+ for (;;) {
+ if (temp->value==0) {
+ struct node *slot=temp;
+ temp=temp->next;
+ while (temp) {
+ if (temp->key==key) {
+ return temp;
+ }
+ temp=temp->next;
+ }
+ slot->key=key;
+ return slot;
+ }
+ else if (temp->key==key)
+ return temp;
+ if (temp->next==0) {
+ break;
+ }
+ temp=temp->next;
+ }
+ for (i=m->freenode;i<m->size;i++) {
+ if (m->buffer[i].value==0) {
+ m->buffer[i].key=key;
+ temp->next=m->buffer+i;
+ m->freenode=i+1;
+ return &(m->buffer[i]);
+ }
+ }
+
+ return expand_search(m,key);
+}
+
+static struct node *
+expand_search(struct map *m,struct key *key)
+{
+ int i;
+ int s=m->size;
+ struct node *old=m->buffer;
+
+ struct node *buffer=(struct node*)memoryAlloc(m->size*2*sizeof(struct node));
+ if (buffer==0) {
+ return 0;
+ }
+
+ m->size*=2;
+ m->freenode=0;
+ m->buffer=buffer;
+ init_table(m);
+
+ for (i=0;i<s;i++) {
+ if (old[i].value!=0) {
+ map_search(m,old[i].key)->value = old[i].value;
+ }
+ }
+
+ memoryFree(old);
+
+ return map_search(m,key);
+}
+
+static void *
+_findfirst(struct map *m, struct map_op * op)
+{
+ struct node *v = map_begin(m);
+ op->value = v;
+ if (v == NULL) {
+ op->key.p = NULL;
+ return NULL;
+ }
+ else {
+ op->key.p = v->key;
+ }
+ return v->value;
+}
+
+static void *
+_findnext(struct map *m, struct map_op * op)
+{
+ if (op->value == NULL) {
+ return _findfirst(m,op);
+ }
+ struct node *v = map_next(m, op->value);
+ op->value = v;
+ if (v == NULL) {
+ op->key.p = NULL;
+ return NULL;
+ }
+ else {
+ op->key.p = v->key;
+ }
+ return v->value;
+}
+
+void *
+mapSearch(struct map * m,struct map_op * op)
+{
+ switch (op->op) {
+ case MAP_SEARCH: {
+ struct node *n = map_find(m,KEY(op));
+ if (n==NULL) {
+ return NULL;
+ } else {
+ return n->value;
+ }
+ }
+ case MAP_INSERT: {
+ struct node *v = map_search(m, KEY(op));
+ void * ret = v->value;
+ v->value = op->value;
+ return ret;
+ }
+ case MAP_REMOVE: {
+ struct node *n = map_find(m,KEY(op));
+ if (n==NULL) {
+ return NULL;
+ } else {
+ void *ret = n->value;
+ n->value = NULL;
+ return ret;
+ }
+ }
+ case MAP_ITERATOR: {
+ return _findnext((struct map *)m, op);
+ }
+ default:
+ return NULL;
+ };
+}
View
26 src/core/map.h
@@ -0,0 +1,26 @@
+#ifndef windsoul_map_h
+#define windsoul_map_h
+
+#include <stdint.h>
+
+struct map;
+
+#define MAP_SEARCH 0
+#define MAP_INSERT 1
+#define MAP_REMOVE 2
+#define MAP_ITERATOR 3
+
+struct map_op {
+ int op;
+ union {
+ uintptr_t i;
+ void *p;
+ } key;
+ void * value;
+};
+
+struct map * mapCreate(void);
+void mapRelease(struct map *);
+void* mapSearch(struct map *, struct map_op * op);
+
+#endif
View
3 src/core/memory.c
@@ -3,8 +3,6 @@
#include "memory.h"
-void *fooBar();
-
void *
memoryAlloc(size_t size)
{
@@ -14,7 +12,6 @@ memoryAlloc(size_t size)
void
memoryFree(void *p)
{
- fooBar();
free(p);
}
View
46 src/test/map.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include "map.h"
+#include "atom.h"
+
+int _mapInit(void);
+int _atomInit(void);
+
+static void
+insert(struct map *m, const char *key, const char *value)
+{
+ struct map_op op;
+ op.op = MAP_INSERT;
+ op.key.p = atomString(key);
+ op.value = atomString(value);
+ mapSearch(m,&op);
+}
+
+static void
+test()
+{
+ struct map *m = mapCreate();
+ insert(m,"1st","Hello");
+ insert(m,"2nd","World");
+
+ struct map_op op;
+ op.op = MAP_ITERATOR;
+ op.value = NULL;
+
+ const char *v =NULL;
+ while ((v=mapSearch(m,&op))!=NULL) {
+ printf("%s : %s\n",(const char *)(op.key.p),v);
+ }
+
+ mapRelease(m);
+}
+
+int
+main()
+{
+ if (_mapInit()) return 1;
+ if (_atomInit()) return 1;
+
+ test();
+
+ return 0;
+}

0 comments on commit 3c5524f

Please sign in to comment.