Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit 97bda2534a712a596da9cdd3bb6fb3ba75f9d4c2 0 parents
@tj tj authored
Showing with 291 additions and 0 deletions.
  1. +2 −0  .gitignore
  2. +9 −0 Makefile
  3. +179 −0 hash.c
  4. +97 −0 hash.h
  5. +4 −0 package.conf
2  .gitignore
@@ -0,0 +1,2 @@
+deps
+test
9 Makefile
@@ -0,0 +1,9 @@
+
+test: hash.c
+ @$(CC) -std=c99 -DTEST_HASH $^ -o $@
+ @./test
+
+clean:
+ rm -f test
+
+.PHONY: test clean
179 hash.c
@@ -0,0 +1,179 @@
+
+//
+// hash.c
+//
+// Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
+//
+
+#include "hash.h"
+
+/*
+ * Set hash `key` to `val`.
+ */
+
+inline void
+hash_set(hash_t *self, char *key, void *val) {
+ int ret;
+ khiter_t k = kh_put(ptr, self, key, &ret);
+ kh_value(self, k) = val;
+}
+
+/*
+ * Get hash `key`, or NULL.
+ */
+
+inline void *
+hash_get(hash_t *self, char *key) {
+ khiter_t k = kh_get(ptr, self, key);
+ return k == kh_end(self) ? NULL : kh_value(self, k);
+}
+
+/*
+ * Check if hash `key` exists.
+ */
+
+inline int
+hash_has(hash_t *self, char *key) {
+ khiter_t k = kh_get(ptr, self, key);
+ return kh_exist(self, k);
+}
+
+/*
+ * Remove hash `key`.
+ */
+
+void
+hash_remove(hash_t *self, char *key) {
+ khiter_t k = kh_get(ptr, self, key);
+ kh_del(ptr, self, k);
+}
+
+// tests
+
+#ifdef TEST_HASH
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+void
+test_hash_set() {
+ hash_t *hash = hash_new();
+ assert(0 == hash_size(hash));
+
+ hash_set(hash, "name", "tobi");
+ hash_set(hash, "species", "ferret");
+ assert(2 == hash_size(hash));
+
+ assert(0 == strcmp("tobi", hash_get(hash, "name")));
+ assert(0 == strcmp("ferret", hash_get(hash, "species")));
+}
+
+void
+test_hash_get() {
+ hash_t *hash = hash_new();
+ hash_set(hash, "foo", "bar");
+ assert(0 == strcmp("bar", hash_get(hash, "foo")));
+ assert(NULL == hash_get(hash, "bar"));
+}
+
+void
+test_hash_has() {
+ hash_t *hash = hash_new();
+ hash_set(hash, "foo", "bar");
+ assert(1 == hash_has(hash, "foo"));
+ assert(0 == hash_has(hash, "bar"));
+}
+
+void
+test_hash_size() {
+ hash_t *hash = hash_new();
+ assert(0 == hash_size(hash));
+ hash_set(hash, "foo", "bar");
+ assert(1 == hash_size(hash));
+ hash_set(hash, "bar", "baz");
+ assert(2 == hash_size(hash));
+}
+
+void
+test_hash_remove() {
+ hash_t *hash = hash_new();
+ hash_set(hash, "foo", "bar");
+ assert(1 == hash_has(hash, "foo"));
+ assert(0 == hash_has(hash, "bar"));
+ hash_remove(hash, "foo");
+ hash_remove(hash, "bar");
+ assert(0 == hash_has(hash, "foo"));
+}
+
+void
+test_hash_each() {
+ hash_t *hash = hash_new();
+ hash_set(hash, "name", "tj");
+ hash_set(hash, "age", "25");
+
+ const char *keys[2];
+ void *vals[2];
+ int n = 0;
+
+ hash_each(hash, {
+ keys[n] = key;
+ vals[n] = val;
+ n++;
+ });
+
+ assert(0 == strcmp("age", keys[0]));
+ assert(0 == strcmp("name", keys[1]));
+ assert(0 == strcmp("25", vals[0]));
+ assert(0 == strcmp("tj", vals[1]));
+}
+
+void
+test_hash_each_key() {
+ hash_t *hash = hash_new();
+ hash_set(hash, "name", "tj");
+ hash_set(hash, "age", "25");
+
+ const char *keys[2];
+ int n = 0;
+
+ hash_each_key(hash, {
+ keys[n++] = key;
+ });
+
+ assert(0 == strcmp("age", keys[0]));
+ assert(0 == strcmp("name", keys[1]));
+}
+
+void
+test_hash_each_val() {
+ hash_t *hash = hash_new();
+ hash_set(hash, "name", "tj");
+ hash_set(hash, "age", "25");
+
+ void *vals[2];
+ int n = 0;
+
+ hash_each_val(hash, {
+ vals[n++] = val;
+ });
+
+ assert(0 == strcmp("25", vals[0]));
+ assert(0 == strcmp("tj", vals[1]));
+}
+
+int
+main(){
+ test_hash_set();
+ test_hash_get();
+ test_hash_has();
+ test_hash_remove();
+ test_hash_size();
+ test_hash_each();
+ test_hash_each_key();
+ test_hash_each_val();
+ printf("\n \e[32m\u2713 \e[90mok\e[0m\n\n");
+ return 0;
+}
+
+#endif
97 hash.h
@@ -0,0 +1,97 @@
+
+//
+// hash.h
+//
+// Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
+//
+
+#ifndef HASH
+#define HASH
+
+#include "deps/khash/khash.h"
+
+// pointer hash
+
+KHASH_MAP_INIT_STR(ptr, void *);
+
+/*
+ * Hash type.
+ */
+
+typedef khash_t(ptr) hash_t;
+
+/*
+ * Allocate a new hash.
+ */
+
+#define hash_new() kh_init(ptr)
+
+/*
+ * Destroy the hash.
+ */
+
+#define hash_free(self) kh_destroy(ptr, self)
+
+/*
+ * Hash size.
+ */
+
+#define hash_size kh_size
+
+/*
+ * Iterate hash keys and ptrs, populating
+ * `key` and `val`.
+ */
+
+#define hash_each(self, block) { \
+ const char *key; \
+ void *val; \
+ for (khiter_t k = kh_begin(self); k < kh_end(self); ++k) { \
+ if (!kh_exist(self, k)) continue; \
+ key = kh_key(self, k); \
+ val = kh_value(self, k); \
+ block; \
+ } \
+ }
+
+/*
+ * Iterate hash keys, populating `key`.
+ */
+
+#define hash_each_key(self, block) { \
+ const char *key; \
+ for (khiter_t k = kh_begin(self); k < kh_end(self); ++k) { \
+ if (!kh_exist(self, k)) continue; \
+ key = kh_key(self, k); \
+ block; \
+ } \
+ }
+
+/*
+ * Iterate hash ptrs, populating `val`.
+ */
+
+#define hash_each_val(self, block) { \
+ void *val; \
+ for (khiter_t k = kh_begin(self); k < kh_end(self); ++k) { \
+ if (!kh_exist(self, k)) continue; \
+ val = kh_value(self, k); \
+ block; \
+ } \
+ }
+
+// protos
+
+void
+hash_set(hash_t *self, char *key, void *val);
+
+void *
+hash_get(hash_t *self, char *key);
+
+int
+hash_has(hash_t *self, char *key);
+
+void
+hash_remove(hash_t *self, char *key);
+
+#endif /* HASH */
4 package.conf
@@ -0,0 +1,4 @@
+name: hash
+version: 0.0.1
+description: Hash API built on khash
+dependencies: khash
Please sign in to comment.
Something went wrong with that request. Please try again.