00001 /* 00002 // $Id: //open/dev/fennel/common/RawIntrusiveList.cpp#8 $ 00003 // Fennel is a library of data storage and processing components. 00004 // Copyright (C) 2005-2009 The Eigenbase Project 00005 // Copyright (C) 2005-2009 SQLstream, Inc. 00006 // Copyright (C) 2005-2009 LucidEra, Inc. 00007 // Portions Copyright (C) 1999-2009 John V. Sichi 00008 // 00009 // This program is free software; you can redistribute it and/or modify it 00010 // under the terms of the GNU General Public License as published by the Free 00011 // Software Foundation; either version 2 of the License, or (at your option) 00012 // any later version approved by The Eigenbase Project. 00013 // 00014 // This program is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with this program; if not, write to the Free Software 00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 00024 #include "fennel/common/CommonPreamble.h" 00025 #include "fennel/common/RawIntrusiveList.h" 00026 00027 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/common/RawIntrusiveList.cpp#8 $"); 00028 00029 void RawIntrusiveList::push_front(IntrusiveListNode &listNode) 00030 { 00031 assert(!listNode.pNext); 00032 listNode.pNext = pFront; 00033 pFront = &listNode; 00034 if (!pBack) { 00035 pBack = pFront; 00036 } 00037 nNodes++; 00038 } 00039 00040 void RawIntrusiveList::push_back(IntrusiveListNode &listNode) 00041 { 00042 assert(!listNode.pNext); 00043 listNode.pNext = NULL; 00044 if (pBack) { 00045 pBack = pBack->pNext = &listNode; 00046 } else { 00047 pFront = pBack = &listNode; 00048 } 00049 nNodes++; 00050 } 00051 00052 void RawIntrusiveList::clear(bool debugClear) 00053 { 00054 nNodes = 0; 00055 #ifdef DEBUG 00056 if (debugClear) { 00057 IntrusiveListNode *p = pFront; 00058 while (p) { 00059 IntrusiveListNode *pNext = p->pNext; 00060 p->pNext = NULL; 00061 p = pNext; 00062 } 00063 } 00064 #endif 00065 pFront = pBack = NULL; 00066 } 00067 00068 bool RawIntrusiveList::remove(IntrusiveListNode &listNode) 00069 { 00070 for (RawIntrusiveListMutator iter(*this); iter.getCurrent(); ++iter) { 00071 if (iter.getCurrent() == &listNode) { 00072 iter.detach(); 00073 return 1; 00074 } 00075 } 00076 return 0; 00077 } 00078 00079 void RawIntrusiveListMutator::promoteCurrToFront() 00080 { 00081 assert(pCurr); 00082 if (pList->pFront == pCurr) { 00083 return; 00084 } 00085 if (pList->pBack == pCurr) { 00086 pList->pBack = pPrev; 00087 } 00088 pPrev->pNext = pCurr->pNext; 00089 pCurr->pNext = pList->pFront; 00090 pList->pFront = pCurr; 00091 pCurr = pPrev->pNext; 00092 bJustDeleted = 1; 00093 } 00094 00095 void RawIntrusiveListMutator::demoteCurrToBack() 00096 { 00097 assert(pCurr); 00098 if (pList->pBack == pCurr) { 00099 return; 00100 } 00101 if (pPrev) { 00102 pPrev->pNext = pCurr->pNext; 00103 } else { 00104 pList->pFront = pCurr->pNext; 00105 } 00106 pCurr->pNext = NULL; 00107 pList->pBack->pNext = pCurr; 00108 pList->pBack = pCurr; 00109 if (pPrev) { 00110 pCurr = pPrev->pNext; 00111 } else { 00112 pCurr = pList->pFront; 00113 } 00114 bJustDeleted = 1; 00115 } 00116 00117 void RawIntrusiveListMutator::demoteFrontBeforeCurr() 00118 { 00119 assert(pCurr); 00120 if (!pPrev) { 00121 return; 00122 } 00123 IntrusiveListNode *pOldFront = pList->pFront; 00124 if (pOldFront == pPrev) { 00125 return; 00126 } 00127 pList->pFront = pOldFront->pNext; 00128 pPrev = pPrev->pNext = pOldFront; 00129 pOldFront->pNext = pCurr; 00130 } 00131 00132 IntrusiveListNode *RawIntrusiveListMutator::detach() 00133 { 00134 assert(pCurr); 00135 IntrusiveListNode *pListNode = pCurr; 00136 if (pCurr == pList->pBack) { 00137 pList->pBack = pPrev; 00138 } 00139 if (pPrev) { 00140 pPrev->pNext = pCurr->pNext; 00141 pCurr = pPrev->pNext; 00142 } else { 00143 pList->pFront = pCurr->pNext; 00144 pCurr = pList->pFront; 00145 } 00146 pList->nNodes--; 00147 bJustDeleted = 1; 00148 #ifdef DEBUG 00149 pListNode->pNext = NULL; 00150 #endif 00151 return pListNode; 00152 } 00153 00154 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/common/RawIntrusiveList.cpp#8 $"); 00155 00156 // End RawIntrusiveList.cpp