Skip to content

Instantly share code, notes, and snippets.

@jan-schreib
Last active February 8, 2017 19:38
Show Gist options
  • Save jan-schreib/9bd219fe17df6e65ec064eca71c5ec98 to your computer and use it in GitHub Desktop.
Save jan-schreib/9bd219fe17df6e65ec064eca71c5ec98 to your computer and use it in GitHub Desktop.
Simple hashmap for IPs
#include <stdio.h>
#include <time.h>
#include "compat.h"
#include "smap.h"
int
main()
{
struct smap map;
time_t t = time(NULL);
smap_init(&map, 200);
for (int i = 0; i < 10000; i++) {
smap_insert(&map, "10.11.12.1", t);
smap_insert(&map, "10.11.12.2", t);
smap_insert(&map, "10.11.12.3", t);
smap_insert(&map, "10.11.12.4", t);
smap_insert(&map, "10.11.12.5", t);
smap_insert(&map, "10.11.12.6", t);
smap_insert(&map, "10.11.12.7", t);
smap_insert(&map, "10.11.12.9", t);
smap_insert(&map, "10.11.12.10", t);
smap_insert(&map, "10.11.12.11", t);
smap_insert(&map, "10.11.12.12", t);
smap_insert(&map, "10.11.12.13", t);
smap_insert(&map, "10.11.12.14", t);
smap_insert(&map, "10.11.12.15", t);
smap_insert(&map, "10.11.12.16", t);
smap_insert(&map, "10.11.12.17", t);
smap_insert(&map, "10.11.12.18", t);
smap_insert(&map, "10.11.12.19", t);
smap_insert(&map, "10.11.12.20", t);
smap_insert(&map, "10.11.12.21", t);
smap_insert(&map, "10.11.12.22", t);
smap_insert(&map, "10.11.12.23", t);
smap_insert(&map, "10.11.12.24", t);
smap_insert(&map, "10.11.12.25", t);
smap_insert(&map, "10.11.12.26", t);
smap_insert(&map, "10.11.12.27", t);
smap_insert(&map, "10.11.12.28", t);
smap_insert(&map, "10.11.12.29", t);
smap_insert(&map, "10.11.12.30", t);
smap_insert(&map, "10.11.12.31", t);
smap_get(&map, "10.11.12.1");
smap_get(&map, "10.11.12.2");
smap_get(&map, "10.11.12.3");
smap_get(&map, "10.11.12.4");
smap_get(&map, "10.11.12.5");
smap_get(&map, "10.11.12.6");
smap_get(&map, "10.11.12.7");
smap_get(&map, "10.11.12.8");
smap_get(&map, "10.11.12.9");
smap_get(&map, "10.11.12.10");
smap_get(&map, "10.11.12.11");
smap_get(&map, "10.11.12.12");
smap_get(&map, "10.11.12.13");
smap_get(&map, "10.11.12.14");
smap_get(&map, "10.11.12.15");
smap_get(&map, "10.11.12.16");
smap_get(&map, "10.11.12.17");
smap_get(&map, "10.11.12.18");
smap_get(&map, "10.11.12.19");
smap_get(&map, "10.11.12.20");
smap_get(&map, "10.11.12.21");
smap_get(&map, "10.11.12.22");
smap_get(&map, "10.11.12.23");
smap_get(&map, "10.11.12.24");
smap_get(&map, "10.11.12.25");
smap_get(&map, "10.11.12.26");
}
if (smap_empty(&map) == 0)
printf("EMPTY!\n");
smap_clear(&map);
smap_free(&map);
return 0;
}
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "compat.h"
#include "smap.h"
static int hash(char*, size_t);
static int exists(struct smap*, int);
void
smap_init(struct smap* map, unsigned int size)
{
map->entry = calloc(size, sizeof(struct entry));
if (map->entry == NULL)
return;
map->size = size;
map->count = 0;
}
void
smap_free(struct smap* map)
{
free(map->entry);
}
int
hash(char* ip, size_t map_size)
{
int hash = 0;
long long temp = 0;
const char *errstr = NULL;
char **ap, *ips[4], *wip, *wwip;
wip = strdup(ip);
if (wip == NULL)
return -1;
wwip = wip;
for (ap = ips; ap <= &ips[3] &&
(*ap = strsep(&wip, ".")) != NULL;) {
if (**ap != '\0')
ap++;
}
for (int i = 0; i <= 3; i++) {
temp = strtonum(ips[i], 0, 255, &errstr);
if (errstr != NULL) {
return -1;
}
hash += temp;
}
hash += 127;
hash %= map_size;
free(wwip);
wwip = NULL;
return hash;
}
int
smap_insert (struct smap *map, char* ip, time_t time)
{
int h = hash(ip, map->size);
int nc = map->count;
if (exists(map, h) == 0)
nc++;
map->entry[h].value = time;
strlcpy(map->entry[h].ip, ip, 33);
map->count = nc;
return 0;
}
//0 = doesnt exist
//1 = exists
int
exists(struct smap *map, int hash)
{
if (strncmp(map->entry[hash].ip, "0", 33) == 0)
return 0;
return 1;
}
int
smap_contains(struct smap *map, char* ip)
{
int h = hash(ip, map->size);
return exists(map, h);
}
struct entry*
smap_get(struct smap *map, char* ip)
{
int h = hash(ip, map->size);
if (exists(map, h) == 0)
return NULL;
return &(map->entry[h]);
}
int
smap_empty(struct smap *map)
{
return (map->count == 0);
}
void
smap_clear(struct smap *map)
{
memset(map->entry, 0, map->size * sizeof(struct entry));
}
#ifndef SMAP_H
#define SMAP_H
struct entry {
char ip[33];
time_t value;
};
struct smap {
size_t size;
unsigned int count;
struct entry* entry;
};
void smap_init(struct smap*, unsigned int);
void smap_free(struct smap*);
int smap_empty(struct smap*);
int smap_insert(struct smap*, char*, time_t);
struct entry* smap_get(struct smap*, char*);
void smap_clear(struct smap*);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment