Statistics
| Branch: | Revision:

grapes / som / ChunkBuffer / buffer.c @ 98bc2380

History | View | Annotate | Download (2.42 KB)

1
#include <stdlib.h>
2
#include <stdint.h>
3
#include <string.h>
4

    
5
#include "chunk.h"
6
#include "chunkbuffer.h"
7
#include "config.h"
8

    
9
struct chunk_buffer {
10
  int size;
11
  int num_chunks;
12
  struct chunk *buffer;
13
};
14

    
15
static void insert_sort(struct chunk *b, int size)
16
{
17
  int i, j;
18
  struct chunk tmp;
19

    
20
  for(i = 1; i < size; i++) {
21
    tmp = b[i];
22
    j = i - 1;
23
    while(j >= 0 && tmp.id < b[j].id) {
24
      b[j + 1] = b[j];
25
      j = j - 1;
26
    }
27
    b[j + 1] = tmp;
28
  }
29
}
30

    
31

    
32

    
33
static void chunk_free(struct chunk *c)
34
{
35
    free(c->data);
36
    c->data = NULL;
37
    free(c->attributes);
38
    c->attributes = NULL;
39
    c->id = -1;
40
}
41

    
42
static int remove_oldest_chunk(struct chunk_buffer *cb, int id)
43
{
44
  int i, min, pos_min;
45

    
46
  min = cb->buffer[0].id; pos_min = 0;
47
  for (i = 1; i < cb->num_chunks; i++) {
48
    if (cb->buffer[i].id < min) {
49
      min = cb->buffer[i].id;
50
      pos_min = i;
51
    }
52
  }
53
  if (min < id) {
54
    chunk_free(&cb->buffer[pos_min]);
55
    cb->num_chunks--;
56

    
57
    return pos_min;
58
  }
59

    
60
  return -1;
61
}
62

    
63
struct chunk_buffer *cb_init(const char *config)
64
{
65
  struct tag *cfg_tags;
66
  struct chunk_buffer *cb;
67
  int res, i;
68

    
69
  cb = malloc(sizeof(struct chunk_buffer));
70
  if (cb == NULL) {
71
    return cb;
72
  }
73
  memset(cb, 0, sizeof(struct chunk_buffer));
74

    
75
  cfg_tags = config_parse(config);
76
  res = config_value_int(cfg_tags, "size", &cb->size);
77
  if (!res) {
78
    free(cb);
79
    free(cfg_tags);
80

    
81
    return NULL;
82
  }
83
  free(cfg_tags);
84

    
85
  cb->buffer = malloc(sizeof(struct chunk) * cb->size);
86
  if (cb->buffer == NULL) {
87
    free(cb);
88
    return NULL;
89
  }
90
  memset(cb->buffer, 0, cb->size);
91
  for (i = 0; i < cb->size; i++) {
92
    cb->buffer[i].id = -1;
93
  }
94

    
95
  return cb;
96
}
97

    
98
int cb_add_chunk(struct chunk_buffer *cb, const struct chunk *c)
99
{
100
  int i;
101

    
102
  if (cb->num_chunks == cb->size) {
103
    i = remove_oldest_chunk(cb, c->id);
104
  } else {
105
    i = 0;
106
  }
107

    
108
  if (i < 0) {
109
    return i;
110
  }
111
  
112
  while(1) {
113
    if (cb->buffer[i].id < 0) {
114
      cb->buffer[i] = *c;
115
      cb->num_chunks++;
116

    
117
      return 0; 
118
    }
119
    i++;
120
  }
121
}
122

    
123
struct chunk *cb_get_chunks(const struct chunk_buffer *cb, int *n)
124
{
125
  *n = cb->num_chunks;
126
  if (*n == 0) {
127
    return NULL;
128
  }
129

    
130
  insert_sort(cb->buffer, cb->num_chunks);
131

    
132
  return cb->buffer;
133
}
134

    
135
int cb_clear(struct chunk_buffer *cb)
136
{
137
  int i;
138

    
139
  for (i = 0; i < cb->num_chunks; i++) {
140
    chunk_free(&cb->buffer[i]);
141
  }
142
  cb->num_chunks = 0;
143

    
144
  return 0;
145
}
146

    
147
void cb_destroy(struct chunk_buffer *cb)
148
{
149
  cb_clear(cb);
150
  free(cb->buffer);
151
  free(cb);
152
}