Prechádzať zdrojové kódy

[map.h] Adding map header only lib

Vinicius Teshima 2 rokov pred
rodič
commit
28e1295904
1 zmenil súbory, kde vykonal 149 pridanie a 0 odobranie
  1. 149 0
      include/toolbox/map.h

+ 149 - 0
include/toolbox/map.h

@@ -0,0 +1,149 @@
+#ifndef MAP_H
+#define MAP_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifndef MAP_MAX_SIZE
+#define MAP_MAX_SIZE 5000
+#endif /* MAP_MAX_SIZE */
+
+struct map_item {
+	void *data;
+	size_t size;
+	const uint64_t hkey;
+	struct map_item *hit;
+};
+
+struct map {
+	/* uint64_t *hkeys; */
+	struct map_item *items;
+	size_t size;
+};
+
+struct map* map_create();
+
+__attribute__((access (read_write, 1), access (read_only, 2),
+	       access (read_only, 3), nonnull))
+void map_add(struct map *__restrict__ map, const char *__restrict__ key,
+	     void *__restrict__ data, size_t size);
+
+__attribute__((access (read_write, 1), access (read_only, 3), nonnull))
+void map_add_h(struct map *__restrict__ map, uint64_t hkey,
+	       void *__restrict__ data, size_t size);
+
+__attribute__((access (read_only, 1), access (read_only, 2), nonnull))
+void* map_get(struct map const *__restrict__ map, const char *__restrict__ key);
+__attribute__((access (read_only, 1), nonnull))
+void* map_get_h(struct map const *__restrict__ map, uint64_t hkey);
+
+__attribute__((access (read_only, 1), access (read_only, 2), nonnull))
+struct map_item* map_get_item(struct map const *__restrict__ map,
+			      const char *__restrict__ key);
+
+__attribute__((access (read_only, 1), nonnull))
+struct map_item* map_get_item_h(struct map const *__restrict__ map,
+				uint64_t hkey);
+
+__attribute__((access (read_write, 1), nonnull))
+void map_destroy(struct map *map);
+
+#define MAP_IMP
+#if defined(MAP_IMP) || defined(IMPLEMENTATIONS)
+
+#define HASH_IMP
+#include "./hash.h"
+#undef HASH_IMP
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct map* map_create() {
+	/* NOTE: Should probraly do something more here */
+	struct map *ret = calloc(1, sizeof(struct map));
+	if ( ret == NULL ) {
+		fprintf(stderr, "[ERROR] Failed to calloc: map_create\n");
+		exit(EXIT_FAILURE);
+	}
+	ret->items = calloc(MAP_MAX_SIZE, sizeof(struct map_item));
+	if ( ret->items == NULL ) {
+		fprintf(stderr, "[ERROR] Failed to calloc: map_create\n");
+		exit(EXIT_FAILURE);
+	}
+	return ret;
+}
+
+void map_add(struct map *__restrict__ map, const char *__restrict__ key,
+	     void *__restrict__ data, size_t size) {
+	map_add_h(map, hash(key, strlen(key)), data, size);
+}
+
+void map_add_h(struct map *__restrict__ map, uint64_t hkey,
+	       void *__restrict__ data, size_t size) {
+	struct map_item *pitem = &map->items[hkey % MAP_MAX_SIZE];
+
+	while ( pitem->data != NULL ) {
+		if ( pitem->hit == NULL ) {
+			pitem->hit = calloc(1, sizeof(struct map_item));
+			if ( pitem->hit == NULL ) {
+				fprintf(stderr, "[ERROR] Failed to calloc: map_add\n");
+				exit(EXIT_FAILURE);
+			}
+		}
+		pitem = pitem->hit;
+	}
+
+	pitem->data = calloc(1, size);
+	if ( pitem->data == NULL ) {
+		fprintf(stderr, "[ERROR] Failed to calloc: map_add\n");
+		exit(EXIT_FAILURE);
+	}
+
+	pitem->size = size;
+	memcpy(pitem->data, data, size);
+
+	/* const kkkkkk */
+	*(uint64_t*) &pitem->hkey = hkey;
+}
+
+void* map_get(struct map const *__restrict__ map,
+	      const char *__restrict__ key) {
+	return map_get_h(map, hash(key, strlen(key)));
+}
+void* map_get_h(struct map const *__restrict__ map, uint64_t hkey) {
+	struct map_item *pitem = map_get_item_h(map, hkey);
+	if ( pitem == NULL ) {
+		return NULL;
+	}
+
+	return pitem->data;
+}
+
+struct map_item* map_get_item(struct map const *__restrict__ map,
+			      const char *__restrict__ key) {
+	return map_get_item_h(map, hash(key, strlen(key)));
+}
+
+struct map_item* map_get_item_h(struct map const *__restrict__ map,
+				uint64_t hkey) {
+	struct map_item *pitem = &map->items[hkey % MAP_MAX_SIZE];
+
+	while ( pitem->hkey != hkey) {
+		if ( pitem->hit == NULL ) {
+			return NULL;
+		}
+
+		pitem = pitem->hit;
+	}
+
+	return pitem;
+}
+
+void map_destroy(struct map *map) {
+	(void) map;
+}
+
+#endif /* MAP_IMP || IMPLEMENTATIONS */
+
+#endif /* MAP_H */