Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / lib / tt / mini_isam / isindfreel.c
1 /*%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                   */
2 /*%%  (c) Copyright 1993, 1994 International Business Machines Corp.     */
3 /*%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                    */
4 /*%%  (c) Copyright 1993, 1994 Novell, Inc.                              */
5 /*%%  $XConsortium: isindfreel.c /main/3 1995/10/23 11:41:03 rswiston $                                                          */
6 #ifndef lint
7 static char sccsid[] = "@(#)isindfreel.c 1.3 89/07/17 Copyr 1988 Sun Micro";
8 #endif
9
10 /*
11  * Copyright (c) 1988 by Sun Microsystems, Inc.
12  */
13
14 /*
15  * isfreelist.c
16  *
17  * Description:
18  *      Free list maintenance functions
19  */
20
21 #include "isam_impl.h"
22
23 extern Bufhdr *_isdisk_fix();
24
25 /*
26  * blkno = _isfreel_alloc()
27  *
28  * Allocate a new index page.
29  */
30
31 Blkno 
32 _isindfreel_alloc(fcb)
33     Fcb                 *fcb;
34 {
35     Bufhdr              *pbhdr;
36     char                *p;
37     int                 npointers;
38     Blkno               blkno;
39
40     if (fcb->indfreelist == FREELIST_NOPAGE) {
41
42         /* 
43          * We must write something to the buffer, or we will get 
44          * segmentation fault when using mapped I/O.
45          */
46         fcb->indsize = _extend_file(fcb, fcb->indfd, fcb->indsize);
47
48         return (fcb->indsize - 1);
49     }
50
51     pbhdr = _isdisk_fix(fcb, fcb->indfd, fcb->indfreelist, ISFIXWRITE);
52     p = pbhdr->isb_buffer;
53     
54     npointers = ldshort(p + FL_NPOINTERS_OFF);
55     
56     if (npointers > 0) {
57         blkno = ldblkno(p + FL_POINTERS_OFF + npointers * BLKNOSIZE);
58         npointers--;
59         stshort((short)npointers, p + FL_NPOINTERS_OFF);
60         
61         return (ldblkno(p + FL_POINTERS_OFF + npointers * BLKNOSIZE));
62     }
63     else {
64         blkno = fcb->indfreelist;
65         fcb->indfreelist = ldblkno(p + FL_NEXT_OFF);
66         
67         return (blkno);
68     }
69 }
70
71 /*
72  * _isfreel_free()
73  *
74  * Free an index page.
75  */
76
77 void
78 _isindfreel_free(fcb, blkno)
79     Fcb                 *fcb;
80     Blkno               blkno;
81 {
82     Bufhdr              *pbhdr;
83     char                *p;
84     int                 npointers;
85
86     if (fcb->indfreelist != FREELIST_NOPAGE) {
87         pbhdr = _isdisk_fix(fcb, fcb->indfd, fcb->indfreelist, ISFIXWRITE);
88         p = pbhdr->isb_buffer;
89
90         npointers = ldshort(p + FL_NPOINTERS_OFF);
91         
92         if (npointers < FL_MAXNPOINTERS) {
93             stblkno(blkno, p + FL_POINTERS_OFF + npointers * BLKNOSIZE);
94             npointers++;
95             stshort((short)npointers, p + FL_NPOINTERS_OFF);
96
97             return;
98         }
99     }
100
101
102     pbhdr = _isdisk_fix(fcb, fcb->indfd, blkno, ISFIXWRITE);
103     p = pbhdr->isb_buffer;
104     
105     /* Mark page to indicate that it is in the free list. */
106     stshort((short)PT_FREELIST, p + FL_TYPE_OFF);
107
108     stshort((short)0, p + FL_NPOINTERS_OFF);
109     stblkno(fcb->indfreelist, p + FL_NEXT_OFF);
110
111     fcb->indfreelist = blkno;
112 }