Statistics
| Branch: | Revision:

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
}