Files
cdesktop/cde/programs/dtinfo/DtMmdb/storage/lru.C
2018-04-28 12:30:20 -06:00

245 lines
5.9 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 libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* $XConsortium: lru.cc /main/4 1996/07/18 14:53:29 drk $
*
* Copyright (c) 1992 HaL Computer Systems, Inc. All rights reserved.
* UNPUBLISHED -- rights reserved under the Copyright Laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* This software contains confidential information and trade secrets of HaL
* Computer Systems, Inc. Use, disclosure, or reproduction is prohibited
* without the prior express written permission of HaL Computer Systems, Inc.
*
* RESTRICTED RIGHTS LEGEND
* Use, duplication, or disclosure by the Government is subject to
* restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7013.
* HaL Computer Systems, Inc.
* 1315 Dell Avenue, Campbell, CA 95008
*
*/
#include "storage/lru.h"
lru::lru(int a_sz, int i_sz, Boolean remove_cells) :
rep_policy(a_sz, i_sz), active_list(remove_cells),
inactive_list(remove_cells)
{
}
lru::~lru()
{
}
// Move the last cell in the active list to the end of the
// inactive list.
// Out: replaced points at the last cell from the active list;
// it is zero if the active list is empty.
void lru::lower_last(rep_cell*& replaced)
{
// if the active list is empty, just return
if ( active_list.count() == 0 )
return ;
// delete the last cell from the active list
dlist_cell *atl = active_list.get_tail();
active_list.delete_cell(atl);
// insert the removed last cell into the inactive list (last position)
dlist_cell *itl = inactive_list.get_tail();
inactive_list.insert_after(itl, atl);
replaced = (rep_cell*)atl;
replaced -> set_position(INACTIVE);
}
Boolean
lru::promote(rep_cell& x, rep_cell*& replaced)
{
/*
MESSAGE(cerr, "enter promote");
debug(cerr, int(this));
debug(cerr, active_list.count());
debug(cerr, inactive_list.count());
*/
replaced = 0;
switch (x.get_position()) {
case ACTIVE:
//MESSAGE(cerr, "active");
active_list.delete_cell(&x);
break;
case INACTIVE:
//MESSAGE(cerr, "inactive");
inactive_list.delete_cell(&x);
lower_last(replaced);
break;
case NOWHERE:
//MESSAGE(cerr, "nowhere");
if ( active_sz > active_list.count() )
break;
else
if ( active_sz == active_list.count() &&
inactive_sz == inactive_list.count() ) {
throw(stringException("lru::promote(): pool too small"));
} else
lower_last(replaced);
break;
}
//debug(cerr, "to merge");
active_list.insert_before(active_list.get_head(), &x);
x.set_position(ACTIVE);
return true;
}
Boolean lru::promote(rep_cell& x)
{
rep_cell* dummy = 0;
return this -> promote(x, dummy);
}
Boolean lru::derank(rep_cell& x, position_t opt)
{
switch (x.get_position()) {
case ACTIVE:
//MESSAGE(cerr, "active status to derank");
active_list.delete_cell(&x);
break;
case INACTIVE:
//MESSAGE(cerr, "derand: an inactive cell");
inactive_list.delete_cell(&x);
opt = INACTIVE;
break;
case NOWHERE:
throw(stringException("lru::derand(): nowhere status"));
}
switch ( opt ) {
case ACTIVE:
active_list.insert_as_tail(&x);
x.set_position(ACTIVE);
break;
case INACTIVE:
inactive_list.insert_as_tail(&x);
x.set_position(INACTIVE);
break;
default:
break;
}
return true;
}
long lru::first(position_t option)
{
switch (option) {
case ACTIVE:
return active_list.first();
case INACTIVE:
return inactive_list.first();
default:
throw(stringException("lru::first(): bad option"));
}
}
rep_cell* lru::operator()(long index, position_t option)
{
switch (option) {
case ACTIVE:
return (rep_cell*)(index);
case INACTIVE:
return (rep_cell*)(index);
default:
throw(stringException("lru::operator(): bad option"));
}
}
void lru::next(long& index, position_t option)
{
switch (option) {
case ACTIVE:
active_list.next(index);
return;
case INACTIVE:
inactive_list.next(index);
return;
default:
throw(stringException("lru::next(): bad option"));
}
}
long lru::last(position_t option)
{
switch (option) {
case ACTIVE:
return active_list.last();
case INACTIVE:
return inactive_list.last();
default:
throw(stringException("lru::last(): bad option"));
}
}
Boolean lru::remove(rep_cell& x)
{
switch (x.get_position()) {
case ACTIVE:
active_list.delete_cell(&x);
return true;
case INACTIVE:
inactive_list.delete_cell(&x);
return true;
case NOWHERE:
throw(stringException("lru::last(): bad option"));
}
return false;
}
void lru::remove()
{
active_list.remove();
inactive_list.remove();
}
void lru::forget()
{
active_list.empty_list();
inactive_list.empty_list();
}