Krita Source Code Documentation
Loading...
Searching...
No Matches
KisTileHashTableTraits< T > Class Template Reference

#include <kis_tile_hash_table.h>

Public Types

typedef T TileType
 
typedef KisSharedPtr< T > TileTypeSP
 
typedef KisWeakSharedPtr< T > TileTypeWSP
 

Public Member Functions

void addTile (TileTypeSP tile)
 
void clear ()
 
void debugMaxListLength (qint32 &min, qint32 &max)
 
void debugPrintInfo ()
 
KisTileDatadefaultTileData () const
 
bool deleteTile (qint32 col, qint32 row)
 
bool deleteTile (TileTypeSP tile)
 
TileTypeSP getExistingTile (qint32 col, qint32 row)
 
TileTypeSP getReadOnlyTileLazy (qint32 col, qint32 row, bool &existingTile)
 
TileTypeSP getTileLazy (qint32 col, qint32 row, bool &newTile)
 
bool isEmpty ()
 
 KisTileHashTableTraits (const KisTileHashTableTraits< T > &ht, KisMementoManager *mm)
 
 KisTileHashTableTraits (KisMementoManager *mm)
 
qint32 numTiles ()
 
KisTileDatarefAndFetchDefaultTileData () const
 
void setDefaultTileData (KisTileData *defaultTileData)
 
bool tileExists (qint32 col, qint32 row)
 
 ~KisTileHashTableTraits ()
 

Private Member Functions

qint32 debugChainLen (qint32 idx)
 
void debugListLengthDistribution ()
 
KisTileDatadefaultTileDataImp () const
 
TileTypeSP getTile (qint32 col, qint32 row, qint32 idx)
 
TileTypeSP getTileMinefieldWalk (qint32 col, qint32 row, qint32 idx)
 
void linkTile (TileTypeSP tile, qint32 idx)
 
void sanityChecksumCheck ()
 
void setDefaultTileDataImp (KisTileData *defaultTileData)
 
bool unlinkTile (qint32 col, qint32 row, qint32 idx)
 

Static Private Member Functions

static quint32 calculateHash (qint32 col, qint32 row)
 

Private Attributes

KisTileDatam_defaultTileData
 
TileTypeSPm_hashTable
 
QReadWriteLock m_lock
 
KisMementoManagerm_mementoManager
 
qint32 m_numTiles
 

Static Private Attributes

static const qint32 TABLE_SIZE = 1024
 

Friends

template<class U , class LockerType >
class KisTileHashTableIteratorTraits
 

Detailed Description

template<class T>
class KisTileHashTableTraits< T >

This is a template for a hash table that stores tiles (or some other objects resembling tiles). Actually, this object should only have col()/row() methods and be able to answer setNext()/next() requests to be stored here. It is used in KisTiledDataManager and KisMementoManager.

Definition at line 24 of file kis_tile_hash_table.h.

Member Typedef Documentation

◆ TileType

template<class T >
typedef T KisTileHashTableTraits< T >::TileType

Definition at line 27 of file kis_tile_hash_table.h.

◆ TileTypeSP

template<class T >
typedef KisSharedPtr<T> KisTileHashTableTraits< T >::TileTypeSP

Definition at line 28 of file kis_tile_hash_table.h.

◆ TileTypeWSP

template<class T >
typedef KisWeakSharedPtr<T> KisTileHashTableTraits< T >::TileTypeWSP

Definition at line 29 of file kis_tile_hash_table.h.

Constructor & Destructor Documentation

◆ KisTileHashTableTraits() [1/2]

◆ KisTileHashTableTraits() [2/2]

Definition at line 28 of file kis_tile_hash_table_p.h.

30 : m_lock(QReadWriteLock::NonRecursive)
31{
32 QReadLocker locker(&ht.m_lock);
33
37
39 Q_CHECK_PTR(m_hashTable);
40
41
42 TileTypeSP foreignTile;
43 TileTypeSP nativeTile;
44 TileTypeSP nativeTileHead;
45 for (qint32 i = 0; i < TABLE_SIZE; i++) {
46 nativeTileHead = 0;
47
48 foreignTile = ht.m_hashTable[i];
49 while (foreignTile) {
50 nativeTile = TileTypeSP(new TileType(*foreignTile, m_mementoManager));
51 nativeTile->setNext(nativeTileHead);
52 nativeTileHead = nativeTile;
53
54 foreignTile = foreignTile->next();
55 }
56
57 m_hashTable[i] = nativeTileHead;
58 }
60}
void setDefaultTileDataImp(KisTileData *defaultTileData)

