Permalink
Browse files

Trying to speed things up with C.

This commit is very much a work in progress.  The C has memory leaks and
there really isn't a good build process around this, seeing how
cmockery and pcre pull from macports and nothing more universal.
  • Loading branch information...
1 parent 1c1ae21 commit 3de92bbe170060103793050525a28ef60086f20d @pope pope committed Oct 11, 2009
View
@@ -0,0 +1 @@
+*.pbxproj -crlf -diff -merge
View
@@ -0,0 +1,4 @@
+# xcode noise
+ext/version_sorter/build/*
+*.pbxuser
+*.mode1v3
@@ -0,0 +1,120 @@
+/*
+ * hash.c
+ * version_sorter
+ *
+ * Created by K. Adam Christensen on 10/10/09.
+ * Copyright 2009. All rights reserved.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "utils.h"
+#include "hash.h"
+
+/* The SDBM hash */
+static unsigned int
+str_hash(const char *str)
+{
+ unsigned int hash = 0;
+ int c;
+
+ while ((c = *str++)) {
+ hash = c + (hash << 6) + (hash << 16) - hash;
+ }
+ return hash;
+}
+
+HashTable *
+hash_init(unsigned int size)
+{
+ HashTable *ht = malloc(sizeof(HashTable));
+ if (ht == NULL) {
+ DIE("ERROR: Not enough memory to allocate HashTable")
+ }
+
+ /* The capacity should be 20% larger than the size. I am using this int
+ * because I want small numbers to have a larger size by at least 1
+ */
+ unsigned int capacity = ceil(size * 1.2);
+ /* The capacity needs to be even */
+ if ((capacity % 2) == 1) {
+ capacity++;
+ }
+
+ ht->capacity = capacity;
+ ht->size = 0;
+
+ ht->table = calloc(capacity, sizeof(HashTableItem *));
+ if (ht->table == NULL) {
+ DIE("ERROR: Not enough memory to allocate HashTable lookup")
+ }
+
+ return ht;
+}
+
+void
+hash_free(HashTable *ht)
+{
+ HashTableItem *cur, *next;
+ int i;
+
+ for (i = 0; i < ht->capacity; i++) {
+ cur = ht->table[i];
+ while (cur) {
+ next = cur->next;
+ free(cur);
+ cur = next;
+ }
+ }
+ free(ht->table);
+ free(ht);
+}
+
+void *
+hash_get(HashTable * ht, const char *key)
+{
+ unsigned int index = str_hash(key) % (ht->capacity - 1);
+ HashTableItem *cur;
+ cur = ht->table[index];
+ while (cur) {
+ if ((strcmp(key, cur->key)) == 0) {
+ return cur->item;
+ }
+ cur = cur->next;
+ }
+
+ return NULL;
+}
+
+void
+hash_put(HashTable *ht, const char *key, void * item)
+{
+ unsigned int index = str_hash(key) % (ht->capacity - 1);
+ HashTableItem *entry = malloc(sizeof(HashTableItem));
+ if (entry == NULL) {
+ DIE("ERROR: Not enough memory to allocate HashTableItem")
+ }
+ entry->key = key;
+ entry->item = item;
+ entry->next = ht->table[index];
+ ht->table[index] = entry;
+}
+
+void
+hash_foreach(HashTable *ht, hash_iter_cb block, void *state)
+{
+ HashTableItem *cur, *next;
+ int i;
+
+ for (i = 0; i < ht->capacity; i++) {
+ cur = ht->table[i];
+ while (cur) {
+ next = cur->next;
+ block(cur->key, cur->item, state);
+ cur = next;
+ }
+ }
+}
@@ -0,0 +1,33 @@
+/*
+ * hash.h
+ * version_sorter
+ *
+ * Created by K. Adam Christensen on 10/10/09.
+ * Copyright 2009. All rights reserved.
+ *
+ */
+
+#ifndef _HASH_H
+#define _HASH_H
+
+typedef struct _HashTable {
+ unsigned int capacity;
+ unsigned int size;
+ struct _HashTableItem **table;
+} HashTable;
+
+typedef struct _HashTableItem {
+ const char *key;
+ void *item;
+ struct _HashTableItem *next;
+} HashTableItem;
+
+typedef void (*hash_iter_cb)(const char *, void *, void *);
+
+extern HashTable * hash_init(unsigned int);
+extern void hash_free(HashTable *);
+extern void * hash_get(HashTable *, const char*);
+extern void hash_put(HashTable *, const char *, void *);
+extern void hash_foreach(HashTable *, hash_iter_cb, void *);
+
+#endif /* _HASH_H */
@@ -0,0 +1,65 @@
+/*
+ * string.c
+ * version_sorter
+ *
+ * Created by K. Adam Christensen on 10/10/09.
+ * Copyright 2009. All rights reserved.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "strings.h"
+#include "utils.h"
+
+int
+string_cmp(const void *a, const void *b)
+{
+ return strcmp(*(const char **)a, *(const char **)b);
+}
+
+StringLinkedList *
+string_linked_list_init(void)
+{
+ StringLinkedList *sll = malloc(sizeof(StringLinkedList));
+ if (sll == NULL) {
+ DIE("ERROR: Not enough memory to allocate StringLinkedList")
+ }
+ sll->head = NULL;
+ sll->tail = NULL;
+ sll->len = 0;
+
+ return sll;
+}
+
+void
+string_linked_list_free(StringLinkedList *sll)
+{
+ StringLinkedListNode *cur;
+ while (cur = sll->head) {
+ sll->head = cur->next;
+ free(cur->str);
+ free(cur);
+ }
+ free(sll);
+}
+
+void
+string_linked_list_append(StringLinkedList *sll, char *str)
+{
+ StringLinkedListNode *slln = malloc(sizeof(StringLinkedListNode));
+ if (slln == NULL) {
+ DIE("ERROR: Not enough memory to allocate string linked list node")
+ }
+ slln->str = str;
+ slln->next = NULL;
+
+ if (sll->head == NULL) {
+ sll->head = slln;
+ sll->tail = slln;
+ } else {
+ sll->tail->next = slln;
+ sll->tail = slln;
+ }
+ sll->len++;
+}
@@ -0,0 +1,30 @@
+/*
+ * string.h
+ * version_sorter
+ *
+ * Created by K. Adam Christensen on 10/10/09.
+ * Copyright 2009. All rights reserved.
+ *
+ */
+
+#ifndef _STRING_H
+#define _STRING_H
+
+typedef struct _StringLinkedList {
+ struct _StringLinkedListNode *head;
+ struct _StringLinkedListNode *tail;
+ int len;
+} StringLinkedList;
+
+typedef struct _StringLinkedListNode {
+ char *str;
+ struct _StringLinkedListNode *next;
+} StringLinkedListNode;
+
+extern int string_cmp(const void *, const void *);
+
+extern StringLinkedList * string_linked_list_init(void);
+extern void string_linked_list_free(StringLinkedList *);
+extern void string_linked_list_append(StringLinkedList *, char *);
+
+#endif /* _STRING_H */
@@ -0,0 +1,44 @@
+/*
+ * hash_test.c
+ * version_sorter
+ *
+ * Created by K. Adam Christensen on 10/10/09.
+ * Copyright 2009. All rights reserved.
+ *
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include "cmockery.h"
+
+#include <assert.h>
+#include <string.h>
+#include "hash.h"
+
+
+static void
+foreach_test_callback(const char *key, void *item, void *state)
+{
+ int * count_p = (int *) state;
+ *count_p = *count_p + 1;
+}
+
+void
+test_hashtable(void **state)
+{
+ HashTable *ht = hash_init(2);
+
+ hash_put(ht, "hello", "HELLO");
+ hash_put(ht, "world", "WORLD");
+
+ assert((strcmp("HELLO", (char *) hash_get(ht, "hello"))) == 0);
+ assert((strcmp("WORLD", (char *) hash_get(ht, "world"))) == 0);
+
+ /* Make sure the foreach works and that I can count the objects */
+ int count = 0;
+ hash_foreach(ht, &foreach_test_callback, (void *) (&count));
+ assert(count == 2);
+
+ hash_free(ht);
+}
@@ -0,0 +1,15 @@
+/*
+ * hash_test.h
+ * version_sorter
+ *
+ * Created by K. Adam Christensen on 10/10/09.
+ * Copyright 2009. All rights reserved.
+ *
+ */
+
+#ifndef _HASH_TEST_H
+#define _HASH_TEST_H
+
+void test_hashtable(void **);
+
+#endif /* _HASH_TEST_H */
Oops, something went wrong.
@@ -0,0 +1,25 @@
+/*
+ * utils.h
+ * version_sorter
+ *
+ * Created by K. Adam Christensen on 10/10/09.
+ * Copyright 2009. All rights reserved.
+ *
+ */
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DIE(msg) \
+ fprintf(stderr, msg);\
+ exit(EXIT_FAILURE);\
+
+#define ARRAY_LENGH(x) \
+ (sizeof(x)/sizeof(x[0]))
+
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+#endif /* _UTILS_H */
Oops, something went wrong.

0 comments on commit 3de92bb

Please sign in to comment.