Added overallocation support for DataBlock.
This provides improved performance for repeated binary data appending. git-svn-id: http://yate.null.ro/svn/yate/trunk@5973 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
b7281eaade
commit
09f40eb24c
|
@ -82,20 +82,27 @@ const DataBlock& DataBlock::empty()
|
|||
return s_empty;
|
||||
}
|
||||
|
||||
DataBlock::DataBlock()
|
||||
: m_data(0), m_length(0)
|
||||
DataBlock::DataBlock(unsigned int overAlloc)
|
||||
: m_data(0), m_length(0), m_allocated(0), m_overAlloc(overAlloc)
|
||||
{
|
||||
}
|
||||
|
||||
DataBlock::DataBlock(const DataBlock& value)
|
||||
: GenObject(),
|
||||
m_data(0), m_length(0)
|
||||
m_data(0), m_length(0), m_allocated(0), m_overAlloc(value.overAlloc())
|
||||
{
|
||||
assign(value.data(),value.length());
|
||||
}
|
||||
|
||||
DataBlock::DataBlock(void* value, unsigned int len, bool copyData)
|
||||
: m_data(0), m_length(0)
|
||||
DataBlock::DataBlock(const DataBlock& value, unsigned int overAlloc)
|
||||
: GenObject(),
|
||||
m_data(0), m_length(0), m_allocated(0), m_overAlloc(overAlloc)
|
||||
{
|
||||
assign(value.data(),value.length());
|
||||
}
|
||||
|
||||
DataBlock::DataBlock(void* value, unsigned int len, bool copyData, unsigned int overAlloc)
|
||||
: m_data(0), m_length(0), m_allocated(0), m_overAlloc(overAlloc)
|
||||
{
|
||||
assign(value,len,copyData);
|
||||
}
|
||||
|
@ -123,15 +130,17 @@ void DataBlock::clear(bool deleteData)
|
|||
}
|
||||
}
|
||||
|
||||
DataBlock& DataBlock::assign(void* value, unsigned int len, bool copyData)
|
||||
DataBlock& DataBlock::assign(void* value, unsigned int len, bool copyData, unsigned int allocated)
|
||||
{
|
||||
if ((value != m_data) || (len != m_length)) {
|
||||
void *odata = m_data;
|
||||
m_length = 0;
|
||||
m_allocated = 0;
|
||||
m_data = 0;
|
||||
if (len) {
|
||||
if (copyData) {
|
||||
void *data = ::malloc(len);
|
||||
allocated = allocLen(len);
|
||||
void *data = ::malloc(allocated);
|
||||
if (data) {
|
||||
if (value)
|
||||
::memcpy(data,value,len);
|
||||
|
@ -140,12 +149,17 @@ DataBlock& DataBlock::assign(void* value, unsigned int len, bool copyData)
|
|||
m_data = data;
|
||||
}
|
||||
else
|
||||
Debug("DataBlock",DebugFail,"malloc(%d) returned NULL!",len);
|
||||
Debug("DataBlock",DebugFail,"malloc(%d) returned NULL!",allocated);
|
||||
}
|
||||
else
|
||||
else {
|
||||
if (allocated < len)
|
||||
allocated = len;
|
||||
m_data = value;
|
||||
if (m_data)
|
||||
}
|
||||
if (m_data) {
|
||||
m_length = len;
|
||||
m_allocated = allocated;
|
||||
}
|
||||
}
|
||||
if (odata && (odata != m_data))
|
||||
::free(odata);
|
||||
|
@ -189,14 +203,20 @@ void DataBlock::append(const DataBlock& value)
|
|||
if (m_length) {
|
||||
if (value.length()) {
|
||||
unsigned int len = m_length+value.length();
|
||||
void *data = ::malloc(len);
|
||||
if (len <= m_allocated) {
|
||||
::memcpy(m_length+(char*)m_data,value.data(),value.length());
|
||||
m_length = len;
|
||||
return;
|
||||
}
|
||||
unsigned int aLen = allocLen(len);
|
||||
void *data = ::malloc(aLen);
|
||||
if (data) {
|
||||
::memcpy(data,m_data,m_length);
|
||||
::memcpy(m_length+(char*)data,value.data(),value.length());
|
||||
assign(data,len,false);
|
||||
assign(data,len,false,aLen);
|
||||
}
|
||||
else
|
||||
Debug("DataBlock",DebugFail,"malloc(%d) returned NULL!",len);
|
||||
Debug("DataBlock",DebugFail,"malloc(%d) returned NULL!",aLen);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -208,14 +228,20 @@ void DataBlock::append(const String& value)
|
|||
if (m_length) {
|
||||
if (value.length()) {
|
||||
unsigned int len = m_length+value.length();
|
||||
void *data = ::malloc(len);
|
||||
if (len <= m_allocated) {
|
||||
::memcpy(m_length+(char*)m_data,value.safe(),value.length());
|
||||
m_length = len;
|
||||
return;
|
||||
}
|
||||
unsigned int aLen = allocLen(len);
|
||||
void *data = ::malloc(aLen);
|
||||
if (data) {
|
||||
::memcpy(data,m_data,m_length);
|
||||
::memcpy(m_length+(char*)data,value.safe(),value.length());
|
||||
assign(data,len,false);
|
||||
assign(data,len,false,aLen);
|
||||
}
|
||||
else
|
||||
Debug("DataBlock",DebugFail,"malloc(%d) returned NULL!",len);
|
||||
Debug("DataBlock",DebugFail,"malloc(%d) returned NULL!",aLen);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -242,6 +268,16 @@ void DataBlock::insert(const DataBlock& value)
|
|||
assign(value.data(),vl);
|
||||
}
|
||||
|
||||
unsigned int DataBlock::allocLen(unsigned int len) const
|
||||
{
|
||||
// allocate a multiple of 8 bytes
|
||||
unsigned int over = (8 - (len & 7)) & 7;
|
||||
if (over < m_overAlloc)
|
||||
return (len + m_overAlloc + 7) & ~7;
|
||||
else
|
||||
return len + over;
|
||||
}
|
||||
|
||||
bool DataBlock::convert(const DataBlock& src, const String& sFormat,
|
||||
const String& dFormat, unsigned maxlen)
|
||||
{
|
||||
|
|
34
yateclass.h
34
yateclass.h
|
@ -3751,21 +3751,31 @@ public:
|
|||
|
||||
/**
|
||||
* Constructs an empty data block
|
||||
* @param overAlloc How many bytes of memory to overallocate
|
||||
*/
|
||||
DataBlock();
|
||||
DataBlock(unsigned int overAlloc = 0);
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
* @param value Data block to copy from
|
||||
*/
|
||||
DataBlock(const DataBlock& value);
|
||||
|
||||
/**
|
||||
* Copy constructor with overallocation
|
||||
* @param value Data block to copy from
|
||||
* @param overAlloc How many bytes of memory to overallocate
|
||||
*/
|
||||
DataBlock(const DataBlock& value, unsigned int overAlloc);
|
||||
|
||||
/**
|
||||
* Constructs an initialized data block
|
||||
* @param value Data to assign, may be NULL to fill with zeros
|
||||
* @param len Length of data, may be zero (then value is ignored)
|
||||
* @param copyData True to make a copy of the data, false to just insert the pointer
|
||||
* @param overAlloc How many bytes of memory to overallocate
|
||||
*/
|
||||
DataBlock(void* value, unsigned int len, bool copyData = true);
|
||||
DataBlock(void* value, unsigned int len, bool copyData = true, unsigned int overAlloc = 0);
|
||||
|
||||
/**
|
||||
* Destroys the data, disposes the memory.
|
||||
|
@ -3823,6 +3833,20 @@ public:
|
|||
inline unsigned int length() const
|
||||
{ return m_length; }
|
||||
|
||||
/**
|
||||
* Get the memory overallocation setting.
|
||||
* @return Amount of memory that will be overallocated.
|
||||
*/
|
||||
inline unsigned int overAlloc() const
|
||||
{ return m_overAlloc; }
|
||||
|
||||
/**
|
||||
* Set the memory overallocation.
|
||||
* @param bytes How many bytes of memory to overallocate
|
||||
*/
|
||||
inline void overAlloc(unsigned int bytes)
|
||||
{ m_overAlloc = bytes; }
|
||||
|
||||
/**
|
||||
* Clear the data and optionally free the memory
|
||||
* @param deleteData True to free the deta block, false to just forget it
|
||||
|
@ -3834,8 +3858,9 @@ public:
|
|||
* @param value Data to assign, may be NULL to fill with zeros
|
||||
* @param len Length of data, may be zero (then value is ignored)
|
||||
* @param copyData True to make a copy of the data, false to just insert the pointer
|
||||
* @param allocated Real allocated data length in case it should not be copied
|
||||
*/
|
||||
DataBlock& assign(void* value, unsigned int len, bool copyData = true);
|
||||
DataBlock& assign(void* value, unsigned int len, bool copyData = true, unsigned int allocated = 0);
|
||||
|
||||
/**
|
||||
* Append data to the current block
|
||||
|
@ -3971,8 +3996,11 @@ public:
|
|||
String sqlEscape(char extraEsc) const;
|
||||
|
||||
private:
|
||||
unsigned int allocLen(unsigned int len) const;
|
||||
void* m_data;
|
||||
unsigned int m_length;
|
||||
unsigned int m_allocated;
|
||||
unsigned int m_overAlloc;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue