grapes / som / ChunkIDSet / chunkids_ops.c @ 4944dc2a
History | View | Annotate | Download (3.04 KB)
1 |
/*
|
---|---|
2 |
* Copyright (c) 2010 Luca Abeni
|
3 |
*
|
4 |
* This is free software; see lgpl-2.1.txt
|
5 |
*/
|
6 |
|
7 |
#include <stdlib.h> |
8 |
#include <stdint.h> |
9 |
#include <limits.h> |
10 |
#include <assert.h> |
11 |
|
12 |
#include "chunkids_private.h" |
13 |
#include "chunkidset.h" |
14 |
#include "config.h" |
15 |
|
16 |
#define DEFAULT_SIZE_INCREMENT 32 |
17 |
|
18 |
struct chunkID_set *chunkID_set_init(const char *config) |
19 |
{ |
20 |
struct chunkID_set *p;
|
21 |
struct tag *cfg_tags;
|
22 |
int res, type;
|
23 |
|
24 |
p = malloc(sizeof(struct chunkID_set)); |
25 |
if (p == NULL) { |
26 |
return NULL; |
27 |
} |
28 |
p->n_elements = 0;
|
29 |
cfg_tags = config_parse(config); |
30 |
res = config_value_int(cfg_tags, "size", &p->size);
|
31 |
if (!res) {
|
32 |
p->size = 0;
|
33 |
} |
34 |
if (p->size) {
|
35 |
p->elements = malloc(p->size * sizeof(int)); |
36 |
if (p->elements == NULL) { |
37 |
p->size = 0;
|
38 |
} |
39 |
} else {
|
40 |
p->elements = NULL;
|
41 |
} |
42 |
p->type = CIST_PRIORITY; |
43 |
res = config_value_int(cfg_tags, "type", &type);
|
44 |
free(cfg_tags); |
45 |
if (res) {
|
46 |
switch (type) {
|
47 |
case priority:
|
48 |
p->type = CIST_PRIORITY; |
49 |
break;
|
50 |
case bitmap:
|
51 |
p->type = CIST_BITMAP; |
52 |
break;
|
53 |
default:
|
54 |
chunkID_set_free(p); |
55 |
|
56 |
return NULL; |
57 |
} |
58 |
} |
59 |
assert(p->type == CIST_PRIORITY || p->type == CIST_BITMAP); |
60 |
return p;
|
61 |
} |
62 |
|
63 |
int chunkID_set_add_chunk(struct chunkID_set *h, int chunk_id) |
64 |
{ |
65 |
if (chunkID_set_check(h, chunk_id) >= 0) { |
66 |
return 0; |
67 |
} |
68 |
|
69 |
if (h->n_elements == h->size) {
|
70 |
int *res;
|
71 |
|
72 |
res = realloc(h->elements, (h->size + DEFAULT_SIZE_INCREMENT) * sizeof(int)); |
73 |
if (res == NULL) { |
74 |
return -1; |
75 |
} |
76 |
h->size += DEFAULT_SIZE_INCREMENT; |
77 |
h->elements = res; |
78 |
} |
79 |
h->elements[h->n_elements++] = chunk_id; |
80 |
|
81 |
return h->n_elements;
|
82 |
} |
83 |
|
84 |
int chunkID_set_size(const struct chunkID_set *h) |
85 |
{ |
86 |
return h->n_elements;
|
87 |
} |
88 |
|
89 |
int chunkID_set_get_chunk(const struct chunkID_set *h, int i) |
90 |
{ |
91 |
if (i < h->n_elements) {
|
92 |
return h->elements[i];
|
93 |
} |
94 |
|
95 |
return -1; |
96 |
} |
97 |
|
98 |
int chunkID_set_check(const struct chunkID_set *h, int chunk_id) |
99 |
{ |
100 |
int i;
|
101 |
|
102 |
for (i = 0; i < h->n_elements; i++) { |
103 |
if (h->elements[i] == chunk_id) {
|
104 |
return i;
|
105 |
} |
106 |
} |
107 |
|
108 |
return -1; |
109 |
} |
110 |
|
111 |
int chunkID_set_get_earliest(const struct chunkID_set *h) |
112 |
{ |
113 |
int i;
|
114 |
uint32_t min; |
115 |
|
116 |
min = h->n_elements ? h->elements[0] : 0; |
117 |
for (i = 0; i < h->n_elements; i++) { |
118 |
min = (h->elements[i] < min) ? h->elements[i] : min; |
119 |
} |
120 |
|
121 |
return min;
|
122 |
} |
123 |
|
124 |
int chunkID_set_get_latest(const struct chunkID_set *h) |
125 |
{ |
126 |
int i;
|
127 |
uint32_t max; |
128 |
|
129 |
max = h->n_elements ? h->elements[0] : 0; |
130 |
for (i = 0; i < h->n_elements; i++) { |
131 |
max = (h->elements[i] > max) ? h->elements[i] : max; |
132 |
} |
133 |
|
134 |
return max;
|
135 |
} |
136 |
|
137 |
int chunkID_set_union(struct chunkID_set *h, struct chunkID_set *a) |
138 |
{ |
139 |
int i;
|
140 |
|
141 |
for (i = 0; i < a->n_elements; i++) { |
142 |
int ret = chunkID_set_add_chunk(h,a->elements[i]);
|
143 |
if (ret < 0) return ret; |
144 |
} |
145 |
return h->n_elements;
|
146 |
} |
147 |
|
148 |
void chunkID_set_clear(struct chunkID_set *h, int size) |
149 |
{ |
150 |
h->n_elements = 0;
|
151 |
h->size = size; |
152 |
h->elements = realloc(h->elements, size * sizeof(int)); |
153 |
if (h->elements == NULL) { |
154 |
h->size = 0;
|
155 |
} |
156 |
} |
157 |
|
158 |
void chunkID_set_free(struct chunkID_set *h) |
159 |
{ |
160 |
chunkID_set_clear(h,0);
|
161 |
free(h->elements); |
162 |
free(h); |
163 |
} |