Line data Source code
1 : #include "libstephen/rb.h"
2 :
3 : #include <stdlib.h>
4 : #include <string.h>
5 :
6 4 : void rb_init(smb_rb *rb, int dsize, int init)
7 : {
8 4 : rb->dsize = dsize;
9 4 : rb->nalloc = init;
10 4 : rb->start = 0;
11 4 : rb->count = 0;
12 4 : rb->data = calloc(dsize, init);
13 4 : }
14 :
15 4 : void rb_destroy(smb_rb *rb)
16 : {
17 4 : free(rb->data);
18 4 : }
19 :
20 4 : void rb_grow(smb_rb *rb)
21 : {
22 4 : int oldalloc = rb->nalloc;
23 4 : rb->nalloc *= 2;
24 4 : rb->data = realloc(rb->data, rb->nalloc * rb->dsize);
25 :
26 20 : for (int i = 0; i < rb->count; i++) {
27 16 : int oldindex = (rb->start + i) % oldalloc;
28 16 : int newindex = (rb->start + i) % rb->nalloc;
29 16 : if (oldindex != newindex) {
30 14 : memcpy(rb->data + newindex * rb->dsize,
31 14 : rb->data + oldindex * rb->dsize, rb->nalloc);
32 : }
33 : }
34 4 : }
35 :
36 11 : void rb_push_front(smb_rb *rb, void *src)
37 : {
38 11 : if (rb->count >= rb->nalloc) {
39 3 : rb_grow(rb);
40 : }
41 :
42 : // ensure the new start index is still positive
43 11 : int newstart = (rb->start + rb->nalloc - 1) % rb->nalloc;
44 11 : rb->start = newstart;
45 11 : memcpy(rb->data + rb->start * rb->dsize, src, rb->dsize);
46 11 : rb->count++;
47 11 : }
48 :
49 5 : void rb_pop_front(smb_rb *rb, void *dst)
50 : {
51 5 : int newstart = (rb->start + 1) % rb->nalloc;
52 5 : memcpy(dst, rb->data + rb->start * rb->dsize, rb->dsize);
53 5 : rb->start = newstart;
54 5 : rb->count--;
55 5 : }
56 :
57 9 : void rb_push_back(smb_rb *rb, void *src)
58 : {
59 9 : if (rb->count >= rb->nalloc) {
60 1 : rb_grow(rb);
61 : }
62 :
63 9 : int index = (rb->start + rb->count) % rb->nalloc;
64 9 : memcpy(rb->data + index * rb->dsize, src, rb->dsize);
65 9 : rb->count++;
66 9 : }
67 :
68 5 : void rb_pop_back(smb_rb *rb, void *dst)
69 : {
70 5 : int index = (rb->start + rb->count - 1) % rb->nalloc;
71 5 : memcpy(dst, rb->data + index * rb->dsize, rb->dsize);
72 5 : rb->count--;
73 5 : }
|