Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / tt / bin / ttdbserverd / dm_access_cache.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 //%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                  
24 //%%  (c) Copyright 1993, 1994 International Business Machines Corp.    
25 //%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                   
26 //%%  (c) Copyright 1993, 1994 Novell, Inc.                             
27 //%%  $XConsortium: dm_access_cache.C /main/3 1995/10/20 16:40:39 rswiston $                                                    
28 /*
29  *  Tool Talk Database Manager - dm_access_cache.h
30  *
31  *  Copyright (c) 1989 Sun Microsystems, Inc.
32  *
33  *  This file contains class implementation for the oid access info cache.
34  *
35  */
36
37 #include "dm_access_cache.h"
38 #include <memory.h>
39 #include <stdlib.h>
40 #include <isam.h>
41
42 implement_ptr_to(_Tt_oid_access)
43 implement_ptr_to(_Tt_oid_access_elem)
44 implement_ptr_to(_Tt_oid_access_queue)
45 implement_ptr_to(_Tt_link_access)
46 implement_ptr_to(_Tt_link_access_elem)
47 implement_ptr_to(_Tt_link_access_queue)
48
49 static char _tt_access_record[ISMAXRECLEN];
50
51 /*
52  *  class _Tt_oid_access
53  */
54
55 _Tt_oid_access::_Tt_oid_access(char *ku)
56 {
57         memcpy(_key, ku, OID_KEY_LENGTH);
58         memcpy((char *)&_user, ku + OID_KEY_LENGTH, sizeof(uid_t));
59         memcpy((char *)&_group, ku + OID_KEY_LENGTH + sizeof(uid_t),
60                sizeof(gid_t));
61         memcpy((char *)&_mode,
62                ku + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
63                sizeof(mode_t));
64 }
65
66 _Tt_oid_access::_Tt_oid_access(const char *key, uid_t user, gid_t group,
67                                mode_t mode)
68 {
69         memcpy(_key, key, OID_KEY_LENGTH);
70         _user = user;
71         _group = group;
72         _mode = mode;
73 }
74
75 _Tt_oid_access::~_Tt_oid_access()
76 {
77 }
78
79 char *
80 _Tt_oid_access::rec()
81 {
82         memcpy(_tt_access_record, _key, OID_KEY_LENGTH);
83         memcpy(_tt_access_record + OID_KEY_LENGTH, (char *)&_user,
84                sizeof(uid_t));
85         memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t),
86                (char *)&_group, sizeof(gid_t));
87         memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
88                (char *)&_mode, sizeof(mode_t));
89         return _tt_access_record;
90 }
91
92 void
93 _Tt_oid_access::print(FILE *fs) const
94 {
95         fprintf(fs, "oid-access entry: ");
96         fprintf(fs, "key - <%d, %d, %d, %d>, user = %d\n",
97                 *((short *) ((char *)_key)),
98                 *((int *) ((char *)_key + 4)), *((int *) ((char *)_key + 8)),
99                 *((int *) ((char *)_key + 12)), _user);
100 }
101
102 /*
103  *  class _Tt_oid_access_elem
104  */
105
106 _Tt_oid_access_elem::_Tt_oid_access_elem(_Tt_oid_access_ptr oa,
107                                          _Tt_oid_access_elem_ptr next)
108 {
109         _oa = oa;
110         _next = next;
111 }
112
113 void
114 _Tt_oid_access_elem::print(FILE *fs) const
115 {
116         _oa->print(fs);
117 }
118
119 /*
120  *  class _Tt_oid_access_queue
121  */
122
123 _Tt_oid_access_queue::_Tt_oid_access_queue()
124 {
125         _head = _tail = 0;
126         _len = 0;
127         for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
128                 _table[i] = 0;
129         }
130 }
131
132 _Tt_oid_access_queue::~_Tt_oid_access_queue()
133 {
134 }
135
136 void
137 _Tt_oid_access_queue::enqueue(_Tt_oid_access_ptr oa)
138 {
139         if (_len == DM_MAX_ACCESS_ELEMS) {
140                 dequeue();
141         }
142         /* put the new element on the LRU list */
143         _Tt_oid_access_elem_ptr oae = new _Tt_oid_access_elem(oa, _head);
144         if (_head.is_null()) {
145                 _tail = oae;
146         }
147         _head = oae;
148         /* put the new element in the lookup table */
149         int bucket = hash(oa->key());
150         _table[bucket] = new _Tt_oid_access_elem(oa, _table[bucket]);
151         _len++;
152 }
153
154 _Tt_oid_access_ptr
155 _Tt_oid_access_queue::lookup(const char *key)
156 {
157         if (!key) {     /* erroneous condition, read by record number needs key */
158                 return 0;
159         }
160         int bucket_no = hash(key);
161         _Tt_oid_access_elem_ptr e = _table[bucket_no];
162         while (!e.is_null()) {
163                 _Tt_oid_access_ptr oa = e->oa();
164                 if (memcmp(oa->key(), key, OID_KEY_LENGTH) == 0) {
165                         return oa;
166                 }
167                 e = e->next();
168         }
169         return 0;
170 }
171
172 /*
173  *  remove - remove the oid access element from both the LRU list and the lookup
174  *  table.  Does not delete the element.
175  */
176
177 void
178 _Tt_oid_access_queue::remove(_Tt_oid_access_ptr oa)
179 {
180         /* remove from the LRU list */
181         _Tt_oid_access_elem_ptr prev = 0;
182         _Tt_oid_access_elem_ptr cur = _head;
183         while (!cur.is_null()) {
184                 if (cur->oa().is_eq(oa)) {
185                         if (prev.is_null()) {
186                                 _head = _head->next();
187                         } else {
188                                 prev->set_next(cur->next());
189                         }
190                         if (cur.is_eq(_tail)) {
191                                 _tail = prev;
192                         }
193                         break;
194                 } else {
195                         prev = cur;
196                         cur = cur->next();
197                 }
198         }
199         /* remove from the lookup table */
200         int bucket = hash(oa->key());
201         prev = 0;
202         cur = _table[bucket];
203         while (!cur.is_null()) {
204                 if (cur->oa().is_eq(oa)) {
205                         if (prev.is_null()) {
206                                 _table[bucket] = _table[bucket]->next();
207                         } else {
208                                 prev->set_next(cur->next());
209                         }
210                         break;
211                 } else {
212                         prev = cur;
213                         cur = cur->next();
214                 }
215         }
216         --_len;
217 }
218
219 /*
220  *  promote - promote the oid access element to the front of the LRU list.
221  */
222
223 void
224 _Tt_oid_access_queue::promote(_Tt_oid_access_ptr oa)
225 {
226         if (_head->oa().is_eq(oa)) {
227                 return;
228         }
229         /* remove from the LRU list */
230         _Tt_oid_access_elem_ptr prev = _head;
231         _Tt_oid_access_elem_ptr cur = prev->next();
232         while (!cur.is_null()) {
233                 if (cur->oa().is_eq(oa)) {
234                         prev->set_next(cur->next());
235                         if (cur.is_eq(_tail)) {
236                                 _tail = prev;
237                         }
238                         cur->set_next(_head);
239                         _head = cur;
240                         break;
241                 } else {
242                         prev = cur;
243                         cur = cur->next();
244                 }
245         }
246 }
247
248 /*
249  *  Remove the LRU element from the LRU list and lookup table and deletes it.
250  */
251
252 void
253 _Tt_oid_access_queue::dequeue()
254 {
255         if (!_tail.is_null()) {
256                 remove(_tail->oa());
257         }
258 }
259
260 int
261 _Tt_oid_access_queue::hash(const char *key)
262 {
263         int hash_value = 0;
264         for (int i = 0; i < OID_KEY_LENGTH; i++) {
265                 hash_value += key[i] & 0177;    /* ignore sign */
266         }
267         hash_value = abs(hash_value);
268         return (hash_value % DM_OID_ACCESS_BUCKETS);
269 }
270
271 void
272 _Tt_oid_access_queue::print(FILE *fs) const
273 {
274         fprintf(fs, "\nOID-ACCESS QUEUE list (len = %d):\n", _len);
275         _Tt_oid_access_elem_ptr e = _head;
276         while (!e.is_null()) {
277                 e->print(fs);
278                 e = e->next();
279         }
280         fprintf(fs, "OID-ACCESS QUEUE table:\n");
281         for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
282                 e = _table[i];
283                 if (!e.is_null()) {
284                         fprintf(fs, "bucket %d:\n", i);
285                         while (!e.is_null()) {
286                                 e->print(fs);
287                                 e = e->next();
288                         }
289                 }
290         }
291         fprintf(fs, "\n");
292 }
293
294 /*
295  *  class _Tt_link_access
296  */
297
298 _Tt_link_access::_Tt_link_access(char *kp)
299 {
300         memcpy(_key, kp, OID_KEY_LENGTH);
301         memcpy((char *)&_user, kp + OID_KEY_LENGTH, sizeof(uid_t));
302         memcpy((char *)&_group, kp + OID_KEY_LENGTH + sizeof(uid_t),
303                sizeof(gid_t));
304         memcpy((char *)&_mode,
305                kp + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
306                sizeof(mode_t));
307 }
308
309 _Tt_link_access::_Tt_link_access(const char *key, uid_t user, gid_t group,
310                                  mode_t mode)
311 {
312         memcpy(_key, key, OID_KEY_LENGTH);
313         _user = user;
314         _group = group;
315         _mode = mode;
316 }
317
318 _Tt_link_access::~_Tt_link_access()
319 {
320 }
321
322 char *
323 _Tt_link_access::rec()
324 {
325         memcpy(_tt_access_record, _key, OID_KEY_LENGTH);
326         memcpy(_tt_access_record + OID_KEY_LENGTH, (char *)&_user,
327                sizeof(uid_t));
328         memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t),
329                (char *)&_group, sizeof(gid_t));
330         memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
331                (char *)&_mode, sizeof(mode_t));
332         return _tt_access_record;
333 }
334
335 void
336 _Tt_link_access::print(FILE *fs) const
337 {
338         fprintf(fs, "link-access entry: ");
339         fprintf(fs, "key - <%d, %d, %d, %d>, user = %d\n",
340                 *((short *) ((char *)_key)),
341                 *((int *) ((char *)_key + 4)), *((int *) ((char *)_key + 8)),
342                 *((int *) ((char *)_key + 12)), _user);
343 }
344
345 /*
346  *  class _Tt_link_access_elem
347  */
348
349 _Tt_link_access_elem::_Tt_link_access_elem(_Tt_link_access_ptr oa,
350                                          _Tt_link_access_elem_ptr next)
351 {
352         _oa = oa;
353         _next = next;
354 }
355
356 void
357 _Tt_link_access_elem::print(FILE *fs) const
358 {
359         _oa->print(fs);
360 }
361
362 /*
363  *  class _Tt_link_access_queue
364  */
365
366 _Tt_link_access_queue::_Tt_link_access_queue()
367 {
368         _head = _tail = 0;
369         _len = 0;
370         for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
371                 _table[i] = 0;
372         }
373 }
374
375 _Tt_link_access_queue::~_Tt_link_access_queue()
376 {
377 }
378
379 void
380 _Tt_link_access_queue::enqueue(_Tt_link_access_ptr oa)
381 {
382         if (_len == DM_MAX_ACCESS_ELEMS) {
383                 dequeue();
384         }
385         /* put the new element on the LRU list */
386         _Tt_link_access_elem_ptr oae = new _Tt_link_access_elem(oa, _head);
387         if (_head.is_null()) {
388                 _tail = oae;
389         }
390         _head = oae;
391         /* put the new element in the lookup table */
392         int bucket = hash(oa->key());
393         _table[bucket] = new _Tt_link_access_elem(oa, _table[bucket]);
394         _len++;
395 }
396
397 _Tt_link_access_ptr
398 _Tt_link_access_queue::lookup(const char *key)
399 {
400         if (!key) {     /* erroneous condition, read by record number needs key */
401                 return 0;
402         }
403         _Tt_link_access_elem_ptr e = _table[hash(key)];
404         while (!e.is_null()) {
405                 _Tt_link_access_ptr oa = e->oa();
406                 if (memcmp(oa->key(), key, OID_KEY_LENGTH) == 0) {
407                         return oa;
408                 }
409                 e = e->next();
410         }
411         return 0;
412 }
413
414 /*
415  *  remove - remove the oid access element from both the LRU list and the lookup
416  *  table.  Does not delete the element.
417  */
418
419 void
420 _Tt_link_access_queue::remove(_Tt_link_access_ptr oa)
421 {
422         /* remove from the LRU list */
423         _Tt_link_access_elem_ptr prev = 0;
424         _Tt_link_access_elem_ptr cur = _head;
425         while (!cur.is_null()) {
426                 if (cur->oa().is_eq(oa)) {
427                         if (prev.is_null()) {
428                                 _head = _head->next();
429                         } else {
430                                 prev->set_next(cur->next());
431                         }
432                         if (cur.is_eq(_tail)) {
433                                 _tail = prev;
434                         }
435                         break;
436                 } else {
437                         prev = cur;
438                         cur = cur->next();
439                 }
440         }
441         /* remove from the lookup table */
442         int bucket = hash(oa->key());
443         prev = 0;
444         cur = _table[bucket];
445         while (!cur.is_null()) {
446                 if (cur->oa().is_eq(oa)) {
447                         if (prev.is_null()) {
448                                 _table[bucket] = _table[bucket]->next();
449                         } else {
450                                 prev->set_next(cur->next());
451                         }
452                         break;
453                 } else {
454                         prev = cur;
455                         cur = cur->next();
456                 }
457         }
458         --_len;
459 }
460
461 /*
462  *  promote - promote the oid access element to the front of the LRU list.
463  */
464
465 void
466 _Tt_link_access_queue::promote(_Tt_link_access_ptr oa)
467 {
468         if (_head->oa().is_eq(oa)) {
469                 return;
470         }
471         /* remove from the LRU list */
472         _Tt_link_access_elem_ptr prev = _head;
473         _Tt_link_access_elem_ptr cur = prev->next();
474         while (!cur.is_null()) {
475                 if (cur->oa().is_eq(oa)) {
476                         prev->set_next(cur->next());
477                         if (cur.is_eq(_tail)) {
478                                 _tail = prev;
479                         }
480                         cur->set_next(_head);
481                         _head = cur;
482                         break;
483                 } else {
484                         prev = cur;
485                         cur = cur->next();
486                 }
487         }
488 }
489
490 /*
491  *  Remove the LRU element from the LRU list and lookup table and deletes it.
492  */
493
494 void
495 _Tt_link_access_queue::dequeue()
496 {
497         if (!_tail.is_null()) {
498                 remove(_tail->oa());
499         }
500 }
501
502 int
503 _Tt_link_access_queue::hash(const char *key)
504 {
505         int hash_value = 0;
506         for (int i = 0; i < OID_KEY_LENGTH; i++) {
507                 hash_value += key[i] & 0177;  /* ignore sign */
508         }
509         hash_value = abs(hash_value);
510         return (hash_value % DM_OID_ACCESS_BUCKETS);
511 }
512
513 void
514 _Tt_link_access_queue::print(FILE *fs) const
515 {
516         fprintf(fs, "\nLINK-ACCESS QUEUE list (len = %d):\n", _len);
517         _Tt_link_access_elem_ptr e = _head;
518         while (!e.is_null()) {
519                 e->print(fs);
520                 e = e->next();
521         }
522         fprintf(fs, "LINK-ACCESS QUEUE table:\n");
523         for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
524                 e = _table[i];
525                 if (!e.is_null()) {
526                         fprintf(fs, "bucket %d:\n", i);
527                         while (!e.is_null()) {
528                                 e->print(fs);
529                                 e = e->next();
530                         }
531                 }
532         }
533         fprintf(fs, "\n");
534 }