◆ ~KisTileHashTableTraits()

template<class T >
KisTileHashTableTraits< T >::~KisTileHashTableTraits ( )

Definition at line 63 of file kis_tile_hash_table_p.h.

64{
65 clear();
66 delete[] m_hashTable;
68}

Member Function Documentation

◆ addTile()

template<class T >
void KisTileHashTableTraits< T >::addTile ( TileTypeSP tile)

Definition at line 267 of file kis_tile_hash_table_p.h.

268{
269 const qint32 idx = calculateHash(tile->col(), tile->row());
270
271 QWriteLocker locker(&m_lock);
272 linkTile(tile, idx);
273}
static quint32 calculateHash(qint32 col, qint32 row)
void linkTile(TileTypeSP tile, qint32 idx)

◆ calculateHash()

template<class T >
quint32 KisTileHashTableTraits< T >::calculateHash ( qint32 col,
qint32 row )
inlinestaticprivate

Definition at line 71 of file kis_tile_hash_table_p.h.

72{
73 return ((row << 5) + (col & 0x1F)) & 0x3FF;
74}

◆ clear()

template<class T >
void KisTileHashTableTraits< T >::clear ( )

About disconnection of tiles see a comment in unlinkTile()

Definition at line 291 of file kis_tile_hash_table_p.h.

292{
293 QWriteLocker locker(&m_lock);
294 TileTypeSP tile = TileTypeSP();
295 qint32 i;
296
297 for (i = 0; i < TABLE_SIZE; i++) {
298 tile = m_hashTable[i];
299
300 while (tile) {
301 TileTypeSP tmp = tile;
302 tile = tile->next();
303
308 tmp->setNext(TileTypeSP());
309 tmp->notifyDetachedFromDataManager();
310 tmp = 0;
311
312 m_numTiles--;
313 }
314
315 m_hashTable[i] = 0;
316 }
317
318 Q_ASSERT(!m_numTiles);
319}

◆ debugChainLen()

template<class T >
qint32 KisTileHashTableTraits< T >::debugChainLen ( qint32 idx)
inlineprivate

Definition at line 361 of file kis_tile_hash_table_p.h.

362{
363 qint32 len = 0;
364 for (TileTypeSP it = m_hashTable[idx]; it; it = it->next(), len++) ;
365 return len;
366}

◆ debugListLengthDistribution()

template<class T >
void KisTileHashTableTraits< T >::debugListLengthDistribution ( )
private

Definition at line 389 of file kis_tile_hash_table_p.h.

390{
391 qint32 min, max;
392 qint32 arraySize;
393 qint32 tmp;
394
395 debugMaxListLength(min, max);
396 arraySize = max - min + 1;
397
398 qint32 *array = new qint32[arraySize];
399 memset(array, 0, sizeof(qint32)*arraySize);
400
401 for (qint32 i = 0; i < TABLE_SIZE; i++) {
402 tmp = debugChainLen(i);
403 array[tmp-min]++;
404 }
405
406 qInfo() << QString(" minChain: %1\n").arg(min);
407 qInfo() << QString(" maxChain: %1\n").arg(max);
408
409 qInfo() << " Chain size distribution:";
410 for (qint32 i = 0; i < arraySize; i++)
411 qInfo() << QString(" %1: %2").arg(i + min).arg(array[i]);
412
413 delete[] array;
414}
void debugMaxListLength(qint32 &min, qint32 &max)
qint32 debugChainLen(qint32 idx)
T min(T a, T b, T c)
constexpr std::enable_if< sizeof...(values)==0, size_t >::type max()

◆ debugMaxListLength()

template<class T >
void KisTileHashTableTraits< T >::debugMaxListLength ( qint32 & min,
qint32 & max )

Definition at line 369 of file kis_tile_hash_table_p.h.

370{
371 TileTypeSP tile;
372 qint32 maxLen = 0;
373 qint32 minLen = m_numTiles;
374 qint32 tmp = 0;
375
376 for (qint32 i = 0; i < TABLE_SIZE; i++) {
377 tmp = debugChainLen(i);
378 if (tmp > maxLen)
379 maxLen = tmp;
380 if (tmp < minLen)
381 minLen = tmp;
382 }
383
384 min = minLen;
385 max = maxLen;
386}

