Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (2.54 KB)

1
/*
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
#include <stdlib.h>
9
#include <stdint.h>
10
#include <string.h>
11

    
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
  struct chunk *buffer;
20
};
21

    
22
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
    j = i - 1;
30
    while(j >= 0 && tmp.id < b[j].id) {
31
      b[j + 1] = b[j];
32
      j = j - 1;
33
    }
34
    b[j + 1] = tmp;
35
  }
36
}
37

    
38

    
39

    
40
static void chunk_free(struct chunk *c)
41
{
42
    free(c->data);
43
    c->data = NULL;
44
    free(c->attributes);
45
    c->attributes = NULL;
46
    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
    cb->num_chunks--;
63

    
64
    return pos_min;
65
  }
66

    
67
  return -1;
68
}
69

    
70
struct chunk_buffer *cb_init(const char *config)
71
{
72
  struct tag *cfg_tags;
73
  struct chunk_buffer *cb;
74
  int res, i;
75

    
76
  cb = malloc(sizeof(struct chunk_buffer));
77
  if (cb == NULL) {
78
    return cb;
79
  }
80
  memset(cb, 0, sizeof(struct chunk_buffer));
81

    
82
  cfg_tags = config_parse(config);
83
  res = config_value_int(cfg_tags, "size", &cb->size);
84
  if (!res) {
85
    free(cb);
86
    free(cfg_tags);
87

    
88
    return NULL;
89
  }
90
  free(cfg_tags);
91

    
92
  cb->buffer = malloc(sizeof(struct chunk) * cb->size);
93
  if (cb->buffer == NULL) {
94
    free(cb);
95
    return NULL;
96
  }
97
  memset(cb->buffer, 0, cb->size);
98
  for (i = 0; i < cb->size; i++) {
99
    cb->buffer[i].id = -1;
100
  }
101

    
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
    i = remove_oldest_chunk(cb, c->id);
111
  } else {
112
    i = 0;
113
  }
114

    
115
  if (i < 0) {
116
    return i;
117
  }
118
  
119
  while(1) {
120
    if (cb->buffer[i].id < 0) {
121
      cb->buffer[i] = *c;
122
      cb->num_chunks++;
123

    
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
  insert_sort(cb->buffer, cb->num_chunks);
138

    
139
  return cb->buffer;
140
}
141

    
142
int cb_clear(struct chunk_buffer *cb)
143
{
144
  int i;
145

    
146
  for (i = 0; i < cb->num_chunks; i++) {
147
    chunk_free(&cb->buffer[i]);
148
  }
149
  cb->num_chunks = 0;
150

    
151
  return 0;
152
}
153

    
154
void cb_destroy(struct chunk_buffer *cb)
155
{
156
  cb_clear(cb);
157
  free(cb->buffer);
158
  free(cb);
159
}