1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
#include "cache16.h"
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _Cache16 {
VALUE value;
struct _Cache16 *slots[16];
};
static void slot_print(Cache16 cache, unsigned int depth);
static void v2s(VALUE v, char *buf, unsigned long len);
void ox_cache16_new(Cache16 *cache) {
Cache16 *cp;
int i;
if (0 == (*cache = (Cache16)malloc(sizeof(struct _Cache16)))) {
rb_raise(rb_eStandardError, "not enough memory\n");
}
(*cache)->value = Qundef;
for (i = 16, cp = (*cache)->slots; 0 < i; i--, cp++) {
*cp = 0;
}
}
VALUE
ox_cache16_get(Cache16 cache, const char *key, VALUE **slot) {
unsigned char *k = (unsigned char *)key;
Cache16 *cp;
for (; '\0' != *k; k++) {
cp = cache->slots + (unsigned int)(*k >> 4); // upper 4 bits
if (0 == *cp) {
ox_cache16_new(cp);
}
cache = *cp;
cp = cache->slots + (unsigned int)(*k & 0x0F); // lower 4 bits
if (0 == *cp) {
ox_cache16_new(cp);
}
cache = *cp;
}
*slot = &cache->value;
return cache->value;
}
void ox_cache16_print(Cache16 cache) {
// printf("-------------------------------------------\n");
slot_print(cache, 0);
}
static void slot_print(Cache16 c, unsigned int depth) {
char indent[256];
Cache16 *cp;
unsigned int i;
if (sizeof(indent) - 1 < depth) {
depth = ((int)sizeof(indent) - 1);
}
memset(indent, ' ', depth);
indent[depth] = '\0';
for (i = 0, cp = c->slots; i < 16; i++, cp++) {
if (0 == *cp) {
// printf("%s%02u:\n", indent, i);
} else {
if (Qundef == (*cp)->value) {
printf("%s%02u:\n", indent, i);
} else {
char value[1024];
const char *clas;
if (Qundef == (*cp)->value) {
strcpy(value, "undefined");
clas = "";
} else {
v2s((*cp)->value, value, sizeof(value));
clas = rb_class2name(rb_obj_class((*cp)->value));
}
printf("%s%02u: %s (%s)\n", indent, i, value, clas);
}
slot_print(*cp, depth + 2);
}
}
}
static void v2s(VALUE v, char *buf, unsigned long len) {
VALUE rs = rb_String(v);
snprintf(buf, len, "%s", StringValuePtr(rs));
}
|