◆ debugPrintInfo()

template<class T >
void KisTileHashTableTraits< T >::debugPrintInfo ( )

Definition at line 348 of file kis_tile_hash_table_p.h.

349{
350 if (!m_numTiles) return;
351
352 qInfo() << "==========================\n"
353 << "TileHashTable:"
354 << "\n def. data:\t\t" << m_defaultTileData
355 << "\n numTiles:\t\t" << m_numTiles;
357 qInfo() << "==========================\n";
358}

◆ defaultTileData()

template<class T >
KisTileData * KisTileHashTableTraits< T >::defaultTileData ( ) const

Definition at line 329 of file kis_tile_hash_table_p.h.

330{
331 QWriteLocker locker(&m_lock);
332 return defaultTileDataImp();
333}
KisTileData * defaultTileDataImp() const

◆ defaultTileDataImp()

template<class T >
KisTileData * KisTileHashTableTraits< T >::defaultTileDataImp ( ) const
inlineprivate

Definition at line 192 of file kis_tile_hash_table_p.h.

193{
194 return m_defaultTileData;
195}

◆ deleteTile() [1/2]

template<class T >
bool KisTileHashTableTraits< T >::deleteTile ( qint32 col,
qint32 row )

Definition at line 276 of file kis_tile_hash_table_p.h.

277{
278 const qint32 idx = calculateHash(col, row);
279
280 QWriteLocker locker(&m_lock);
281 return unlinkTile(col, row, idx);
282}
bool unlinkTile(qint32 col, qint32 row, qint32 idx)

◆ deleteTile() [2/2]

template<class T >
bool KisTileHashTableTraits< T >::deleteTile ( TileTypeSP tile)

Definition at line 285 of file kis_tile_hash_table_p.h.

286{
287 return deleteTile(tile->col(), tile->row());
288}
bool deleteTile(TileTypeSP tile)

◆ getExistingTile()

template<class T >
KisTileHashTableTraits< T >::TileTypeSP KisTileHashTableTraits< T >::getExistingTile ( qint32 col,
qint32 row )

Returns a tile in position (col,row). If no tile exists, returns null.

Parameters
colcolumn of the tile
rowrow of the tile

Definition at line 206 of file kis_tile_hash_table_p.h.

207{
208 const qint32 idx = calculateHash(col, row);
209
210 // NOTE: minefield walk is disabled due to supposed unsafety,
211 // see bug 391270
212
213 QReadLocker locker(&m_lock);
214 return getTile(col, row, idx);
215}
TileTypeSP getTile(qint32 col, qint32 row, qint32 idx)

◆ getReadOnlyTileLazy()

template<class T >
KisTileHashTableTraits< T >::TileTypeSP KisTileHashTableTraits< T >::getReadOnlyTileLazy ( qint32 col,
qint32 row,
bool & existingTile )

Returns a tile in position (col,row). If no tile exists, creates nothing, but returns shared default tile object of the table. Be careful, this object has column and row parameters set to (qint32_MIN, qint32_MIN).

Parameters
colcolumn of the tile
rowrow of the tile
existingTilereturns true if the tile actually exists in the table and it is not a lazily created default wrapper tile

Definition at line 247 of file kis_tile_hash_table_p.h.

248{
249 const qint32 idx = calculateHash(col, row);
250
251 // NOTE: minefield walk is disabled due to supposed unsafety,
252 // see bug 391270
253
254 QReadLocker locker(&m_lock);
255
256 TileTypeSP tile = getTile(col, row, idx);
257 existingTile = tile;
258
259 if (!existingTile) {
260 tile = new TileType(col, row, m_defaultTileData, 0);
261 }
262
263 return tile;
264}

◆ getTile()

template<class T >
KisTileHashTableTraits< T >::TileTypeSP KisTileHashTableTraits< T >::getTile ( qint32 col,
qint32 row,
qint32 idx )
private

Definition at line 113 of file kis_tile_hash_table_p.h.

