ex35 bits
This commit is contained in:
140
lcthw-remnants-2/liblcthw/src/lcthw/radixmap.c
Normal file
140
lcthw-remnants-2/liblcthw/src/lcthw/radixmap.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Based on code by Andre Reinald then heavily modified by Zed A. Shaw
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <lcthw/radixmap.h>
|
||||
#include <lcthw/dbg.h>
|
||||
|
||||
RadixMap *RadixMap_create(size_t max)
|
||||
{
|
||||
RadixMap *map = calloc(sizeof(RadixMap), 1);
|
||||
check_mem(map);
|
||||
|
||||
map->contents = calloc(sizeof(RMElement), max + 1);
|
||||
check_mem(map->contents);
|
||||
|
||||
map->temp = calloc(sizeof(RMElement), max + 1);
|
||||
check_mem(map->temp);
|
||||
|
||||
map->max = max;
|
||||
map->end = 0;
|
||||
|
||||
return map;
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void RadixMap_destroy(RadixMap *map)
|
||||
{
|
||||
if(map) {
|
||||
free(map->contents);
|
||||
free(map->temp);
|
||||
free(map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define ByteOf(x,y) (((uint8_t *)x)[y])
|
||||
|
||||
static inline void radix_sort(short offset, uint64_t max, uint64_t *source, uint64_t *dest)
|
||||
{
|
||||
uint64_t count[256] = {0};
|
||||
uint64_t *cp = NULL;
|
||||
uint64_t *sp = NULL;
|
||||
uint64_t *end = NULL;
|
||||
uint64_t s = 0;
|
||||
uint64_t c = 0;
|
||||
|
||||
// count occurences of every byte value
|
||||
for(sp = source, end = source + max; sp < end; sp++) {
|
||||
count[ByteOf(sp, offset)]++;
|
||||
}
|
||||
|
||||
// transform count into index by summing elements and storing into same array
|
||||
for(s = 0, cp = count, end = count + 256; cp < end; cp++) {
|
||||
c = *cp;
|
||||
*cp = s;
|
||||
s += c;
|
||||
}
|
||||
|
||||
// fill dest with the right values in the right place
|
||||
for(sp = source, end = source + max; sp < end; sp++) {
|
||||
cp = count + ByteOf(sp, offset);
|
||||
dest[*cp] = *sp;
|
||||
++(*cp);
|
||||
}
|
||||
}
|
||||
|
||||
void RadixMap_sort(RadixMap *map)
|
||||
{
|
||||
uint64_t *source = &map->contents[0].raw;
|
||||
uint64_t *temp = &map->temp[0].raw;
|
||||
|
||||
radix_sort(0, map->end, source, temp);
|
||||
radix_sort(1, map->end, temp, source);
|
||||
radix_sort(2, map->end, source, temp);
|
||||
radix_sort(3, map->end, temp, source);
|
||||
}
|
||||
|
||||
RMElement *RadixMap_find(RadixMap *map, uint32_t to_find)
|
||||
{
|
||||
int low = 0;
|
||||
int high = map->end - 1;
|
||||
RMElement *data = map->contents;
|
||||
|
||||
while(low <= high) {
|
||||
int middle = low + (high - low)/2;
|
||||
uint32_t key = data[middle].data.key;
|
||||
|
||||
if(to_find < key) {
|
||||
high = middle - 1;
|
||||
} else if(to_find > key) {
|
||||
low = middle + 1;
|
||||
} else {
|
||||
return &data[middle];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int RadixMap_add(RadixMap *map, uint32_t key, uint32_t value)
|
||||
{
|
||||
check(key < UINT32_MAX, "Key can't be equal to UINT32_MAX.");
|
||||
|
||||
RMElement element = {.data = {.key = key, .value = value}};
|
||||
check(map->end + 1 < map->max, "RadixMap is full.");
|
||||
|
||||
map->contents[map->end++] = element;
|
||||
|
||||
RadixMap_sort(map);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int RadixMap_delete(RadixMap *map, RMElement *el)
|
||||
{
|
||||
check(map->end > 0, "There is nothing to delete.");
|
||||
check(el != NULL, "Can't delete a NULL element.");
|
||||
|
||||
el->data.key = UINT32_MAX;
|
||||
|
||||
if(map->end > 1) {
|
||||
// don't bother resorting a map of 1 length
|
||||
RadixMap_sort(map);
|
||||
}
|
||||
|
||||
map->end--;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
35
lcthw-remnants-2/liblcthw/src/lcthw/radixmap.h
Normal file
35
lcthw-remnants-2/liblcthw/src/lcthw/radixmap.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef lcthw_radixmap_h
|
||||
#define lcthw_radixmap_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef union RMElement {
|
||||
uint64_t raw;
|
||||
struct {
|
||||
uint32_t key;
|
||||
uint32_t value;
|
||||
} data;
|
||||
} RMElement;
|
||||
|
||||
typedef struct RadixMap {
|
||||
size_t max;
|
||||
size_t end;
|
||||
uint32_t counter;
|
||||
RMElement *contents;
|
||||
RMElement *temp;
|
||||
} RadixMap;
|
||||
|
||||
|
||||
RadixMap *RadixMap_create(size_t max);
|
||||
|
||||
void RadixMap_destroy(RadixMap *map);
|
||||
|
||||
void RadixMap_sort(RadixMap *map);
|
||||
|
||||
RMElement *RadixMap_find(RadixMap *map, uint32_t key);
|
||||
|
||||
int RadixMap_add(RadixMap *map, uint32_t key, uint32_t value);
|
||||
|
||||
int RadixMap_delete(RadixMap *map, RMElement *el);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user