cdesktopenv/cde/lib/tt/bin/ttdbserverd/dm_access_cache.C

535 lines
11 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
//%% (c) Copyright 1993, 1994 Novell, Inc.
//%% $XConsortium: dm_access_cache.C /main/3 1995/10/20 16:40:39 rswiston $
/*
* Tool Talk Database Manager - dm_access_cache.h
*
* Copyright (c) 1989 Sun Microsystems, Inc.
*
* This file contains class implementation for the oid access info cache.
*
*/
#include "dm_access_cache.h"
#include <memory.h>
#include <stdlib.h>
#include <isam.h>
implement_ptr_to(_Tt_oid_access)
implement_ptr_to(_Tt_oid_access_elem)
implement_ptr_to(_Tt_oid_access_queue)
implement_ptr_to(_Tt_link_access)
implement_ptr_to(_Tt_link_access_elem)
implement_ptr_to(_Tt_link_access_queue)
static char _tt_access_record[ISMAXRECLEN];
/*
* class _Tt_oid_access
*/
_Tt_oid_access::_Tt_oid_access(char *ku)
{
memcpy(_key, ku, OID_KEY_LENGTH);
memcpy((char *)&_user, ku + OID_KEY_LENGTH, sizeof(uid_t));
memcpy((char *)&_group, ku + OID_KEY_LENGTH + sizeof(uid_t),
sizeof(gid_t));
memcpy((char *)&_mode,
ku + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
sizeof(mode_t));
}
_Tt_oid_access::_Tt_oid_access(const char *key, uid_t user, gid_t group,
mode_t mode)
{
memcpy(_key, key, OID_KEY_LENGTH);
_user = user;
_group = group;
_mode = mode;
}
_Tt_oid_access::~_Tt_oid_access()
{
}
char *
_Tt_oid_access::rec()
{
memcpy(_tt_access_record, _key, OID_KEY_LENGTH);
memcpy(_tt_access_record + OID_KEY_LENGTH, (char *)&_user,
sizeof(uid_t));
memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t),
(char *)&_group, sizeof(gid_t));
memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
(char *)&_mode, sizeof(mode_t));
return _tt_access_record;
}
void
_Tt_oid_access::print(FILE *fs) const
{
fprintf(fs, "oid-access entry: ");
fprintf(fs, "key - <%d, %d, %d, %d>, user = %d\n",
*((short *) ((char *)_key)),
*((int *) ((char *)_key + 4)), *((int *) ((char *)_key + 8)),
*((int *) ((char *)_key + 12)), _user);
}
/*
* class _Tt_oid_access_elem
*/
_Tt_oid_access_elem::_Tt_oid_access_elem(_Tt_oid_access_ptr oa,
_Tt_oid_access_elem_ptr next)
{
_oa = oa;
_next = next;
}
void
_Tt_oid_access_elem::print(FILE *fs) const
{
_oa->print(fs);
}
/*
* class _Tt_oid_access_queue
*/
_Tt_oid_access_queue::_Tt_oid_access_queue()
{
_head = _tail = 0;
_len = 0;
for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
_table[i] = 0;
}
}
_Tt_oid_access_queue::~_Tt_oid_access_queue()
{
}
void
_Tt_oid_access_queue::enqueue(_Tt_oid_access_ptr oa)
{
if (_len == DM_MAX_ACCESS_ELEMS) {
dequeue();
}
/* put the new element on the LRU list */
_Tt_oid_access_elem_ptr oae = new _Tt_oid_access_elem(oa, _head);
if (_head.is_null()) {
_tail = oae;
}
_head = oae;
/* put the new element in the lookup table */
int bucket = hash(oa->key());
_table[bucket] = new _Tt_oid_access_elem(oa, _table[bucket]);
_len++;
}
_Tt_oid_access_ptr
_Tt_oid_access_queue::lookup(const char *key)
{
if (!key) { /* erroneous condition, read by record number needs key */
return 0;
}
int bucket_no = hash(key);
_Tt_oid_access_elem_ptr e = _table[bucket_no];
while (!e.is_null()) {
_Tt_oid_access_ptr oa = e->oa();
if (memcmp(oa->key(), key, OID_KEY_LENGTH) == 0) {
return oa;
}
e = e->next();
}
return 0;
}
/*
* remove - remove the oid access element from both the LRU list and the lookup
* table. Does not delete the element.
*/
void
_Tt_oid_access_queue::remove(_Tt_oid_access_ptr oa)
{
/* remove from the LRU list */
_Tt_oid_access_elem_ptr prev = 0;
_Tt_oid_access_elem_ptr cur = _head;
while (!cur.is_null()) {
if (cur->oa().is_eq(oa)) {
if (prev.is_null()) {
_head = _head->next();
} else {
prev->set_next(cur->next());
}
if (cur.is_eq(_tail)) {
_tail = prev;
}
break;
} else {
prev = cur;
cur = cur->next();
}
}
/* remove from the lookup table */
int bucket = hash(oa->key());
prev = 0;
cur = _table[bucket];
while (!cur.is_null()) {
if (cur->oa().is_eq(oa)) {
if (prev.is_null()) {
_table[bucket] = _table[bucket]->next();
} else {
prev->set_next(cur->next());
}
break;
} else {
prev = cur;
cur = cur->next();
}
}
--_len;
}
/*
* promote - promote the oid access element to the front of the LRU list.
*/
void
_Tt_oid_access_queue::promote(_Tt_oid_access_ptr oa)
{
if (_head->oa().is_eq(oa)) {
return;
}
/* remove from the LRU list */
_Tt_oid_access_elem_ptr prev = _head;
_Tt_oid_access_elem_ptr cur = prev->next();
while (!cur.is_null()) {
if (cur->oa().is_eq(oa)) {
prev->set_next(cur->next());
if (cur.is_eq(_tail)) {
_tail = prev;
}
cur->set_next(_head);
_head = cur;
break;
} else {
prev = cur;
cur = cur->next();
}
}
}
/*
* Remove the LRU element from the LRU list and lookup table and deletes it.
*/
void
_Tt_oid_access_queue::dequeue()
{
if (!_tail.is_null()) {
remove(_tail->oa());
}
}
int
_Tt_oid_access_queue::hash(const char *key)
{
int hash_value = 0;
for (int i = 0; i < OID_KEY_LENGTH; i++) {
hash_value += key[i] & 0177; /* ignore sign */
}
hash_value = abs(hash_value);
return (hash_value % DM_OID_ACCESS_BUCKETS);
}
void
_Tt_oid_access_queue::print(FILE *fs) const
{
fprintf(fs, "\nOID-ACCESS QUEUE list (len = %d):\n", _len);
_Tt_oid_access_elem_ptr e = _head;
while (!e.is_null()) {
e->print(fs);
e = e->next();
}
fprintf(fs, "OID-ACCESS QUEUE table:\n");
for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
e = _table[i];
if (!e.is_null()) {
fprintf(fs, "bucket %d:\n", i);
while (!e.is_null()) {
e->print(fs);
e = e->next();
}
}
}
fprintf(fs, "\n");
}
/*
* class _Tt_link_access
*/
_Tt_link_access::_Tt_link_access(char *kp)
{
memcpy(_key, kp, OID_KEY_LENGTH);
memcpy((char *)&_user, kp + OID_KEY_LENGTH, sizeof(uid_t));
memcpy((char *)&_group, kp + OID_KEY_LENGTH + sizeof(uid_t),
sizeof(gid_t));
memcpy((char *)&_mode,
kp + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
sizeof(mode_t));
}
_Tt_link_access::_Tt_link_access(const char *key, uid_t user, gid_t group,
mode_t mode)
{
memcpy(_key, key, OID_KEY_LENGTH);
_user = user;
_group = group;
_mode = mode;
}
_Tt_link_access::~_Tt_link_access()
{
}
char *
_Tt_link_access::rec()
{
memcpy(_tt_access_record, _key, OID_KEY_LENGTH);
memcpy(_tt_access_record + OID_KEY_LENGTH, (char *)&_user,
sizeof(uid_t));
memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t),
(char *)&_group, sizeof(gid_t));
memcpy(_tt_access_record + OID_KEY_LENGTH + sizeof(uid_t) + sizeof(gid_t),
(char *)&_mode, sizeof(mode_t));
return _tt_access_record;
}
void
_Tt_link_access::print(FILE *fs) const
{
fprintf(fs, "link-access entry: ");
fprintf(fs, "key - <%d, %d, %d, %d>, user = %d\n",
*((short *) ((char *)_key)),
*((int *) ((char *)_key + 4)), *((int *) ((char *)_key + 8)),
*((int *) ((char *)_key + 12)), _user);
}
/*
* class _Tt_link_access_elem
*/
_Tt_link_access_elem::_Tt_link_access_elem(_Tt_link_access_ptr oa,
_Tt_link_access_elem_ptr next)
{
_oa = oa;
_next = next;
}
void
_Tt_link_access_elem::print(FILE *fs) const
{
_oa->print(fs);
}
/*
* class _Tt_link_access_queue
*/
_Tt_link_access_queue::_Tt_link_access_queue()
{
_head = _tail = 0;
_len = 0;
for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
_table[i] = 0;
}
}
_Tt_link_access_queue::~_Tt_link_access_queue()
{
}
void
_Tt_link_access_queue::enqueue(_Tt_link_access_ptr oa)
{
if (_len == DM_MAX_ACCESS_ELEMS) {
dequeue();
}
/* put the new element on the LRU list */
_Tt_link_access_elem_ptr oae = new _Tt_link_access_elem(oa, _head);
if (_head.is_null()) {
_tail = oae;
}
_head = oae;
/* put the new element in the lookup table */
int bucket = hash(oa->key());
_table[bucket] = new _Tt_link_access_elem(oa, _table[bucket]);
_len++;
}
_Tt_link_access_ptr
_Tt_link_access_queue::lookup(const char *key)
{
if (!key) { /* erroneous condition, read by record number needs key */
return 0;
}
_Tt_link_access_elem_ptr e = _table[hash(key)];
while (!e.is_null()) {
_Tt_link_access_ptr oa = e->oa();
if (memcmp(oa->key(), key, OID_KEY_LENGTH) == 0) {
return oa;
}
e = e->next();
}
return 0;
}
/*
* remove - remove the oid access element from both the LRU list and the lookup
* table. Does not delete the element.
*/
void
_Tt_link_access_queue::remove(_Tt_link_access_ptr oa)
{
/* remove from the LRU list */
_Tt_link_access_elem_ptr prev = 0;
_Tt_link_access_elem_ptr cur = _head;
while (!cur.is_null()) {
if (cur->oa().is_eq(oa)) {
if (prev.is_null()) {
_head = _head->next();
} else {
prev->set_next(cur->next());
}
if (cur.is_eq(_tail)) {
_tail = prev;
}
break;
} else {
prev = cur;
cur = cur->next();
}
}
/* remove from the lookup table */
int bucket = hash(oa->key());
prev = 0;
cur = _table[bucket];
while (!cur.is_null()) {
if (cur->oa().is_eq(oa)) {
if (prev.is_null()) {
_table[bucket] = _table[bucket]->next();
} else {
prev->set_next(cur->next());
}
break;
} else {
prev = cur;
cur = cur->next();
}
}
--_len;
}
/*
* promote - promote the oid access element to the front of the LRU list.
*/
void
_Tt_link_access_queue::promote(_Tt_link_access_ptr oa)
{
if (_head->oa().is_eq(oa)) {
return;
}
/* remove from the LRU list */
_Tt_link_access_elem_ptr prev = _head;
_Tt_link_access_elem_ptr cur = prev->next();
while (!cur.is_null()) {
if (cur->oa().is_eq(oa)) {
prev->set_next(cur->next());
if (cur.is_eq(_tail)) {
_tail = prev;
}
cur->set_next(_head);
_head = cur;
break;
} else {
prev = cur;
cur = cur->next();
}
}
}
/*
* Remove the LRU element from the LRU list and lookup table and deletes it.
*/
void
_Tt_link_access_queue::dequeue()
{
if (!_tail.is_null()) {
remove(_tail->oa());
}
}
int
_Tt_link_access_queue::hash(const char *key)
{
int hash_value = 0;
for (int i = 0; i < OID_KEY_LENGTH; i++) {
hash_value += key[i] & 0177; /* ignore sign */
}
hash_value = abs(hash_value);
return (hash_value % DM_OID_ACCESS_BUCKETS);
}
void
_Tt_link_access_queue::print(FILE *fs) const
{
fprintf(fs, "\nLINK-ACCESS QUEUE list (len = %d):\n", _len);
_Tt_link_access_elem_ptr e = _head;
while (!e.is_null()) {
e->print(fs);
e = e->next();
}
fprintf(fs, "LINK-ACCESS QUEUE table:\n");
for (int i = 0; i < DM_OID_ACCESS_BUCKETS; i++) {
e = _table[i];
if (!e.is_null()) {
fprintf(fs, "bucket %d:\n", i);
while (!e.is_null()) {
e->print(fs);
e = e->next();
}
}
}
fprintf(fs, "\n");
}