114{
115 TileTypeSP tile = m_hashTable[idx];
116
117 for (; tile; tile = tile->next()) {
118 if (tile->col() == col &&
119 tile->row() == row) {
120
121 return tile;
122 }
123 }
124
125 return TileTypeSP();
126}

◆ getTileLazy()

template<class T >
KisTileHashTableTraits< T >::TileTypeSP KisTileHashTableTraits< T >::getTileLazy ( qint32 col,
qint32 row,
bool & newTile )

Returns a tile in position (col,row). If no tile exists, creates a new one, attaches it to the list and returns.

Parameters
colcolumn of the tile
rowrow of the tile
newTileout-parameter, returns true if a new tile was created

Definition at line 219 of file kis_tile_hash_table_p.h.

221{
222 const qint32 idx = calculateHash(col, row);
223
224 // NOTE: minefield walk is disabled due to supposed unsafety,
225 // see bug 391270
226
227 newTile = false;
228 TileTypeSP tile;
229
230 {
231 QReadLocker locker(&m_lock);
232 tile = getTile(col, row, idx);
233 }
234
235 if (!tile) {
236 QWriteLocker locker(&m_lock);
237 tile = new TileType(col, row, m_defaultTileData, m_mementoManager);
238 linkTile(tile, idx);
239 newTile = true;
240 }
241
242 return tile;
243}
struct Tile * newTile(struct rect r)
Definition pixels.c:231

References newTile().

◆ getTileMinefieldWalk()

template<class T >
KisTileHashTableTraits< T >::TileTypeSP KisTileHashTableTraits< T >::getTileMinefieldWalk ( qint32 col,
qint32 row,
qint32 idx )
private

This is a special method for dangerous and unsafe access to the tiles table. Thanks to the fact that our shared pointers are thread safe, we can iterate through the linked list without having any locks help. In the worst case, we will miss the needed tile. In that case, the higher level code will do the proper locking and do the second try with all the needed locks held.

Definition at line 78 of file kis_tile_hash_table_p.h.

79{
80 // WARNING: this function is here only for educational purposes! Don't
81 // use it! It causes race condition in a shared pointer copy-ctor
82 // when accessing m_hashTable!
83
93 TileTypeSP headTile = m_hashTable[idx];
94 TileTypeSP tile = headTile;
95
96 for (; tile; tile = tile->next()) {
97 if (tile->col() == col &&
98 tile->row() == row) {
99
100 if (m_hashTable[idx] != headTile) {
101 tile.clear();
102 }
103
104 break;
105 }
106 }
107
108 return tile;
109}

◆ isEmpty()

template<class T >
bool KisTileHashTableTraits< T >::isEmpty ( )
inline

Definition at line 38 of file kis_tile_hash_table.h.

38 {
39 return !m_numTiles;
40 }

References KisTileHashTableTraits< T >::m_numTiles.

◆ linkTile()

template<class T >
void KisTileHashTableTraits< T >::linkTile ( TileTypeSP tile,
qint32 idx )
private

Definition at line 129 of file kis_tile_hash_table_p.h.

130{
131 TileTypeSP firstTile = m_hashTable[idx];
132
133#ifdef SHARED_TILES_SANITY_CHECK
134 Q_ASSERT_X(!tile->next(), "KisTileHashTableTraits<T>::linkTile",
135 "A tile can't be shared by several hash tables, sorry.");
136#endif
137
138 tile->setNext(firstTile);
139 m_hashTable[idx] = tile;
140 m_numTiles++;
141}

◆ numTiles()

template<class T >
qint32 KisTileHashTableTraits< T >::numTiles ( )
inline

Definition at line 83 of file kis_tile_hash_table.h.

83 {
84 return m_numTiles;
85 }

References KisTileHashTableTraits< T >::m_numTiles.

◆ refAndFetchDefaultTileData()

template<class T >
KisTileData * KisTileHashTableTraits< T >::refAndFetchDefaultTileData ( ) const
inline

Definition at line 336 of file kis_tile_hash_table_p.h.

337{
338 QWriteLocker locker(&m_lock);
340 result->ref();
341 return result;
342}
bool ref() const

References KisTileData::ref().

◆ sanityChecksumCheck()

template<class T >
void KisTileHashTableTraits< T >::sanityChecksumCheck ( )
private

We assume that the lock should have already been taken by the code that was going to change the table

Definition at line 417 of file kis_tile_hash_table_p.h.

