khanat-opennel-code/code/nel/include/nel/misc/buf_fifo.h

165 lines
4.2 KiB
C++

// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_BUF_FIFO_H
#define NL_BUF_FIFO_H
#include "types_nl.h"
#include <vector>
#include "time_nl.h"
#include "mem_stream.h"
#include "command.h"
namespace NLMISC {
#undef BUFFIFO_TRACK_ALL_BUFFERS
/**
* This class is a dynamic size FIFO that contains variable size uint8 buffer.
* It's used in the layer1 network for storing temporary messages.
* You can resize the internal FIFO buffer if you know the average size
* of data you'll put in it. It have the same behavior as STL so if the
* buffer is full the size will be automatically increase by 2.
*
* TODO: Add a method getMsgNb() that will return the number of messages in queue.
* For acceptable performance, it would need to store the current number instead
* of browsing the blocks.
*
* \code
CBufFIFO fifo;
fifo.resize(10000);
vector<uint8> vec;
vec.resize(rand()%256);
memset (&(vec[0]), '-', vec.size());
// push the vector
fifo.push(vec);
// display the fifo
fifo.display();
vector<uint8> vec2;
// get the vector
fifo.pop(vec2);
* \endcode
* \author Vianney Lecroart
* \author Nevrax France
* \date 2001
*/
class CBufFIFO
{
public:
CBufFIFO ();
~CBufFIFO ();
/// Push 'buffer' in the head of the FIFO
void push (const std::vector<uint8> &buffer) { push (&buffer[0], (uint32)buffer.size()); }
void push (const NLMISC::CMemStream &buffer) { push (buffer.buffer(), buffer.length()); }
void push (const uint8 *buffer, uint32 size);
/// Concate and push 'buffer1' and buffer2 in the head of the FIFO. The goal is to avoid a copy
void push (const std::vector<uint8> &buffer1, const std::vector<uint8> &buffer2);
/// Get the buffer in the tail of the FIFO and put it in 'buffer'
void front (std::vector<uint8> &buffer);
void front (NLMISC::CMemStream &buffer);
void front (uint8 *&buffer, uint32 &size);
/// This function returns the last byte of the front message
/// It is used by the network to know a value quickly without doing front()
uint8 frontLast ();
/// Pop the buffer in the tail of the FIFO
void pop ();
/// Set the size of the FIFO buffer in byte
void resize (uint32 size);
/// Return true if the FIFO is empty
bool empty () { return _Empty; }
/// Erase the FIFO
void clear ();
/// Returns the size of the FIFO
uint32 size ();
/// display the FIFO to stdout (used to debug the FIFO)
void display ();
/// display the FIFO statistics (speed, nbcall, etc...) to stdout
void displayStats (CLog *log = InfoLog);
private:
typedef uint32 TFifoSize;
// pointer to the big buffer
uint8 *_Buffer;
// size of the big buffer
uint32 _BufferSize;
// true if the bufffer is empty
bool _Empty;
// head of the FIFO
uint8 *_Head;
// tail of the FIFO
uint8 *_Tail;
// pointer to the rewinder of the FIFO
uint8 *_Rewinder;
// return true if we can put size bytes on the buffer
// return false if we have to resize
bool canFit (uint32 size);
// statistics of the FIFO
uint32 _BiggestBlock;
uint32 _SmallestBlock;
uint32 _BiggestBuffer;
uint32 _SmallestBuffer;
uint32 _Pushed ;
uint32 _Fronted;
uint32 _Resized;
TTicks _PushedTime;
TTicks _FrontedTime;
TTicks _ResizedTime;
#ifdef BUFFIFO_TRACK_ALL_BUFFERS
typedef std::set<CBufFIFO*> TAllBuffers;
// All the buffer for debug output
static TAllBuffers _AllBuffers; // WARNING: not mutexed, can produce some crashes!
#endif
NLMISC_CATEGORISED_COMMAND_FRIEND(misc, dumpAllBuffers);
};
} // NLMISC
#endif // NL_BUF_FIFO_H
/* End of buf_fifo.h */