~ne02ptzero/libfloat

ref: c93ce23cec30a46ea6bd54d341f22cb6d582bbd9 libfloat/libfloat.c -rw-r--r-- 2.6 KiB
c93ce23c — Louis Solofrizzo log: Add helpers for human readable consistency types 2 months ago
                                                                                
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
97
98
99
100
101
102
103
104
105
106
107
#include "internal.h"

libfloat_ctx_t *libfloat_ctx_new(void *(*malloc)(size_t), void *(*calloc)(size_t, size_t), void (*free)(void *))
{
    libfloat_ctx_t      *ret = calloc(1, sizeof(*ret));

    if (ret == NULL)
        return NULL;

    ret->malloc = malloc;
    ret->calloc = calloc;
    ret->free = free;

    ret->persistent.log = kh_init(libfloat_entry_id_t);
    ret->nodes = kh_init(libfloat_node_id_t);

    /* Defaults */
    ret->election_timeout_rand = 2000;
    ret->request_timeout = 800;
    ret->conf.election_timeout = 2000;
    ret->conf.log_commit_timeout = 5;
    ret->conf.compact_every_n_log = 10000;
    ret->conf.avoid_congestion = false;
    ret->conf.sanity_timeout = 6;
    ret->conf.optimistic_replication = true;
    ret->conf.max_logs_per_ae = 500;
    ret->conf.do_revert = false;

    /* Init the log list */
    ret->logs.prev = &ret->logs;
    ret->logs.next = &ret->logs;

    return ret;
}

void libfloat_ctx_del(libfloat_ctx_t *ctx)
{
    libfloat_log_entry_t        *log;
    libfloat_node_t             *node;

    kh_foreach_value(ctx->persistent.log, log, {
        if (log->commit != NULL)
        {
            log->commit(log->udata, LIBFLOAT_ENTRY_REFUSED);
        }

        if (log->data != NULL)
        {
            ctx->free(log->data->buf);
            ctx->free(log->data);
        }

        libfloat_log_free_acks(ctx, log);
        ctx->free(log);
    });

    kh_foreach_value(ctx->nodes, node, {
        ctx->free(node);
    });

    kh_destroy(libfloat_entry_id_t, ctx->persistent.log);
    kh_destroy(libfloat_node_id_t, ctx->nodes);
    ctx->free(ctx);
}

static const char *types[] = {
    [LIBFLOAT_HOPEFULLY_CONSISTENT] = "hopeful",
    [LIBFLOAT_EVENTUALLY_CONSISTENT] = "eventual",
    [LIBFLOAT_STRONGLY_CONSISTENT] = "strong",
    [LIBFLOAT_ABSOLUTELY_CONSISTENT] = "absolute",
};
_Static_assert(sizeof(types) / sizeof(types[0]) == LIBFLOAT_COMMIT_TYPE_LAST, "Missing a commit type entry");

const char *libfloat_commit_type_to_str(libfloat_commit_type_t t)
{
    return types[t];
}

static int libfloat_strcmp(const char *s1, const char *s2)
{
    size_t      i;

    for (i = 0; s1[i] != '\0' && s2[i] != '\0' && s1[i] == s2[i]; i++)
        ;

    if (s1[i] == '\0' && s2[i] == '\0')
        return 0;

    return s1[i] - s2[i];
}

bool libfloat_str_to_commit_type(const char *t, libfloat_commit_type_t *out)
{
    if (t == NULL || out == NULL)
        return false;

    for (size_t i = 0; i < sizeof(types) / sizeof(types[0]); i++)
    {
        if (libfloat_strcmp(t, types[i]) == 0)
        {
            *out = i;
            return true;
        }
    }

    return false;
}