TNB Library
TnbQueue.h
[詳解]
1#pragma once
15#include "TnbVector.h"
16
17
18
19//TNB Library
20namespace TNB
21{
22
23
24
41template<typename TYP>
42struct IQueueT
43{
45 virtual ~IQueueT(void)
46 {
47 }
48
57 virtual size_t AddElements(size_t size, const TYP* P = NULL) = 0;
58
67 virtual INDEX Add(const TYP& t) = 0;
68
77 virtual size_t TakeElements(size_t size, TYP* P = NULL) = 0;
78
85 virtual TYP Take(void)
86 {
87 TYP t;
88 if ( TakeElements(1, &t) == 1 )
89 {
90 return t;
91 }
92 ASSERT0( false, "IQueue::Take()", "キューが空の時取得操作されました。" );
93 throw CEmptyException();
94 }
95
103 virtual size_t EraseElements(size_t size)
104 {
105 return TakeElements(size);
106 }
107
115 {
117 bool boRc = (TakeElements(size, v.GetBuffer(size)) == size);
118 v.ReleaseBuffer();
119 if ( ! boRc )
120 {
121 v.Invalid();
122 }
123 return v;
124 }
125};
126
127
128
158template<typename TYP, bool ISI = false, class INV = TYP>
159class CRingQueueT : public ICollectionMidT<TYP>, public IQueueT<TYP>
160{
161 DEFSUPER(ICollectionMidT<TYP>);
162public:
163
170 explicit CRingQueueT(size_t size = 10000) : _super(), m_hptHead(new THead(size))
171 {
172 }
173
179 CRingQueueT(const CRingQueueT& queue) : _super(), m_hptHead(queue.m_hptHead)
180 {
181 }
182
186 virtual ~CRingQueueT(void)
187 {
188 m_hptHead.Null();
189 }
190
199 {
200 EXCLUSIVE(&other);
201 m_hptHead = other.m_hptHead;
202 return *this;
203 }
204
213 virtual bool Lock(DWORD dwTime = INFINITE) const
214 {
215 return m_syncFunc.Lock();
216 }
217
219 virtual void Unlock(void) const
220 {
221 m_syncFunc.Unlock();
222 }
223
230 void SetQueueSize(size_t size)
231 {
232 m_hptHead = new THead(size);
233 ASSERT( GetSize() == 0 );
234 }
235
240 size_t GetQueueSize(void) const
241 {
242 return m_hptHead->bufferSize;
243 }
244
249 virtual size_t GetSize(void) const
250 {
251 return m_hptHead->dataSize;
252 }
253
259 bool IsFull(void) const
260 {
261 if ( GetQueueSize() <= GetSize() )
262 {
263 return true;
264 }
265 return false;
266 }
267
277 virtual INDEX Add(const TYP& t)
278 {
279 size_t r = GetSize();
280 return (AddElements(1, &t) == 1) ? r : INVALID_INDEX;
281 }
282
291 virtual bool Remove(INDEX index)
292 {
293 if ( IsInRange(index) )
294 {
295 m_Separate();
296 THead* H = *m_hptHead.ReferP();
297 size_t sz = H->dataSize;
298 INDEX ri = H->readIndex;
299 size_t bs = H->bufferSize;
300 loop ( i, sz -index - 1 )
301 {
302 INDEX dst = (ri + i + index) % bs;
303 INDEX src = (ri + i + index + 1) % bs;
304 H->pBuffer[dst] = H->pBuffer[src];
305 }
306 if ( ISI )
307 {
308 INDEX dst = (ri + sz - 1) % bs;
309 H->pBuffer[dst] = INV();
310 }
311 (H->dataSize)--;
312 return true;
313 }
314 return false;
315 }
316
322 virtual bool RemoveAll(void)
323 {
324 EXCLUSIVE(this);
325 size_t l = m_hptHead->dataSize;
326 if ( l > 0 )
327 {
328 TakeElements(l);
329 ASSERT( m_hptHead->dataSize == 0 );
330 }
331 return true;
332 }
333
343 virtual size_t AddElements(size_t size, const TYP* P = NULL)
344 {
345 EXCLUSIVE(this);
346 m_Separate();
347 THead* H = *m_hptHead.ReferP();
348 if ( (H->dataSize) + size > (H->bufferSize) )
349 {
350 //それ以上になるならエラー
351 return INVALID_SIZE;
352 }
353 H->syncObj.Lock();
354 size_t bs = H->bufferSize;
355 INDEX tmp = (H->readIndex + H->dataSize) % bs;
356 if ( P != NULL )
357 {
358 loop ( i, size )
359 {
360 H->pBuffer[tmp++] = *P++;
361 if ( tmp >= bs )
362 {
363 tmp -= bs;
364 }
365 }
366 }
367 else
368 {
369 loop ( i, size )
370 {
371 H->pBuffer[tmp++] = TYP();
372 if ( tmp >= bs )
373 {
374 tmp -= bs;
375 }
376 }
377 }
378 (H->dataSize) += size;
379 H->syncObj.Unlock();
380 return size;
381 }
382
392 virtual size_t TakeElements(size_t size, TYP* P = NULL)
393 {
394 EXCLUSIVE(this);
395 m_Separate();
396 THead* H = *m_hptHead.ReferP();
397 H->syncObj.Lock();
398 if ( (H->dataSize) < size )
399 {
400 //キューにその長さの情報がないのでエラー
401 H->syncObj.Unlock();
402 return INVALID_SIZE;
403 }
404 size_t bs = H->bufferSize;
405 if ( P != NULL || ISI )
406 {
407 INDEX tmp = H->readIndex;
408 loop ( i, size )
409 {
410 if ( P != NULL )
411 {
412 *P++ = H->pBuffer[tmp];
413 }
414 if ( ISI )
415 {
416 H->pBuffer[tmp] = INV();
417 }
418 if ( ++tmp >= bs )
419 {
420 tmp -= bs;
421 }
422 }
423 }
424 (H->readIndex) += size;
425 (H->readIndex) %= bs;
426 (H->dataSize) -= size;
427 H->syncObj.Unlock();
428 return size;
429 }
430
436 size_t GetFreeSize(void) const
437 {
438 return (m_hptHead->bufferSize) - (m_hptHead->dataSize);
439 }
440
441protected:
442
444 struct THead
445 {
449 size_t bufferSize;
450 size_t dataSize;
451 INDEX readIndex;
452 TYP* pBuffer;
454 THead(size_t size) : readIndex(0), bufferSize(size), dataSize(0)
455 {
456 pBuffer = new TYP[size];
457 }
459 ~THead(void)
460 {
461 if ( pBuffer != NULL )
462 {
463 delete[] pBuffer;
464 }
465 }
466 };
467
469
470private:
471
472 CSyncSection m_syncFunc;
473
475 void m_Separate(void)
476 {
477 if ( m_hptHead.GetReferCount() > 1 )
478 {
479 size_t size = m_hptHead->bufferSize;
480 THead* pNew = new THead(size);
481 if ( (m_hptHead->dataSize) > 0 )
482 {
483 pNew->dataSize = m_hptHead->dataSize;
485 TYP* P1 = pNew->pBuffer;
486 TYP* P2 = m_hptHead->pBuffer;
487 while ( (size--) > 0 )
488 {
489 *P1++ = *P2++;
490 }
491 }
492 m_hptHead = pNew;
493 }
494 }
495
502 virtual const TYP* m_GetConstPointer(INDEX index) const
503 {
504 if ( IsInRange(index) )
505 {
506 INDEX tmp;
507 THead* H = *m_hptHead.ReferP();
508 tmp = (H->readIndex) + index;
509 tmp %= (H->bufferSize);
510 return &(H->pBuffer[tmp]);
511 }
512 return NULL;
513 }
514
521 virtual TYP* m_GetPointer(INDEX index)
522 {
523 if ( IsInRange(index) )
524 {
525 m_Separate();
526 INDEX tmp;
527 THead* H = *m_hptHead.ReferP();
528 tmp = (H->readIndex) + index;
529 tmp %= (H->bufferSize);
530 return &(H->pBuffer[tmp]);
531 }
532 return NULL;
533 }
534
535 friend class CQueueTest;
536};
537
538
539
557template<typename TYP, bool ISI = false, class INV = TYP>
558class CBlockingQueueT : public CRingQueueT<TYP, ISI, INV>
559{
561 DEFSUPER(_super);
562public:
563
570 explicit CBlockingQueueT(size_t size = 10000) : _super(size)
571 {
572 }
573
577 virtual ~CBlockingQueueT(void)
578 {
579 }
580
589 virtual size_t TakeElements(size_t size, TYP* P = NULL)
590 {
591 if ( _super::TakeElements(size, P) != size )
592 {
593 //なかった
594 while ( true )
595 {
596 m_hptHead->syncAdding.Lock();
597 if ( _super::TakeElements(size, P) == size )
598 {
599 break;
600 }
601 }
602 }
603 m_hptHead->syncTaking.Pulse();
604 return size;
605 }
606
615 virtual size_t AddElements(size_t size, const TYP* P = NULL)
616 {
617 if ( _super::AddElements(size, P) != size )
618 {
619 //追加できなかった
620 loop ( i, size )
621 {
622 while ( true )
623 {
624 if ( _super::AddElements(1, P) == 1 )
625 {
626 break;
627 }
628 ::Sleep(10);
629 }
630 m_hptHead->syncAdding.Pulse();
631 P++;
632 }
633 }
634 m_hptHead->syncAdding.Pulse();
635 return size;
636 }
637};
638
639
640
647
648
649
656
657
658
665
666
667
674
675
676
683
684
685
686#ifdef __AFX_H__
687
695
696#endif
697
698
699
700}; // TNB
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
配列型情報管理関係のヘッダ
ブロック付キュー型情報管理テンプレート
Definition: TnbQueue.h:559
virtual ~CBlockingQueueT(void)
デストラクタ
Definition: TnbQueue.h:577
CBlockingQueueT(size_t size=10000)
コンストラクタ
Definition: TnbQueue.h:570
virtual size_t TakeElements(size_t size, TYP *P=NULL)
[取得] 複数要素取り出し.
Definition: TnbQueue.h:589
virtual size_t AddElements(size_t size, const TYP *P=NULL)
[追加] 複数要素追加.
Definition: TnbQueue.h:615
取得要素(空き)無し例外
Definition: TnbException.h:107
int GetReferCount(void) const
[取得] 参照数取得.
TYP * ReferP(void)
[取得] TYPのポインタ取得.
void Null(void)
[設定] 開放.
リング式キュー型情報管理テンプレート
Definition: TnbQueue.h:160
virtual size_t GetSize(void) const
[取得] 要素数取得
Definition: TnbQueue.h:249
friend class CQueueTest
フレンドクラス宣言
Definition: TnbQueue.h:535
void SetQueueSize(size_t size)
[設定] リングキューサイズ指定.
Definition: TnbQueue.h:230
CRingQueueT(size_t size=10000)
コンストラクタ
Definition: TnbQueue.h:170
virtual bool Remove(INDEX index)
[削除] 要素一つ削除.
Definition: TnbQueue.h:291
CRingQueueT(const CRingQueueT &queue)
コピーコンストラクタ
Definition: TnbQueue.h:179
virtual bool Lock(DWORD dwTime=INFINITE) const
[排他] ロック
Definition: TnbQueue.h:213
CRingQueueT & operator=(const CRingQueueT &other)
[代入] コピーオペレータ
Definition: TnbQueue.h:198
bool IsFull(void) const
[確認] 満タン?
Definition: TnbQueue.h:259
virtual size_t TakeElements(size_t size, TYP *P=NULL)
[取得] 複数要素取り出し.
Definition: TnbQueue.h:392
virtual bool RemoveAll(void)
[削除] データ全削除.
Definition: TnbQueue.h:322
virtual size_t AddElements(size_t size, const TYP *P=NULL)
[追加] 複数要素追加.
Definition: TnbQueue.h:343
size_t GetFreeSize(void) const
[取得] 格納可能数取得.
Definition: TnbQueue.h:436
virtual INDEX Add(const TYP &t)
[追加] 要素追加.
Definition: TnbQueue.h:277
CPointerHandleT< THead > m_hptHead
管理用ヘッダのポインタハンドル
Definition: TnbQueue.h:468
virtual void Unlock(void) const
[排他] アンロック
Definition: TnbQueue.h:219
virtual ~CRingQueueT(void)
デストラクタ
Definition: TnbQueue.h:186
size_t GetQueueSize(void) const
[取得] リングキューサイズ取得.
Definition: TnbQueue.h:240
Event排他管理クラス
Definition: TnbSync.h:480
Section排他管理クラス
Definition: TnbSync.h:125
virtual bool Lock(DWORD dwTime=INFINITE) const
[排他] ロック
Definition: TnbSync.h:148
virtual void Unlock(void) const
[排他] アンロック
Definition: TnbSync.h:155
配列型情報管理テンプレート
Definition: TnbVector.h:75
TYP * GetBuffer(size_t size=0)
[操作] データアドレス取得
Definition: TnbVector.h:745
void ReleaseBuffer(void)
[操作] データの管理を元に戻す.
Definition: TnbVector.h:805
void Invalid(void)
[操作] 無効状態にする
Definition: TnbVector.h:604
情報群管理操作インターフェース拡張テンプレート
TNB::CRingQueueT< CString, true > CStringQueue
CString型キュー管理クラス
Definition: TnbQueue.h:694
TNB::CBlockingQueueT< CStr, true > CStrBlockingQueue
CStr型ブロッキングキュー管理クラス
Definition: TnbQueue.h:682
TNB::CRingQueueT< BYTE > CByteQueue
BYTE型(unsigned 8bit)キュークラス
Definition: TnbQueue.h:646
TNB::CBlockingQueueT< BYTE > CByteBlockingQueue
BYTE型(unsigned 8bit)ブロッキングキュークラス
Definition: TnbQueue.h:655
TNB::CRingQueueT< DWORD > CDwordQueue
DWORD型(unsigned 32bit)キュー管理クラス
Definition: TnbQueue.h:664
TNB::CRingQueueT< CStr, true > CStrQueue
CStr型キュー管理クラス
Definition: TnbQueue.h:673
#define EXCLUSIVE(CLS)
簡易排他制御マクロ.
Definition: TnbSync.h:788
TNB Library
Definition: TnbDoxyTitle.txt:2
配列型情報管理の管理型
Definition: TnbQueue.h:445
THead(size_t size)
コンストラクタ
Definition: TnbQueue.h:454
CSyncEvent syncTaking
Takeした時一時的にUnlockされる(CBlockingQueueT用)
Definition: TnbQueue.h:447
TYP * pBuffer
バッファ
Definition: TnbQueue.h:452
CSyncEvent syncAdding
Addした時一時的にUnlockされる(CBlockingQueueT用)
Definition: TnbQueue.h:448
~THead(void)
デストラクタ
Definition: TnbQueue.h:459
size_t dataSize
実際のデータの長さ
Definition: TnbQueue.h:450
size_t bufferSize
バッファの長さ
Definition: TnbQueue.h:449
INDEX readIndex
読込みポジション
Definition: TnbQueue.h:451
CSyncSection syncObj
参照排他
Definition: TnbQueue.h:446
bool IsInRange(INDEX index) const
[確認] INDEXの有効確認.
キュー型情報管理インターフェーステンプレート
Definition: TnbQueue.h:43
virtual size_t AddElements(size_t size, const TYP *P=NULL)=0
[追加] 複数要素追加.
virtual ~IQueueT(void)
デストラクタ
Definition: TnbQueue.h:45
virtual size_t EraseElements(size_t size)
[削除] 要素削除.
Definition: TnbQueue.h:103
virtual INDEX Add(const TYP &t)=0
[追加] 要素一つ追加.
CVectorT< TYP > TakeoutToVector(size_t size)
[取得] 要素配列取出し.
Definition: TnbQueue.h:114
virtual TYP Take(void)
[取得] 先頭要素取り出し.
Definition: TnbQueue.h:85
virtual size_t TakeElements(size_t size, TYP *P=NULL)=0
[取得] 複数要素取り出し