Statistics
| Branch: | Revision:

grapes / som / ChunkBuffer / buffer.c @ 8ab58ec7

History | View | Annotate | Download (2.54 KB)

1 8ab58ec7 Luca Abeni
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *  Copyright (c) 2010 Csaba Kiraly
4
 *
5
 *  This is free software; see lgpl-2.1.txt
6
 */
7
8 9c41353a Luca Abeni
#include <stdlib.h>
9 40be1074 Luca Abeni
#include <stdint.h>
10 9c41353a Luca Abeni
#include <string.h>
11 40be1074 Luca Abeni
12
#include "chunk.h"
13
#include "chunkbuffer.h"
14
#include "config.h"
15
16
struct chunk_buffer {
17
  int size;
18
  int num_chunks;
19 9c41353a Luca Abeni
  struct chunk *buffer;
20 40be1074 Luca Abeni
};
21
22 359e99fc Luca Abeni
static void insert_sort(struct chunk *b, int size)
23
{
24
  int i, j;
25
  struct chunk tmp;
26
27
  for(i = 1; i < size; i++) {
28
    tmp = b[i];
29 c3ed3606 Luca Abeni
    j = i - 1;
30
    while(j >= 0 && tmp.id < b[j].id) {
31 359e99fc Luca Abeni
      b[j + 1] = b[j];
32
      j = j - 1;
33
    }
34
    b[j + 1] = tmp;
35
  }
36
}
37
38
39
40 9c41353a Luca Abeni
static void chunk_free(struct chunk *c)
41
{
42
    free(c->data);
43 c3ed3606 Luca Abeni
    c->data = NULL;
44 9c41353a Luca Abeni
    free(c->attributes);
45 c3ed3606 Luca Abeni
    c->attributes = NULL;
46 9c41353a Luca Abeni
    c->id = -1;
47
}
48
49
static int remove_oldest_chunk(struct chunk_buffer *cb, int id)
50
{
51
  int i, min, pos_min;
52
53
  min = cb->buffer[0].id; pos_min = 0;
54
  for (i = 1; i < cb->num_chunks; i++) {
55
    if (cb->buffer[i].id < min) {
56
      min = cb->buffer[i].id;
57
      pos_min = i;
58
    }
59
  }
60
  if (min < id) {
61
    chunk_free(&cb->buffer[pos_min]);
62 98bc2380 Luca Abeni
    cb->num_chunks--;
63 9c41353a Luca Abeni
64
    return pos_min;
65
  }
66
67
  return -1;
68
}
69
70
struct chunk_buffer *cb_init(const char *config)
71 40be1074 Luca Abeni
{
72
  struct tag *cfg_tags;
73
  struct chunk_buffer *cb;
74 9c41353a Luca Abeni
  int res, i;
75 40be1074 Luca Abeni
76 9c41353a Luca Abeni
  cb = malloc(sizeof(struct chunk_buffer));
77 40be1074 Luca Abeni
  if (cb == NULL) {
78
    return cb;
79
  }
80 9c41353a Luca Abeni
  memset(cb, 0, sizeof(struct chunk_buffer));
81 40be1074 Luca Abeni
82
  cfg_tags = config_parse(config);
83 9c41353a Luca Abeni
  res = config_value_int(cfg_tags, "size", &cb->size);
84
  if (!res) {
85 40be1074 Luca Abeni
    free(cb);
86 9c41353a Luca Abeni
    free(cfg_tags);
87
88 40be1074 Luca Abeni
    return NULL;
89
  }
90
  free(cfg_tags);
91
92 9c41353a Luca Abeni
  cb->buffer = malloc(sizeof(struct chunk) * cb->size);
93 40be1074 Luca Abeni
  if (cb->buffer == NULL) {
94
    free(cb);
95
    return NULL;
96
  }
97 c3ed3606 Luca Abeni
  memset(cb->buffer, 0, cb->size);
98 9c41353a Luca Abeni
  for (i = 0; i < cb->size; i++) {
99
    cb->buffer[i].id = -1;
100
  }
101 40be1074 Luca Abeni
102
  return cb;
103
}
104
105
int cb_add_chunk(struct chunk_buffer *cb, const struct chunk *c)
106
{
107
  int i;
108
109
  if (cb->num_chunks == cb->size) {
110 9c41353a Luca Abeni
    i = remove_oldest_chunk(cb, c->id);
111
  } else {
112
    i = 0;
113 40be1074 Luca Abeni
  }
114 98bc2380 Luca Abeni
115
  if (i < 0) {
116
    return i;
117
  }
118 40be1074 Luca Abeni
  
119
  while(1) {
120 9c41353a Luca Abeni
    if (cb->buffer[i].id < 0) {
121
      cb->buffer[i] = *c;
122
      cb->num_chunks++;
123 40be1074 Luca Abeni
124
      return 0; 
125
    }
126
    i++;
127
  }
128
}
129
130
struct chunk *cb_get_chunks(const struct chunk_buffer *cb, int *n)
131
{
132
  *n = cb->num_chunks;
133
  if (*n == 0) {
134
    return NULL;
135
  }
136
137 c3ed3606 Luca Abeni
  insert_sort(cb->buffer, cb->num_chunks);
138 40be1074 Luca Abeni
139
  return cb->buffer;
140
}
141
142 9c41353a Luca Abeni
int cb_clear(struct chunk_buffer *cb)
143 40be1074 Luca Abeni
{
144 9c41353a Luca Abeni
  int i;
145
146 c3ed3606 Luca Abeni
  for (i = 0; i < cb->num_chunks; i++) {
147 9c41353a Luca Abeni
    chunk_free(&cb->buffer[i]);
148 40be1074 Luca Abeni
  }
149 c3ed3606 Luca Abeni
  cb->num_chunks = 0;
150 40be1074 Luca Abeni
151
  return 0;
152
}
153 c3ed3606 Luca Abeni
154
void cb_destroy(struct chunk_buffer *cb)
155
{
156
  cb_clear(cb);
157
  free(cb->buffer);
158
  free(cb);
159
}