535 lines
11 KiB
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");
|
|
}
|