6 * $Date: 2012-07-04 23:09:19 +0200 (Mi, 04. Jul 2012) $
7 ***************************************************************/
10 * \brief Implementation of Hashing (class HashingBase)
12 * \author Carsten Gutwenger
15 * This file is part of the Open Graph Drawing Framework (OGDF).
19 * See README.txt in the root directory of the OGDF installation for details.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * Version 2 or 3 as published by the Free Software Foundation;
25 * see the file LICENSE.txt included in the packaging of this file
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38 * Boston, MA 02110-1301, USA.
40 * \see http://www.gnu.org/copyleft/gpl.html
41 ***************************************************************/
43 #include <ogdf/basic/Hashing.h>
48 HashingBase::HashingBase(int minTableSize
)
51 init(m_minTableSize
= minTableSize
);
55 HashingBase::HashingBase(const HashingBase
&H
)
61 HashingBase::~HashingBase()
67 void HashingBase::init(int tableSize
)
69 OGDF_ASSERT(tableSize
>= m_minTableSize
)
71 m_tableSize
= tableSize
;
72 m_hashMask
= tableSize
-1;
73 m_tableSizeHigh
= tableSize
<< 1;
74 m_tableSizeLow
= (tableSize
> m_minTableSize
) ? (tableSize
>> 1) : -1;
76 m_table
= (HashElementBase
**)calloc(tableSize
,sizeof(HashElementBase
*));
80 void HashingBase::destroyAll()
82 HashElementBase
**pList
= m_table
, **pListStop
= m_table
+m_tableSize
;
84 for(; pList
!= pListStop
; ++pList
) {
85 HashElementBase
*pElement
= *pList
, *pNext
;
86 for (; pElement
; pElement
= pNext
) {
87 pNext
= pElement
->next();
94 void HashingBase::copyAll(const HashingBase
&H
)
99 HashElementBase
**pList
= H
.m_table
;
100 HashElementBase
**pListStop
= H
.m_table
+m_tableSize
;
102 for(; pList
!= pListStop
; ++pList
) {
103 HashElementBase
*pElement
= *pList
;
104 for (; pElement
; pElement
= pElement
->next())
105 insert(H
.copy(pElement
));
110 void HashingBase::clear()
116 init(m_minTableSize
);
120 HashingBase
&HashingBase::operator=(const HashingBase
&H
)
129 void HashingBase::resize(int newTableSize
)
131 HashElementBase
**oldTable
= m_table
;
132 HashElementBase
**oldTableStop
= oldTable
+ m_tableSize
;
136 for(HashElementBase
**pOldList
= oldTable
;
137 pOldList
!= oldTableStop
; ++pOldList
)
139 HashElementBase
*pElement
= *pOldList
, *pNext
;
140 for(; pElement
; pElement
= pNext
) {
141 pNext
= pElement
->m_next
;
143 HashElementBase
**pList
= m_table
+
144 (pElement
->m_hashValue
& m_hashMask
);
145 pElement
->m_next
= *pList
;
154 void HashingBase::insert(HashElementBase
*pElement
)
156 if (++m_count
== m_tableSizeHigh
)
157 resize(m_tableSizeHigh
);
159 HashElementBase
**pList
= m_table
+ (pElement
->m_hashValue
& m_hashMask
);
160 pElement
->m_next
= *pList
;
165 void HashingBase::del(HashElementBase
*pElement
)
167 HashElementBase
**pList
= m_table
+ (pElement
->m_hashValue
& m_hashMask
);
168 HashElementBase
*pPrev
= *pList
;
170 if (pPrev
== pElement
) {
171 *pList
= pElement
->m_next
;
174 while (pPrev
->m_next
!= pElement
) pPrev
= pPrev
->m_next
;
175 pPrev
->m_next
= pElement
->m_next
;
178 if (--m_count
== m_tableSizeLow
)
179 resize(m_tableSizeLow
);
183 HashElementBase
*HashingBase::firstElement(HashElementBase
***pList
) const
185 HashElementBase
**pStop
= m_table
+ m_tableSize
;
186 for(*pList
= m_table
; *pList
!= pStop
; ++(*pList
))
187 if (**pList
) return **pList
;
193 HashElementBase
*HashingBase::nextElement(HashElementBase
***pList
,
194 HashElementBase
*pElement
) const
196 if ((pElement
= pElement
->next()) != 0) return pElement
;
198 HashElementBase
**pStop
= m_table
+ m_tableSize
;
199 for(++(*pList
); *pList
!= pStop
; ++(*pList
))
200 if (**pList
) return **pList
;
207 } // end namespace ogdf