Statistics
| Branch: | Tag: | Revision:

sssimulator / Matrix / string_indexer.c @ master

History | View | Annotate | Download (2.71 KB)

1
/*
2
 * This is SSSim: the Simple & Stupid Simulator
3
 *
4
 *  Copyright (c) 2015 Luca Baldesi
5
 *
6
 *  This is free software; see gpl-3.0.txt
7
 */
8

    
9
#include <stdint.h>
10
#include <string.h>
11
#include <malloc.h>
12

    
13
#define STRING_INDEXER_INC_SIZE 10
14

    
15
struct string_indexer {
16
        char ** strings;
17
        uint32_t * ids;
18
        uint32_t n_elements;
19
        uint32_t size;
20
};
21

    
22
int string_indexer_init(struct string_indexer * si,const uint32_t size)
23
{
24
        if(si)
25
        {
26
                si->n_elements = 0;
27
                si->size = size;
28
                si->strings = (char **) malloc (sizeof(char *) * si->size);
29
                si->ids = (uint32_t *) malloc (sizeof(char *) * si->size);
30
        }
31
        return si->strings == NULL || si->ids == NULL ? -1 : 0;
32
}
33

    
34
struct string_indexer * string_indexer_new(const uint32_t size)
35
{
36
        struct string_indexer * si = NULL;
37

    
38
        si = (struct string_indexer *) malloc (sizeof(struct string_indexer));
39

    
40
        string_indexer_init(si,size);
41
        return si;
42
}
43

    
44
void string_indexer_destroy(struct string_indexer ** si)
45
{
46
        uint32_t i;
47
//        fprintf(stderr, "[DEBUG] in string destroy\n");
48

    
49
        if(si && *si && (*si)->strings)
50
        {
51
                for(i = 0; i < (*si)->n_elements; i++)
52
                        free(((*si)->strings)[i]);
53
                free((*si)->strings);
54
        }
55
        if (si)
56
        {
57
                if(*si && (*si)->ids)
58
                        free((*si)->ids);
59
                if(*si)
60
                        free(*si);
61
                *si = NULL;
62
        }
63
}
64

    
65
uint32_t string_indexer_check_pos(const struct string_indexer *h, const char * s)
66
{
67
        uint32_t a,b,i;
68

    
69
        i = 0;
70
        if(h && h->n_elements > 0)
71
        {
72
                a = 0;
73
                b = h->n_elements-1;
74
                i = (b+a)/2;
75
                
76
                while(b > a)
77
                {
78
                        if (strcmp(s,h->strings[i]) > 0)
79
                                a = i+1;
80
                        if (strcmp(s,h->strings[i]) < 0)
81
                                b = i ? i-1 : 0;
82
                        if (strcmp(s,h->strings[i]) == 0)
83
                                a = b = i;
84
                
85
                        i = (b+a)/2;
86
                }
87
                if (strcmp(s,h->strings[i]) > 0)
88
                        i++;
89
        }
90

    
91
        return i;        
92
}
93

    
94
uint32_t string_indexer_id(struct string_indexer * si,const char * line)
95
{
96
        uint32_t i;
97

    
98
        if(si && line)
99
        {
100
                i = string_indexer_check_pos(si,line);
101
                if(i>= si->n_elements || strcmp(line,(si->strings)[i]))
102
                {
103
                        if((si->n_elements + 1) >= si->size)
104
                        {
105
                                si->size += STRING_INDEXER_INC_SIZE;
106
                                si->strings = (char **) realloc(si->strings,sizeof(char*) * si->size);
107
                                si->ids = (uint32_t *) realloc(si->ids,sizeof(uint32_t) * si->size);
108
                        }
109
                        memmove(&(si->strings[i+1]),&(si->strings[i]),sizeof(char *) * (si->n_elements -i));
110
                        memmove(&(si->ids[i+1]),&(si->ids[i]),sizeof(uint32_t) * (si->n_elements -i));
111

    
112
                        si->strings[i] = strdup(line);
113
                        si->ids[i] = si->n_elements;
114
                        si->n_elements++;
115
                } 
116
                return si->ids[i];
117
        }
118
        return 0;
119
}
120

    
121
uint32_t string_indexer_size(struct string_indexer *si)
122
{
123
        if(si)
124
                return si->n_elements;
125
        else
126
                return 0;
127
}
128

    
129
uint8_t string_indexer_check(const struct string_indexer * si,const char* s)
130
{
131
        uint32_t pos;
132

    
133
        pos = string_indexer_check_pos(si,s);
134

    
135
        if(pos >= si->n_elements || strcmp(si->strings[pos],s) != 0)
136
                return 0;
137
        return 1;
138
}