This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.
[samba.git] / source / lib / bitmap.c
1 /*
2    Unix SMB/CIFS implementation.
3    simple bitmap functions
4    Copyright (C) Andrew Tridgell 1992-1998
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 /* these functions provide a simple way to allocate integers from a
24    pool without repetition */
25
26 /****************************************************************************
27 allocate a bitmap of the specified size
28 ****************************************************************************/
29 struct bitmap *bitmap_allocate(int n)
30 {
31         struct bitmap *bm;
32
33         bm = (struct bitmap *)malloc(sizeof(*bm));
34
35         if (!bm) return NULL;
36         
37         bm->n = n;
38         bm->b = (uint32 *)malloc(sizeof(bm->b[0])*(n+31)/32);
39         if (!bm->b) {
40                 SAFE_FREE(bm);
41                 return NULL;
42         }
43
44         memset(bm->b, 0, sizeof(bm->b[0])*(n+31)/32);
45
46         return bm;
47 }
48
49 /****************************************************************************
50 free a bitmap.
51 ****************************************************************************/
52
53 void bitmap_free(struct bitmap *bm)
54 {
55         if (!bm)
56                 return;
57
58         SAFE_FREE(bm->b);
59         SAFE_FREE(bm);
60 }
61
62 /****************************************************************************
63 set a bit in a bitmap
64 ****************************************************************************/
65 BOOL bitmap_set(struct bitmap *bm, unsigned i)
66 {
67         if (i >= bm->n) {
68                 DEBUG(0,("Setting invalid bitmap entry %d (of %d)\n",
69                       i, bm->n));
70                 return False;
71         }
72         bm->b[i/32] |= (1<<(i%32));
73         return True;
74 }
75
76 /****************************************************************************
77 clear a bit in a bitmap
78 ****************************************************************************/
79 BOOL bitmap_clear(struct bitmap *bm, unsigned i)
80 {
81         if (i >= bm->n) {
82                 DEBUG(0,("clearing invalid bitmap entry %d (of %d)\n",
83                       i, bm->n));
84                 return False;
85         }
86         bm->b[i/32] &= ~(1<<(i%32));
87         return True;
88 }
89
90 /****************************************************************************
91 query a bit in a bitmap
92 ****************************************************************************/
93 BOOL bitmap_query(struct bitmap *bm, unsigned i)
94 {
95         if (i >= bm->n) return False;
96         if (bm->b[i/32] & (1<<(i%32))) {
97                 return True;
98         }
99         return False;
100 }
101
102 /****************************************************************************
103 find a zero bit in a bitmap starting at the specified offset, with
104 wraparound
105 ****************************************************************************/
106 int bitmap_find(struct bitmap *bm, unsigned ofs)
107 {
108         int i, j;
109
110         if (ofs > bm->n) ofs = 0;
111
112         i = ofs;
113         while (i < bm->n) {
114                 if (~(bm->b[i/32])) {
115                         j = i;
116                         do {
117                                 if (!bitmap_query(bm, j)) return j;
118                                 j++;
119                         } while (j & 31 && j < bm->n);
120                 }
121                 i += 32;
122                 i &= ~31;
123         }
124
125         i = 0;
126         while (i < ofs) {
127                 if (~(bm->b[i/32])) {
128                         j = i;
129                         do {
130                                 if (!bitmap_query(bm, j)) return j;
131                                 j++;
132                         } while (j & 31 && j < bm->n);
133                 }
134                 i += 32;
135                 i &= ~31;
136         }
137
138         return -1;
139 }