00001 // Copyright (C) 2001, Compaq Computer Corporation 00002 // 00003 // This file is part of Vesta. 00004 // 00005 // Vesta is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // Vesta is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with Vesta; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 // 00020 // ShortIdRefCount.H 00021 // 00022 // Reference counts for shortids in a volatile directory tree 00023 // 00024 00025 #ifndef _SID_REF_COUNT 00026 #define _SID_REF_COUNT 00027 00028 #include "Basics.H" 00029 #include "Table.H" 00030 #include "ShortIdKey.H" 00031 00032 class ShortIdRefCount : public Table<ShortIdKey, int>::Default 00033 { 00034 public: 00035 typedef Table<ShortIdKey, int>::Iterator Iterator; 00036 00037 ShortIdRefCount() : Table<ShortIdKey, int>::Default() { } 00038 00039 // Avoid the need for the caller to create a ShortIdKey. Optioanlly 00040 // provide a default value if no reference is found. (In some cases 00041 // 0 is desired, and in others 1 is.) 00042 inline int GetCount(ShortId sid, int count = 0) 00043 { 00044 ShortIdKey sidkey(sid); 00045 bool found = this->Get(sidkey, count); 00046 assert(!found || (count > 0)); 00047 return count; 00048 } 00049 00050 // Increment the reference count for "sid", returning its new count. 00051 inline int Increment(ShortId sid) 00052 { 00053 ShortIdKey sidkey(sid); 00054 int count; 00055 if(this->Get(sidkey, count)) 00056 { 00057 assert(count > 0); 00058 count++; 00059 } 00060 else 00061 count = 1; 00062 this->Put(sidkey, count); 00063 return count; 00064 } 00065 00066 // Decrement the reference count for "sid", returning its new count. 00067 // If "missing_ok" is false we assert that "sid" must already have 00068 // an entry in the table. 00069 inline int Decrement(ShortId sid, bool missing_ok) 00070 { 00071 ShortIdKey sidkey(sid); 00072 int count = 0; 00073 bool present = this->Get(sidkey, count); 00074 assert(missing_ok || present); 00075 if(present) 00076 { 00077 assert(count > 0); 00078 count--; 00079 if(count > 0) 00080 this->Put(sidkey, count); 00081 else 00082 // Note that we don't resize when we delete an entry. This 00083 // means that we never shrink the table, which should result 00084 // in fewer overall table resizes. This is good, since they 00085 // can be expensive and happen while locks are held. 00086 this->Delete(sidkey, count, false); 00087 return count; 00088 } 00089 return 0; 00090 } 00091 00092 // Compare with another reference counter, returning true if the two 00093 // match exactly. If there are any mis-matches, messages will be 00094 // printed. (This is intended for paranoid double-checking used 00095 // during development and testing.) 00096 bool Compare(const ShortIdRefCount &other); 00097 00098 private: 00099 ShortIdRefCount(const ShortIdRefCount &other) : Table<ShortIdKey, int>::Default(&other) { } 00100 }; 00101 00102 #endif