Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (2.42 KB)

1 9c41353a Luca Abeni
#include <stdlib.h>
2 40be1074 Luca Abeni
#include <stdint.h>
3 9c41353a Luca Abeni
#include <string.h>
4 40be1074 Luca Abeni
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 9c41353a Luca Abeni
  struct chunk *buffer;
13 40be1074 Luca Abeni
};
14
15 359e99fc Luca Abeni
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 c3ed3606 Luca Abeni
    j = i - 1;
23
    while(j >= 0 && tmp.id < b[j].id) {
24 359e99fc Luca Abeni
      b[j + 1] = b[j];
25
      j = j - 1;
26
    }
27
    b[j + 1] = tmp;
28
  }
29
}
30
31
32
33 9c41353a Luca Abeni
static void chunk_free(struct chunk *c)
34
{
35
    free(c->data);
36 c3ed3606 Luca Abeni
    c->data = NULL;
37 9c41353a Luca Abeni
    free(c->attributes);
38 c3ed3606 Luca Abeni
    c->attributes = NULL;
39 9c41353a Luca Abeni
    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 98bc2380 Luca Abeni
    cb->num_chunks--;
56 9c41353a Luca Abeni
57
    return pos_min;
58
  }
59
60
  return -1;
61
}
62
63
struct chunk_buffer *cb_init(const char *config)
64 40be1074 Luca Abeni
{
65
  struct tag *cfg_tags;
66
  struct chunk_buffer *cb;
67 9c41353a Luca Abeni
  int res, i;
68 40be1074 Luca Abeni
69 9c41353a Luca Abeni
  cb = malloc(sizeof(struct chunk_buffer));
70 40be1074 Luca Abeni
  if (cb == NULL) {
71
    return cb;
72
  }
73 9c41353a Luca Abeni
  memset(cb, 0, sizeof(struct chunk_buffer));
74 40be1074 Luca Abeni
75
  cfg_tags = config_parse(config);
76 9c41353a Luca Abeni
  res = config_value_int(cfg_tags, "size", &cb->size);
77
  if (!res) {
78 40be1074 Luca Abeni
    free(cb);
79 9c41353a Luca Abeni
    free(cfg_tags);
80
81 40be1074 Luca Abeni
    return NULL;
82
  }
83
  free(cfg_tags);
84
85 9c41353a Luca Abeni
  cb->buffer = malloc(sizeof(struct chunk) * cb->size);
86 40be1074 Luca Abeni
  if (cb->buffer == NULL) {
87
    free(cb);
88
    return NULL;
89
  }
90 c3ed3606 Luca Abeni
  memset(cb->buffer, 0, cb->size);
91 9c41353a Luca Abeni
  for (i = 0; i < cb->size; i++) {
92
    cb->buffer[i].id = -1;
93
  }
94 40be1074 Luca Abeni
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 9c41353a Luca Abeni
    i = remove_oldest_chunk(cb, c->id);
104
  } else {
105
    i = 0;
106 40be1074 Luca Abeni
  }
107 98bc2380 Luca Abeni
108
  if (i < 0) {
109
    return i;
110
  }
111 40be1074 Luca Abeni
  
112
  while(1) {
113 9c41353a Luca Abeni
    if (cb->buffer[i].id < 0) {
114
      cb->buffer[i] = *c;
115
      cb->num_chunks++;
116 40be1074 Luca Abeni
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 c3ed3606 Luca Abeni
  insert_sort(cb->buffer, cb->num_chunks);
131 40be1074 Luca Abeni
132
  return cb->buffer;
133
}
134
135 9c41353a Luca Abeni
int cb_clear(struct chunk_buffer *cb)
136 40be1074 Luca Abeni
{
137 9c41353a Luca Abeni
  int i;
138
139 c3ed3606 Luca Abeni
  for (i = 0; i < cb->num_chunks; i++) {
140 9c41353a Luca Abeni
    chunk_free(&cb->buffer[i]);
141 40be1074 Luca Abeni
  }
142 c3ed3606 Luca Abeni
  cb->num_chunks = 0;
143 40be1074 Luca Abeni
144
  return 0;
145
}
146 c3ed3606 Luca Abeni
147
void cb_destroy(struct chunk_buffer *cb)
148
{
149
  cb_clear(cb);
150
  free(cb->buffer);
151
  free(cb);
152
}