Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / diskhash / disk_bucket.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  * $XConsortium: disk_bucket.cc /main/4 1996/06/11 17:16:00 cde-hal $
25  *
26  * Copyright (c) 1993 HAL Computer Systems International, Ltd.
27  * All rights reserved.  Unpublished -- rights reserved under
28  * the Copyright Laws of the United States.  USE OF A COPYRIGHT
29  * NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
30  * OR DISCLOSURE.
31  * 
32  * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE
33  * SECRETS OF HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.  USE,
34  * DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE
35  * PRIOR EXPRESS WRITTEN PERMISSION OF HAL COMPUTER SYSTEMS
36  * INTERNATIONAL, LTD.
37  * 
38  *                         RESTRICTED RIGHTS LEGEND
39  * Use, duplication, or disclosure by the Government is subject
40  * to the restrictions as set forth in subparagraph (c)(l)(ii)
41  * of the Rights in Technical Data and Computer Software clause
42  * at DFARS 252.227-7013.
43  *
44  *          HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.
45  *                  1315 Dell Avenue
46  *                  Campbell, CA  95008
47  * 
48  */
49
50
51
52 #include "diskhash/disk_bucket.h"
53 #include "api/transaction.h"
54
55 //#define BKT_PARAMS_SIZE  (sizeof(char) + sizeof(v_k) + sizeof(v_r))
56 #define BKT_PARAMS_SIZE  (sizeof(char))
57
58 //static buffer buf(LBUFSIZ);
59
60 extern transaction* g_transac;
61
62 disk_bucket::disk_bucket(int bnum, page_storage* store) : 
63 v_bucket_num(bnum), v_key_store(store), v_overflowed(false),
64 buf(store -> aux_buf())
65 {
66    buf.set_swap_order(store -> swap_order());
67    init_params();
68 }
69
70 disk_bucket::~disk_bucket()
71 {
72 }
73
74 page* disk_bucket::bucket_page()
75 {
76    if ( g_transac ) {
77       g_transac -> book(v_key_store);
78    }
79    return (*v_key_store)(v_bucket_num+2, page_storage::READ);
80 }
81
82 void disk_bucket::init_params()
83 {
84    page* p = bucket_page();
85    buf.reset();
86
87    if ( p -> count() > 1 ) {
88       p -> get(1, buf);
89       char c; buf.get(c); v_overflowed = c;
90       //buf.get(v_k);
91       //buf.get(v_r);
92    } else {
93
94       v_key_store -> save_to_log(p);
95
96       int slot_num; char* z;
97       p -> alloc_slot(slot_num, BKT_PARAMS_SIZE, z);
98       if ( slot_num != 1 ) {
99          debug(cerr, v_bucket_num+2);
100          debug(cerr, slot_num);
101          throw(stringException("corrupted disk bucket"));
102       } 
103       char c = v_overflowed; buf.put(c);
104       p -> update_slot(1, buf);
105
106
107 /*
108       MESSAGE(cerr, "bucket OK");
109       debug(cerr, int(p));
110       debug(cerr, v_bucket_num+2);
111 */
112    }
113 }
114
115 void disk_bucket::sync_params()
116 {
117    page* p = bucket_page();
118
119    v_key_store -> save_to_log(p);
120
121    buf.reset();
122
123    char c = v_overflowed; buf.put(c);
124    //buf.put(v_k);
125    //buf.put(v_r);
126
127    p -> update_slot(1, buf);
128 }
129
130 Boolean disk_bucket::member(data_t& v, int& slot_num)
131 {
132 //debug(cerr, v);
133    data_t *x = 0;
134
135 ////////////////////////////////////
136 // use the hint, if slot_num != 0 
137 ////////////////////////////////////
138
139 //debug(cerr, bucket_page() -> count());
140 //debug(cerr, slot_num);
141
142    if ( slot_num != 0 && count() >= slot_num ) {
143
144 //MESSAGE(cerr, "probe the slot");
145       x = (*this)(slot_num);
146
147       if ( x && *x == v ) {
148
149          v.dt = x -> dt;
150          delete x;
151          return true;
152       }
153       delete x;
154
155    }
156
157 /////////////////////////
158 // do a linear search 
159 /////////////////////////
160    int ind = first();
161 //debug(cerr, ind);
162    while ( ind && ind != slot_num ) {
163 //MESSAGE(cerr, "linearly search the bucket");
164       x = (*this)(ind);
165 //debug(cerr, *x);
166       if ( x && *x == v ) {
167          v.dt = x -> dt;
168          delete x;
169          slot_num = ind;
170          return true;
171       }
172       delete x;
173       next(ind);
174    }
175    return false;
176 }
177
178 int disk_bucket::insert(data_t* data)
179 {
180 //MESSAGE(cerr, "disk_bucket::insert()");
181    buf.reset();
182    data -> binaryOut(buf);
183 //debug(cerr, buf.content_sz());
184
185    int slot_num = 0;
186    page* p = bucket_page();
187
188    v_key_store -> save_to_log(p);
189
190    if (  p -> free_bytes() > buf.content_sz() ) {
191       p -> put( slot_num, buf );
192    } else {
193       set_overflow(true); 
194       sync_params();
195    }
196
197    return slot_num; 
198 }
199
200 Boolean disk_bucket::remove(int ind)
201 {
202    page* p = bucket_page();
203    v_key_store -> save_to_log(p);
204
205    p -> del_slot(ind);
206
207    return true;
208 }
209
210 void disk_bucket::remove_all()
211 {
212    bucket_page() -> clean_all();
213    init_params();
214 }
215
216 /*
217 int disk_bucket::first()
218 {
219    int ind = 0;
220    next(ind);
221    return ind;
222 }
223 */
224
225 data_t* disk_bucket::operator()(int ind)
226 {
227    buf.reset();
228
229    if ( bucket_page() -> get( ind+1, buf ) == false ) return 0;
230
231    data_t *x = new data_t;
232    x-> binaryIn(buf);
233
234    return x;
235 }
236
237 /*
238 void disk_bucket::next(int& ind)
239 {
240    ind = ( ind >= count() ) ? 0 : ind+1;
241 }
242
243 int disk_bucket::count()
244 {
245    return MAX(0, bucket_page() -> count() - 2);
246 }
247
248 Boolean disk_bucket::empty()
249 {
250    return ( count() == 0 ) ? true : false;
251 }
252 */
253
254 ostream& disk_bucket::asciiOut(ostream& out, print_func_ptr_t print_f)
255 {
256   int ind = first();
257    while ( ind != 0 ) {
258
259       data_t* x = (*this)(ind);
260
261       if ( x )
262         x -> asciiOut(out, print_f);
263
264       delete x;
265
266       next(ind);
267    }
268    return out;
269 }
270
271 ostream& operator<<(ostream& out, disk_bucket& bt)
272 {
273 //MESSAGE(cerr, "in disk_bucket::<<");
274 //debug(cerr, bt.bucket_page() -> count());
275
276    int ind = bt.first();
277    while ( ind != 0 ) {
278
279       data_t* x = bt(ind);
280
281       if ( x )
282          out << *x << "\n";
283
284       delete x;
285
286       bt.next(ind);
287    }
288    return out;
289 }