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