418{
423 Q_ASSERT(!m_lock.tryLockForWrite());
424
425 TileTypeSP tile = 0;
426 qint32 exactNumTiles = 0;
427
428 for (qint32 i = 0; i < TABLE_SIZE; i++) {
429 tile = m_hashTable[i];
430 while (tile) {
431 exactNumTiles++;
432 tile = tile->next();
433 }
434 }
435
436 if (exactNumTiles != m_numTiles) {
437 dbgKrita << "Sanity check failed!";
438 dbgKrita << ppVar(exactNumTiles);
440 dbgKrita << "Wrong tiles checksum!";
441 Q_ASSERT(0); // not fatalKrita for a backtrace support
442 }
443}
#define dbgKrita
Definition kis_debug.h:45
#define ppVar(var)
Definition kis_debug.h:155

References dbgKrita, and ppVar.

◆ setDefaultTileData()

template<class T >
void KisTileHashTableTraits< T >::setDefaultTileData ( KisTileData * defaultTileData)

Definition at line 322 of file kis_tile_hash_table_p.h.

323{
324 QWriteLocker locker(&m_lock);
326}
KisTileData * defaultTileData() const

◆ setDefaultTileDataImp()

template<class T >
void KisTileHashTableTraits< T >::setDefaultTileDataImp ( KisTileData * defaultTileData)
inlineprivate

Definition at line 178 of file kis_tile_hash_table_p.h.

179{
180 if (m_defaultTileData) {
183 }
184
185 if (defaultTileData) {
188 }
189}

References KisTileData::acquire().

◆ tileExists()

template<class T >
bool KisTileHashTableTraits< T >::tileExists ( qint32 col,
qint32 row )

Definition at line 199 of file kis_tile_hash_table_p.h.

200{
201 return this->getExistingTile(col, row);
202}
TileTypeSP getExistingTile(qint32 col, qint32 row)

◆ unlinkTile()

template<class T >
bool KisTileHashTableTraits< T >::unlinkTile ( qint32 col,
qint32 row,
qint32 idx )
private

The shared pointer may still be accessed by someone, so we need to disconnects the tile from memento manager explicitly

Definition at line 144 of file kis_tile_hash_table_p.h.

145{
146 TileTypeSP tile = m_hashTable[idx];
147 TileTypeSP prevTile;
148
149 for (; tile; tile = tile->next()) {
150 if (tile->col() == col &&
151 tile->row() == row) {
152
153 if (prevTile)
154 prevTile->setNext(tile->next());
155 else
156 /* optimize here*/
157 m_hashTable[idx] = tile->next();
158
164 tile->setNext(TileTypeSP());
165 tile->notifyDetachedFromDataManager();
166 tile.clear();
167
168 m_numTiles--;
169 return true;
170 }
171 prevTile = tile;
172 }
173
174 return false;
175}

References KisSharedPtr< T >::clear().

Friends And Related Symbol Documentation

◆ KisTileHashTableIteratorTraits

template<class T >
template<class U , class LockerType >
friend class KisTileHashTableIteratorTraits
friend

Definition at line 106 of file kis_tile_hash_table.h.

Member Data Documentation

◆ m_defaultTileData

template<class T >
KisTileData* KisTileHashTableTraits< T >::m_defaultTileData
private

Definition at line 112 of file kis_tile_hash_table.h.

◆ m_hashTable

template<class T >
TileTypeSP* KisTileHashTableTraits< T >::m_hashTable
private

Definition at line 109 of file kis_tile_hash_table.h.

◆ m_lock

template<class T >
QReadWriteLock KisTileHashTableTraits< T >::m_lock
mutableprivate

Definition at line 115 of file kis_tile_hash_table.h.

◆ m_mementoManager

template<class T >
KisMementoManager* KisTileHashTableTraits< T >::m_mementoManager
private

Definition at line 113 of file kis_tile_hash_table.h.

◆ m_numTiles

template<class T >
qint32 KisTileHashTableTraits< T >::m_numTiles
private

Definition at line 110 of file kis_tile_hash_table.h.

◆ TABLE_SIZE

template<class T >
const qint32 KisTileHashTableTraits< T >::TABLE_SIZE = 1024
staticprivate

Definition at line 108 of file kis_tile_hash_table.h.


The documentation for this class was generated from the following files: