dslinux/user/pixil/packages/dvdview/dvdview/src/utility bytebuffer.cc bytebuffer.hh fastalloc.cc fastalloc.hh
amadeus
dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:26:02 CEST 2006
Update of /cvsroot/dslinux/dslinux/user/pixil/packages/dvdview/dvdview/src/utility
In directory antilope:/tmp/cvs-serv11916/packages/dvdview/dvdview/src/utility
Added Files:
bytebuffer.cc bytebuffer.hh fastalloc.cc fastalloc.hh
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it
--- NEW FILE: bytebuffer.cc ---
/********************************************************************************
Copyright (C) 1999 Dirk Farin
This program is distributed under GNU Public License (GPL) as
outlined in the COPYING file that comes with the source distribution.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
********************************************************************************/
#include "utility/bytebuffer.hh"
#include "error.hh"
#include <string.h>
const unsigned int ByteBufferParams::c_InitialBufferSize = 10*1024-64;
ByteBufferParams::ByteBufferParams(int InitialSize_Hint,int poolsize)
: initialsize_hint(InitialSize_Hint),
memalloc(InitialSize_Hint,poolsize),
EstimatedSize(c_InitialBufferSize),
LargestSize(0)
{
}
#define OLDVERSION 0
// This factor defines what fraction of the new estimation will be taken from the
// old estimation.
#define AgingFactor 15:16
ByteBuffer::ByteBuffer(ByteBufferParams& p)
: d_param(p)
{
if (d_param.initialsize_hint==0)
{
d_buf = NULL;
d_len = 0;
d_size = 0;
}
else
{
#if OLDVERSION
d_buf = new unsigned char[d_param.initialsize_hint];
Assert(d_buf);
d_len = 0;
d_size = d_param.initialsize_hint;
#else
int s;
d_buf = (unsigned char*)(d_param.memalloc.Alloc(d_param.initialsize_hint,&d_size));
Assert(d_buf);
d_len = 0;
#endif
}
}
ByteBuffer::~ByteBuffer()
{
if (d_buf)
{
#if OLDVERSION
delete[] d_buf;
#else
d_param.memalloc.Free(d_buf);
#endif
// Update statistics.
d_param.EstimatedSize = (d_param.EstimatedSize * (1?AgingFactor) + // old fraction
d_len * ((0?AgingFactor)-(1?AgingFactor))) // new fraction
/ (0?AgingFactor);
if (d_len > d_param.LargestSize) d_param.LargestSize=d_len;
}
}
unsigned char* ByteBuffer::GetPtrToAppendToBuffer(unsigned int len)
{
Assert(len>0);
// If contents will not fit into the buffer, enlarge buffer.
if (d_len+len > d_size)
{
unsigned int newsize=d_size;
// No buffer allocated so far, use estimated size.
if (newsize==0) newsize = d_param.EstimatedSize;
// If this is not enough, use larger buffer.
if (newsize<d_len+len && d_param.LargestSize>0) newsize = d_param.LargestSize;
// If still not enough, double size until big enough.
// This will allocate buffers that are far too big in some cases.
// But allocating just the size that is needed will result in poor
// performance when appending many small portions of data.
while (newsize<d_len+len) newsize *= 2;
// Allocate new buffer and copy old buffer contents to new buffer.
#if OLDVERSION
unsigned char* newbuf = new unsigned char[newsize];
#else
int newlen;
unsigned char* newbuf = (unsigned char*)(d_param.memalloc.Alloc(newsize,&newlen));
#endif
Assert(newbuf); // Memory error handler should have caught error.
if (d_len>0) { memcpy(newbuf,d_buf,d_len); }
#if OLDVERSION
// The old buffer can now be replaced with the new one and be deleted.
if (d_buf) { delete[] d_buf; }
d_buf=newbuf;
d_size=newsize;
#else
// The old buffer can now be replaced with the new one and be deleted.
if (d_buf) { d_param.memalloc.Free(d_buf); }
d_buf=newbuf;
d_size=newlen;
#endif
}
// There has to be enough memory left now.
Assert(d_len+len <= d_size);
// Return pointer, pointing behind the last already filled byte in the buffer and
// enlarge the buffer contents size variable.
unsigned char* newdatastart = &d_buf[d_len];
d_len += len;
return newdatastart;
}
void ByteBuffer::TruncateBuffer(unsigned int nBytes)
{
Assert(nBytes <= d_len);
d_len -= nBytes;
}
void ByteBuffer::AppendBytes(unsigned char* mem,unsigned int len)
{
if (len>0)
{
unsigned char* buffermem = GetPtrToAppendToBuffer(len);
#if 0
if (len<200)
{
while (len)
{
*buffermem++ = *mem++;
len--;
}
}
else
#endif
{
// Append new contents behind current buffer data.
memcpy(buffermem,mem,len);
}
}
}
--- NEW FILE: bytebuffer.hh ---
/********************************************************************************
utility/bytebuffer.hh
purpose:
Each ByteBuffer encapsulates a dynamically allocated memory area
to which an arbitrary amount of bytes may be appended. It
automatically enlarges if more data is appended than the current
buffer can hold.
notes:
1) You must not acquire several pointers using GetPtrToAppendToBuffer() to
fill the associated memory area later. Strictly speaking you have to get
the pointer and fill the memory area before you call any non-const method
with this ByteBuffer-object again.
to do:
author(s):
- Dirk Farin, farin at ti.uni-mannheim.de
modifications:
28/Sep/1999 - Dirk Farin
- Memory is now allocated via a MemoryAllocator object for better performance.
- ByteBuffer statistics are now held externally in a ByteBufferParams
structure that can be shared across multiple ByteBuffer objects.
18/Dec/1998 - Dirk Farin
- Changed several int-types to unsigned to eliminate compiler warnings.
20/Nov/1998 - Dirk Farin
- introduced TruncateBuffer()
15/Nov/1998 - Dirk Farin
- first implementation
********************************************************************************
Copyright (C) 1999 Dirk Farin
This program is distributed under GNU Public License (GPL) as
outlined in the COPYING file that comes with the source distribution.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
********************************************************************************/
#ifndef DVDVIEW_UTILITY_BYTEBUFFER_HH
#define DVDVIEW_UTILITY_BYTEBUFFER_HH
#include "types.hh"
#include "utility/fastalloc.hh"
struct ByteBufferParams
{
ByteBufferParams(int InitialSize_Hint,
int PoolSize);
~ByteBufferParams() { }
private:
uint32 initialsize_hint;
MemoryAllocator memalloc;
// Collect information about how large these buffers usually get.
// This helps to allocate buffers that are most of the time big enough
// to hold all the data in them.
unsigned int EstimatedSize;
unsigned int LargestSize;
// Initial buffer size if we did not collect a significant amount of
// statistics yet.
static const unsigned int c_InitialBufferSize;
friend class ByteBuffer;
};
class ByteBuffer
{
public:
ByteBuffer(ByteBufferParams&);
~ByteBuffer();
void AppendBytes(unsigned char* mem,unsigned int len);
unsigned char* GetPtrToAppendToBuffer(unsigned int len); // see note 1)
void TruncateBuffer(unsigned int nBytes); // Throw away last 'nBytes' bytes of buffer.
void Clear() { d_len=0; } // Clear buffer contents but do not free memory.
unsigned char* AskContents() const { return d_buf; }
int AskLength() const { return d_len; }
private:
unsigned char* d_buf;
int d_len; // Amount of data in the buffer.
int d_size; // Total size of allocated buffer memory.
ByteBufferParams& d_param;
};
#endif
--- NEW FILE: fastalloc.hh ---
/********************************************************************************
utility/fastalloc.hh
purpose:
Very fast memory allocation.
notes:
- It is suggested that you create a separate MemoryAllocator object
for each purpose of allocation as the allocator may generate statistics
on how large the allocated memory area usually are. This may be needed
for optimal performance.
to do:
author(s):
- Dirk Farin, farin at ti.uni-mannheim.de
modifications:
28/Sep/1999 - Dirk Farin
- first implementation based on old DVDView's alloc.cc
********************************************************************************
Copyright (C) 1999 Dirk Farin
This program is distributed under GNU Public License (GPL) as
outlined in the COPYING file that comes with the source distribution.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
********************************************************************************/
#ifndef DVDVIEW_UTILITY_FASTALLOC_HH
#define DVDVIEW_UTILITY_FASTALLOC_HH
#include "types.hh"
class MemoryAllocator
{
public:
MemoryAllocator(int MinimumMemorySize,int PoolSize);
~MemoryAllocator();
void* Alloc(int size,int* realsize=NULL);
void Free(void*);
private:
int** d_Pool;
int d_nAreasInPool;
int d_PoolSize;
int d_MinMemSize;
};
#endif
--- NEW FILE: fastalloc.cc ---
/********************************************************************************
Copyright (C) 1999 Dirk Farin
This program is distributed under GNU Public License (GPL) as
outlined in the COPYING file that comes with the source distribution.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
********************************************************************************/
#include "utility/fastalloc.hh"
#include "error.hh"
#include <stdlib.h>
MemoryAllocator::MemoryAllocator(int minmemsize,int poolsize)
: d_nAreasInPool(0),
d_PoolSize(poolsize),
d_MinMemSize(minmemsize)
{
d_Pool = new int*[d_PoolSize];
}
MemoryAllocator::~MemoryAllocator()
{
for (int i=0;i<d_nAreasInPool;i++)
{
Assert(d_Pool[i]);
free(d_Pool[i]);
}
delete[] d_Pool;
}
void* MemoryAllocator::Alloc(int size,int* realsize)
{
// Find memory block that is at least as large as the requested size.
int minidx = -1;
int minsize;
int i;
for (i=0;i<d_nAreasInPool;i++)
if (d_Pool[i][0] >= size)
{
minidx=i;
minsize=d_Pool[minidx][0];
break;
}
// Now look if there is a memory block that is smaller but still large enought.
for (;i<d_nAreasInPool;i++)
if (d_Pool[i][0] >= size && d_Pool[i][0]<minsize)
{
minidx=i;
minsize=d_Pool[i][0];
}
// If an appropriate memory block is found, remove this block from the pool
// and return it.
if (minidx>=0)
{
int* mem = d_Pool[minidx];
d_Pool[minidx] = d_Pool[--d_nAreasInPool];
if (realsize) *realsize=mem[0];
return &mem[1];
}
else
{
// Otherwise we have to allocate a new memory block.
int* mem = (int*)malloc(size + sizeof(int));
mem[0] = size;
if (realsize) *realsize=size;
return &mem[1];
}
}
void MemoryAllocator::Free(void* memptr)
{
int* mem = (int*)memptr;
mem = &mem[-1];
if (d_nAreasInPool<d_PoolSize)
{
d_Pool[d_nAreasInPool++]=mem;
}
else
{
// If returned memory block does not fit into the pool anymore,
// delete it. This is perhaps better than deleting the smallest
// memory area as otherwise the total allocated memory for
// grow forever. This way every memory block will eventually
// be deleted independent of its size.
free(mem);
}
}
More information about the dslinux-commit
mailing list