aboutsummaryrefslogtreecommitdiffstats
path: root/router/router.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-06-28 19:09:38 -0700
committerChris Robinson <[email protected]>2017-06-28 19:09:38 -0700
commitb88b57868ab37453980170896070631714fdc1fa (patch)
tree4b34806dfb6f73ff72b208b88d051766f16b0c6c /router/router.c
parent9fd7349220223c90e4476030f55a033eb3a37dbd (diff)
Add a ptr-to-int map
Diffstat (limited to 'router/router.c')
-rw-r--r--router/router.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/router/router.c b/router/router.c
index 21ab8a6a..7bbdfa8e 100644
--- a/router/router.c
+++ b/router/router.c
@@ -5,6 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "AL/alc.h"
#include "AL/al.h"
@@ -275,3 +276,152 @@ void LoadDriverList(void)
path[len-1] = '\0';
SearchDrivers(path);
}
+
+
+void InitPtrIntMap(PtrIntMap *map)
+{
+ map->keys = NULL;
+ map->values = NULL;
+ map->size = 0;
+ map->capacity = 0;
+ RWLockInit(&map->lock);
+}
+
+void ResetPtrIntMap(PtrIntMap *map)
+{
+ WriteLock(&map->lock);
+ free(map->keys);
+ map->keys = NULL;
+ map->values = NULL;
+ map->size = 0;
+ map->capacity = 0;
+ WriteUnlock(&map->lock);
+}
+
+ALenum InsertPtrIntMapEntry(PtrIntMap *map, ALvoid *key, ALint value)
+{
+ ALsizei pos = 0;
+
+ WriteLock(&map->lock);
+ if(map->size > 0)
+ {
+ ALsizei count = map->size;
+ do {
+ ALsizei step = count>>1;
+ ALsizei i = pos+step;
+ if(!(map->keys[i] < key))
+ count = step;
+ else
+ {
+ pos = i+1;
+ count -= step+1;
+ }
+ } while(count > 0);
+ }
+
+ if(pos == map->size || map->keys[pos] != key)
+ {
+ if(map->size == map->capacity)
+ {
+ ALvoid **keys = NULL;
+ ALint *values;
+ ALsizei newcap;
+
+ newcap = (map->capacity ? (map->capacity<<1) : 4);
+ if(newcap > map->capacity)
+ keys = calloc(sizeof(map->keys[0])+sizeof(map->values[0]), newcap);
+ if(!keys)
+ {
+ WriteUnlock(&map->lock);
+ return AL_OUT_OF_MEMORY;
+ }
+ values = (ALint*)&keys[newcap];
+
+ if(map->keys)
+ {
+ memcpy(keys, map->keys, map->size*sizeof(map->keys[0]));
+ memcpy(values, map->values, map->size*sizeof(map->values[0]));
+ }
+ free(map->keys);
+ map->keys = keys;
+ map->values = values;
+ map->capacity = newcap;
+ }
+
+ if(pos < map->size)
+ {
+ memmove(&map->keys[pos+1], &map->keys[pos],
+ (map->size-pos)*sizeof(map->keys[0]));
+ memmove(&map->values[pos+1], &map->values[pos],
+ (map->size-pos)*sizeof(map->values[0]));
+ }
+ map->size++;
+ }
+ map->keys[pos] = key;
+ map->values[pos] = value;
+ WriteUnlock(&map->lock);
+
+ return AL_NO_ERROR;
+}
+
+ALint RemovePtrIntMapKey(PtrIntMap *map, ALvoid *key)
+{
+ ALint ret = -1;
+ WriteLock(&map->lock);
+ if(map->size > 0)
+ {
+ ALsizei pos = 0;
+ ALsizei count = map->size;
+ do {
+ ALsizei step = count>>1;
+ ALsizei i = pos+step;
+ if(!(map->keys[i] < key))
+ count = step;
+ else
+ {
+ pos = i+1;
+ count -= step+1;
+ }
+ } while(count > 0);
+ if(pos < map->size && map->keys[pos] == key)
+ {
+ ret = map->values[pos];
+ if(pos < map->size-1)
+ {
+ memmove(&map->keys[pos], &map->keys[pos+1],
+ (map->size-1-pos)*sizeof(map->keys[0]));
+ memmove(&map->values[pos], &map->values[pos+1],
+ (map->size-1-pos)*sizeof(map->values[0]));
+ }
+ map->size--;
+ }
+ }
+ WriteUnlock(&map->lock);
+ return ret;
+}
+
+ALint LookupPtrIntMapKey(PtrIntMap *map, ALvoid *key)
+{
+ ALint ret = -1;
+ ReadLock(&map->lock);
+ if(map->size > 0)
+ {
+ ALsizei pos = 0;
+ ALsizei count = map->size;
+ do {
+ ALsizei step = count>>1;
+ ALsizei i = pos+step;
+ if(!(map->keys[i] < key))
+ count = step;
+ else
+ {
+ pos = i+1;
+ count -= step+1;
+ }
+ } while(count > 0);
+ if(pos < map->size && map->keys[pos] == key)
+ ret = map->values[pos];
+ }
+ ReadUnlock(&map->lock);
+ return ret;
+}