UniSet  2.6.0
MQAtomic.h
00001 /*
00002  * Copyright (c) 2015 Pavel Vainerman.
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU Lesser General Public License as
00006  * published by the Free Software Foundation, version 2.1.
00007  *
00008  * This program is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00011  * Lesser General Lesser Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00015  */
00016 // --------------------------------------------------------------------------
00017 #ifndef MQAtomic_H_
00018 #define MQAtomic_H_
00019 //--------------------------------------------------------------------------
00020 #include <atomic>
00021 #include <vector>
00022 #include <memory>
00023 #include <mutex>
00024 #include "MessageType.h"
00025 //--------------------------------------------------------------------------
00026 typedef std::shared_ptr<uniset::VoidMessage> VoidMessagePtr;
00027 //--------------------------------------------------------------------------
00028 namespace uniset
00029 {
00062 class MQAtomic
00063 {
00064     public:
00065         MQAtomic( size_t qsize = 2000 );
00066 
00068         bool push( const VoidMessagePtr& msg ) noexcept;
00069 
00073         VoidMessagePtr top() noexcept;
00074 
00075         size_t size() const noexcept;
00076         bool empty() const noexcept;
00077 
00078         // ----- Настройки  -----
00079         // неявно подразумевается, что всё настривается до первого использования
00080         // ----------------------
00081         void setMaxSizeOfMessageQueue( size_t s );
00082         size_t getMaxSizeOfMessageQueue() const noexcept;
00083 
00085         enum LostStrategy
00086         {
00087             lostOldData, // default
00088             lostNewData
00089         };
00090 
00091         void setLostStrategy( LostStrategy s ) noexcept;
00092 
00093         // ---- Статистика ----
00095         inline size_t getMaxQueueMessages() const noexcept
00096         {
00097             return stMaxQueueMessages;
00098         }
00099 
00101         inline size_t getCountOfLostMessages() const noexcept
00102         {
00103             return stCountOfLostMessages;
00104         }
00105 
00106     protected:
00107 
00108         // заполнить всю очередь указанным сообщением
00109         void mqFill( const VoidMessagePtr& v );
00110 
00111         // для возможности тестирования переполнения
00112         // специально делается такая функция
00113         void set_wpos( unsigned long pos ) noexcept;
00114         void set_rpos( unsigned long pos ) noexcept;
00115 
00116     private:
00117 
00118         typedef std::vector<VoidMessagePtr> MQueue;
00119 
00120         MQueue mqueue;
00121         std::atomic_ulong wpos = { 0 }; // позиция на запись
00122         std::atomic_ulong rpos = { 0 }; // позиция на чтение
00123         std::atomic_ulong qpos = { 0 }; // текущая позиция последнего элемента (max position) (реально добавленного в очередь)
00124 
00125         LostStrategy lostStrategy = { lostOldData };
00126 
00128         size_t SizeOfMessageQueue = { 2000 };
00129 
00130         // статистическая информация
00131         size_t stMaxQueueMessages = { 0 };    
00132         size_t stCountOfLostMessages = { 0 };    
00133 };
00134 // -------------------------------------------------------------------------
00135 } // end of uniset namespace
00136 //---------------------------------------------------------------------------
00137 #endif
00138 //---------------------------------------------------------------------------