2 * bit map routines (in-core).
5 * Copyright (c) 1995, 1996 Marcus D. Watts All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Marcus D. Watts.
18 * 4. The name of the developer may not be used to endorse or promote
19 * products derived from this software without specific prior written
22 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25 * MARCUS D. WATTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <afsconfig.h>
35 #include <afs/param.h>
44 #undef PRINT_MAP_ERROR
45 /* #define MAP_DEBUG /**/
46 /* #define NEED_READ_WRITE /**/
49 #define MSHIFT 8 /* XXX make this 8 in the production version... */
50 #define MDATA (1<<MSHIFT)
52 struct bitmap *m_next;
57 #define MAP(p) ((struct bitmap*)((long)(p)&~1))
58 #define NEGMAP(p) (((int)(p))&1)
59 #define POSMAP(p) (!NEGMAP(p))
60 #define NOT_MAP(mp) ((struct map *) (((long)(mp)) ^ 1))
62 #define NUMBERTOBIT(n) ((n) & ((1<<LSHIFT)-1))
63 #define NUMBERTOINDEX(n) ((n>>LSHIFT) & ((1<<MSHIFT)-1))
64 #define NUMBERTOPAGE(n) ((n>>(LSHIFT+MSHIFT)))
65 #define TONUMBER(p,x,b) ((b) + ((x)<<LSHIFT) + ((p)<<((LSHIFT+MSHIFT))))
67 #define Mflag (debug_mask & (1L<<('Y'-'@')))
68 #define Aflag (debug_mask & (1L<<('Z'-'@')))
69 extern int debug_mask;
72 int in_map(struct map *parm, long node)
74 int in_map(parm, node)
87 printf ("in_map: is %d in [", node);
92 bit = NUMBERTOBIT(node);
93 x = NUMBERTOINDEX(node);
94 page = NUMBERTOPAGE(node);
97 if (TONUMBER(page,x,bit) != node)
99 printf ("bxp mixup: node=%ld -> p=%d x=%d b=%d -> %ld, %ld, %ld = %ld\n",
107 TONUMBER(page,x,bit));
112 for (map = MAP(parm); map; map = map->m_next)
113 if (map->m_page == page)
114 return NEGMAP(parm) ^ (!!(map->m_data[x] & bit));
115 result = !POSMAP(parm);
118 printf (" -> %s\n", result ? "yes" : "no");
127 struct bitmap *map, *next;
131 printf ("Freeing map");
144 struct map *add_map(parm, node)
155 printf ("add_map: adding %d to [", node);
160 bit = NUMBERTOBIT(node);
161 x = NUMBERTOINDEX(node);
162 page = NUMBERTOPAGE(node);
166 for (map = MAP(parm); map; map = map->m_next)
167 if (map->m_page == page)
170 map = (struct bitmap *) malloc(sizeof *map);
172 #ifdef PRINT_MAP_ERROR
173 printf ("No memory!\n");
175 free_map((struct map *) map);
179 bzero((char*) map->m_data, sizeof map->m_data);
183 for (i = 0; i < MDATA; ++i)
186 map->m_next = MAP(parm);
188 parm = (struct map *) map;
193 map->m_data[x] |= bit;
195 map->m_data[x] &= ~bit;
204 return (struct map *) parm;
211 struct bitmap **mpp, *mp2;
213 for (mpp = ↦ mp2 = *mpp; )
215 for (i = 0; i < MDATA; ++i)
219 #ifdef PRINT_MAP_ERROR
220 printf ("simplify_bitmap: failed to eliminate zero page %d\n", mp2->m_page);
225 else mpp = &mp2->m_next;
230 struct bitmap *or_bitmap(left, right)
231 struct bitmap *left, *right;
233 struct bitmap **rightmp, *lmap, *rmap;
235 for (lmap = left; lmap; lmap = lmap->m_next)
237 for (rightmp = &right; rmap = *rightmp; rightmp = &rmap->m_next)
238 if (rmap->m_page == lmap->m_page)
240 for (i = 0; i < MDATA; ++i)
241 lmap->m_data[i] |= rmap->m_data[i];
242 *rightmp = rmap->m_next;
247 for (rightmp = &left; *rightmp; rightmp = &(*rightmp)->m_next)
253 struct bitmap *and_bitmap(left, right)
254 struct bitmap *left, *right;
256 struct bitmap **rightmp, *lmap, *rmap, **leftmp;
259 for (leftmp = &left; lmap = *leftmp; )
262 for (rightmp = &right; rmap = *rightmp; rightmp = &rmap->m_next)
263 if (rmap->m_page == lmap->m_page)
265 for (i = 0; i < MDATA; ++i)
266 sig |= (lmap->m_data[i] &= rmap->m_data[i]);
267 *rightmp = rmap->m_next;
273 leftmp = &lmap->m_next;
275 *leftmp = lmap->m_next;
279 free_map((struct map *) right);
280 return simplify_bitmap(left);
283 /* bit set in left, but not in right */
284 struct bitmap *bic_bitmap(left, right)
285 struct bitmap *left, *right;
287 struct bitmap **rightmp, *lmap, *rmap, **leftmp;
293 printf ("bic_bitmap: left=%#lx right=%#lx\n", left, right);
296 for (leftmp = &left; lmap = *leftmp; )
299 for (rightmp = &right; rmap = *rightmp; rightmp = &rmap->m_next)
300 if (rmap->m_page == lmap->m_page)
302 for (i = 0; i < MDATA; ++i)
303 sig |= (lmap->m_data[i] &= ~rmap->m_data[i]);
304 *rightmp = rmap->m_next;
310 leftmp = &lmap->m_next;
312 *leftmp = lmap->m_next;
316 free_map((struct map *) right);
317 left = simplify_bitmap(left);
321 printf ("bic_bitmap: result=%#lx\n", left);
327 struct map *and_map(mp1, mp2)
328 struct map *mp1, *mp2;
333 printf ("Anding maps");
341 mp1 = (struct map *) and_bitmap(mp1, mp2);
343 mp1 = (struct map *) bic_bitmap(mp1, MAP(mp2));
346 mp1 = (struct map *) bic_bitmap(mp2, MAP(mp1));
348 mp1 = NOT_MAP(or_bitmap(MAP(mp1), MAP(mp2)));
360 struct map *or_map(mp1, mp2)
361 struct map *mp1, *mp2;
366 printf ("Oring maps");
374 mp1 = (struct map *) or_bitmap(mp1, mp2);
376 mp1 = NOT_MAP(bic_bitmap(MAP(mp2), mp1));
379 mp1 = NOT_MAP(bic_bitmap(MAP(mp1), mp2));
381 mp1 = NOT_MAP(and_bitmap(MAP(mp1), MAP(mp2)));
393 struct map *not_map(map)
399 printf ("Notting map");
407 struct map *copy_map(parm)
410 struct bitmap *result, **mpp, *map;
420 for (mpp = &result; *mpp = 0, map; map = map->m_next) {
421 *mpp = (struct bitmap *) malloc(sizeof **mpp);
425 printf ("copy_map: out of memory\n");
427 free_map((struct map *) result);
432 mpp = &(*mpp)->m_next;
435 return NOT_MAP(result);
437 return (struct map*) result;
449 for (map = MAP(parm); map; map = map->m_next)
451 for (i = 0; i < MDATA; ++i)
455 else if (!~map->m_data[i])
457 else for (j = 0; j < (1L<<LSHIFT); ++j)
458 if (map->m_data[i] & (1L<<j))
463 nf = ~nf; /* note 1's complement */
467 printf ("countmap:");
469 printf (" -> %d\n", nf);
480 struct bitmap *map, *lowest;
490 printf ("next_map: selecting next after %d from", node);
497 printf ("next_map failed; negative map\n");
503 bit = NUMBERTOBIT(node);
504 x = NUMBERTOINDEX(node);
505 page = NUMBERTOPAGE(node);
509 for (map = MAP(parm); map; map = map->m_next)
510 if (map->m_page >= page && (!lowest || lowest->m_page > map->m_page))
513 if (page == map->m_page) i = x, mask = -bit;
514 for (; i < MDATA; ++i, mask = ~0)
515 if (map->m_data[i] & mask) break;
517 for (bn = 0; bn < (1<<LSHIFT); ++bn)
518 if (map->m_data[i]&mask&(1L<<bn)) {
524 if (bn == (1<<LSHIFT)){
525 printf ("next_map: botch; pageno %d index %d data %#lx mask %#lx x,bit %d,%#lx\n",
535 best = bn + ((i+((map->m_page)<<MSHIFT)
543 printf (" -> %d\n", best);
544 if (best >= 0 && !in_map((struct map *) parm, best)) {
545 printf ("next_map: botch; %d not in map\n", best);
557 return next_map(parm, -9999);
565 struct bitmap *map, *lowest;
575 printf ("prev_map: selecting previous before %d from", node);
582 printf ("prev_map failed; negative map\n");
588 node = ((unsigned long)~0)>>1;
591 bit = NUMBERTOBIT(node);
592 x = NUMBERTOINDEX(node);
593 page = NUMBERTOPAGE(node);
597 for (map = MAP(parm); map; map = map->m_next)
598 if (map->m_page <= page && (!lowest || lowest->m_page < map->m_page))
600 i = MDATA-1; mask = ~0;
601 if (page == map->m_page) i = x, mask = (bit<<1)-1;
602 for (; i >= 0; --i, mask = ~0)
603 if (map->m_data[i] & mask) break;
605 for (bn = (1<<LSHIFT)-1; bn >= 0; --bn)
606 if (map->m_data[i]&mask&(1L<<bn)) {
613 printf ("prev_map: botch; pageno %d index %d data %#lx mask %#lx x,bit %d,%#lx\n",
623 best = bn + ((i+((map->m_page)<<MSHIFT)
631 printf (" -> %d\n", best);
632 if (best >= 0 && !in_map(parm, best)) {
633 printf ("prev_map: botch; %d not in map\n", best);
645 return prev_map(parm, 0x7fffffff);
648 struct map *negative_map(map)
651 return (struct map *) NEGMAP(map);
654 struct map *bic_map(mp1, mp2)
655 struct map *mp1, *mp2;
666 mp1 = and_map(mp1, NOT_MAP(mp2));
678 #ifdef PRINT_MAP_ERROR
684 int bitno, firstbitno, lastbitno;
690 printf (" nil(%lx)", parm);
691 else printf (" %lx", parm);
694 for (; map; map = map->m_next)
695 for (i = 0; i < MDATA; ++i)
697 for (j = 0; j < (1<<LSHIFT); ++j)
701 ((map->m_page)<<(LSHIFT+MSHIFT));
702 if (map->m_data[i] & (1<<j))
704 if (bitno == lastbitno + 1)
709 if (bitno != (lastbitno + 1)) {
711 && firstbitno != lastbitno)
712 printf ("-%d", lastbitno);
717 firstbitno = lastbitno = bitno;
719 if (firstbitno >= 0 && firstbitno != lastbitno)
720 printf ("-%d", lastbitno);
724 if (firstbitno >= 0 && firstbitno != lastbitno)
725 printf ("-%d", lastbitno);
729 #ifdef NEED_READ_WRITE
735 struct bitmap *map, *result, **mp;
737 int bitno, lastno, thisno, prevno;
741 /* count, then startbitno, then bits. */
742 lastno = ((*f)(arg));
745 if (lastno & ((1<<LSHIFT)-1))
747 #ifdef PRINT_MAP_ERROR
748 printf ("read_map: bad count\n");
753 if (bitno & ((1<<LSHIFT)-1))
755 #ifdef PRINT_MAP_ERROR
756 printf ("read_map: bad start\n");
762 for (; bitno < lastno; bitno += (1<<LSHIFT))
766 page = NUMBERTOPAGE(bitno);
767 if (!map || map->m_page != page)
768 for (mp = &result; map = *mp; mp = &map->m_next)
769 if (map->m_page == page)
773 map = (struct bitmap *) malloc(sizeof *map);
775 #ifdef PRINT_MAP_ERROR
776 printf ("No memory!\n");
779 free_map((struct map *) result);
782 bzero((char*) map->m_data, sizeof map->m_data);
787 map->m_data[NUMBERTOINDEX(bitno)] = data;
789 return (struct map *) result;
792 write_map(parm, f, arg)
799 int bitno, lastno, thisno, prevno;
802 bitno = first_map(parm);
803 bitno &= ~((1<<LSHIFT)-1);
805 lastno = last_map(parm);
807 lastno += ((1<<LSHIFT));
808 lastno &= ~((1<<LSHIFT)-1);
809 /* count, then startbitno, then bits. */
810 if ((*f)(arg, lastno) == -1)
812 /* word: number of bits */
813 if ((*f)(arg, bitno) == -1)
817 for (bitno = first_map(parm); bitno >= 0; bitno = next_map(parm, bitno))
819 page = NUMBERTOPAGE(bitno);
820 for (map = MAP(parm); map; map = map->m_next)
821 if (map->m_page == page)
825 #ifdef PRINT_MAP_ERROR
826 printf ("write_map: botch #1: can't find page %d\n", page);
830 for (i = 0; i < MDATA; ++i)
834 thisno = TONUMBER(page, i, 0);
835 for (j = thisno - prevno; j > 0; j -= (1<<LSHIFT))
836 if ((*f)(arg, 0) == -1)
841 if ((*f)(arg, map->m_data[i]) == -1)
843 prevno += (1<<LSHIFT);
845 if (i >= MDATA || !map->m_data[i])
850 bitno = TONUMBER(page, i, 0)-1;
852 #ifdef PRINT_MAP_ERROR
853 if (prevno != lastno)
854 printf ("write_map: botch #2: bitno=%d prevno=%d lastno=%d\n", bitno, prevno, lastno);