File: cache16.c

package info (click to toggle)
ruby-ox 2.14.23-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,504 kB
  • sloc: xml: 39,683; ansic: 9,626; ruby: 6,441; sh: 47; makefile: 2
file content (96 lines) | stat: -rw-r--r-- 2,502 bytes parent folder | download | duplicates (2)
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));
}