]> mj.ucw.cz Git - libucw.git/blob - lib/pool.c
Added secondary sorting (i.e., breaking ties when two documents have the same Q)
[libucw.git] / lib / pool.c
1 /*
2  *      Sherlock Library -- Memory Pools (One-Time Allocation)
3  *
4  *      (c) 1997--2001 Martin Mares <mj@ucw.cz>
5  */
6
7 #include "lib/lib.h"
8 #include "lib/pools.h"
9
10 #include <stdlib.h>
11 #include <string.h>
12
13 struct memchunk {
14   struct memchunk *next;
15   byte data[0];
16 };
17
18 struct mempool *
19 mp_new(uns size)
20 {
21   struct mempool *p = xmalloc(sizeof(struct mempool));
22
23   size -= sizeof(struct memchunk);
24   p->free = p->last = NULL;
25   p->first = p->current = p->first_large = NULL;
26   p->plast = &p->first;
27   p->chunk_size = size;
28   p->threshold = size / 3;
29   return p;
30 }
31
32 void
33 mp_delete(struct mempool *p)
34 {
35   struct memchunk *c, *d;
36
37   for(d=p->first; d; d = c)
38     {
39       c = d->next;
40       xfree(d);
41     }
42   for(d=p->first_large; d; d = c)
43     {
44       c = d->next;
45       xfree(d);
46     }
47   xfree(p);
48 }
49
50 void
51 mp_flush(struct mempool *p)
52 {
53   struct memchunk *c;
54
55   p->free = p->last = NULL;
56   p->current = p->first;
57   while (c = p->first_large)
58     {
59       p->first_large = c->next;
60       xfree(c);
61     }
62 }
63
64 void *
65 mp_alloc(struct mempool *p, uns s)
66 {
67   if (s <= p->threshold)
68     {
69       byte *x = (byte *)(((uns) p->free + POOL_ALIGN - 1) & ~(POOL_ALIGN - 1));
70       if (x + s > p->last)
71         {
72           struct memchunk *c;
73
74           if (p->current)
75             {
76               /* Still have free chunks from previous incarnation */
77               c = p->current;
78               p->current = c->next;
79             }
80           else
81             {
82               c = xmalloc(sizeof(struct memchunk) + p->chunk_size);
83               *p->plast = c;
84               p->plast = &c->next;
85               c->next = NULL;
86             }
87           x = c->data;
88           p->last = x + p->chunk_size;
89         }
90       p->free = x + s;
91       return x;
92     }
93   else
94     {
95       struct memchunk *c = xmalloc(sizeof(struct memchunk) + s);
96       c->next = p->first_large;
97       p->first_large = c;
98       return c->data;
99     }
100 }
101
102 void *
103 mp_alloc_zero(struct mempool *p, uns s)
104 {
105   void *x = mp_alloc(p, s);
106   bzero(x, s);
107   return x;
108 }