use a shared buffer
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Tue May 06 14:18:05 2008 -0700 (21 months ago)
changeset 3042d0a9677d5452
parent 3041 a624276a897b
child 3043 4a1ab06f0d63
use a shared buffer
src/common/tag-list.cc
src/common/tag-list.h
     1.1 --- a/src/common/tag-list.cc	Thu Apr 24 16:06:33 2008 -0700
     1.2 +++ b/src/common/tag-list.cc	Tue May 06 14:18:05 2008 -0700
     1.3 @@ -64,45 +64,68 @@
     1.4  
     1.5  
     1.6  TagList::TagList ()
     1.7 -  : m_buffer (0),
     1.8 -    m_size (0)
     1.9 +  : m_used (0),
    1.10 +    m_data (0)
    1.11  {}
    1.12  TagList::TagList (const TagList &o)
    1.13 -  : m_size (o.m_size)
    1.14 +  : m_used (o.m_used),
    1.15 +    m_data (o.m_data)
    1.16  {
    1.17 -  m_buffer = new uint8_t [o.m_size] ();
    1.18 -  memcpy (m_buffer, o.m_buffer, o.m_size);
    1.19 +  if (m_data != 0)
    1.20 +    {
    1.21 +      m_data->count++;
    1.22 +    }
    1.23  }
    1.24  TagList &
    1.25  TagList::operator = (const TagList &o)
    1.26  {
    1.27 -  delete [] m_buffer;
    1.28 -  m_buffer = new uint8_t [o.m_size] ();
    1.29 -  memcpy (m_buffer, o.m_buffer, m_size);
    1.30 -  m_size = o.m_size;
    1.31 +  if (this == &o)
    1.32 +    {
    1.33 +      return *this;
    1.34 +    }
    1.35 +
    1.36 +  Deallocate (m_data);
    1.37 +  m_data = o.m_data;
    1.38 +  m_used = o.m_used;
    1.39 +  if (m_data != 0)
    1.40 +    {
    1.41 +      m_data->count++;
    1.42 +    }
    1.43    return *this;
    1.44  }
    1.45  TagList::~TagList ()
    1.46  {
    1.47 -  delete [] m_buffer;
    1.48 -  m_buffer = 0;
    1.49 -  m_size = 0;
    1.50 +  Deallocate (m_data);
    1.51 +  m_data = 0;
    1.52 +  m_used = 0;
    1.53  }
    1.54  
    1.55  TagBuffer
    1.56  TagList::Add (TypeId tid, uint32_t bufferSize, uint32_t start, uint32_t end)
    1.57  {
    1.58 -  uint32_t newSize = m_size + bufferSize + 4 + 4 + 4 + 4;
    1.59 -  uint8_t *newBuffer = new uint8_t [newSize] ();
    1.60 -  memcpy (newBuffer, m_buffer, m_size);
    1.61 -  TagBuffer tag = TagBuffer (newBuffer + m_size, newBuffer + newSize);
    1.62 +  uint32_t spaceNeeded = m_used + bufferSize + 4 + 4 + 4 + 4;
    1.63 +  NS_ASSERT (m_used <= spaceNeeded);
    1.64 +  if (m_data == 0)
    1.65 +    {
    1.66 +      m_data = Allocate (spaceNeeded);
    1.67 +      m_used = 0;
    1.68 +    } 
    1.69 +  else if (m_data->size < spaceNeeded ||
    1.70 +	   (m_data->count != 1 && m_data->dirty != m_used))
    1.71 +    {
    1.72 +      struct TagList::Data *newData = Allocate (spaceNeeded);
    1.73 +      memcpy (&newData->data, &m_data->data, m_used);
    1.74 +      Deallocate (m_data);
    1.75 +      m_data = newData;
    1.76 +    }
    1.77 +  TagBuffer tag = TagBuffer (&m_data->data[m_used], 
    1.78 +			     &m_data->data[spaceNeeded]);
    1.79    tag.WriteU32 (tid.GetUid ());
    1.80    tag.WriteU32 (bufferSize);
    1.81    tag.WriteU32 (start);
    1.82    tag.WriteU32 (end);
    1.83 -  delete [] m_buffer;
    1.84 -  m_buffer = newBuffer;
    1.85 -  m_size = newSize;
    1.86 +  m_used = spaceNeeded;
    1.87 +  m_data->dirty = m_used;
    1.88    return tag;
    1.89  }
    1.90  
    1.91 @@ -127,15 +150,22 @@
    1.92  void 
    1.93  TagList::RemoveAll (void)
    1.94  {
    1.95 -  delete [] m_buffer;
    1.96 -  m_buffer = 0;
    1.97 -  m_size = 0;  
    1.98 +  Deallocate (m_data);
    1.99 +  m_data = 0;
   1.100 +  m_used = 0;
   1.101  }
   1.102  
   1.103  TagList::Iterator 
   1.104  TagList::Begin (uint32_t offsetStart, uint32_t offsetEnd) const
   1.105  {
   1.106 -  return Iterator (m_buffer, m_buffer + m_size, offsetStart, offsetEnd);
   1.107 +  if (m_data == 0)
   1.108 +    {
   1.109 +      return Iterator (0, 0, offsetStart, offsetEnd);
   1.110 +    }
   1.111 +  else
   1.112 +    {
   1.113 +      return Iterator (m_data->data, &m_data->data[m_used], offsetStart, offsetEnd);
   1.114 +    }
   1.115  }
   1.116  
   1.117  bool 
   1.118 @@ -234,4 +264,32 @@
   1.119    *this = list;    
   1.120  }
   1.121  
   1.122 +
   1.123 +struct TagList::Data *
   1.124 +TagList::Allocate (uint32_t size)
   1.125 +{
   1.126 +  uint8_t *buffer = new uint8_t [size + sizeof (struct TagList::Data) - 4];
   1.127 +  struct Data *data = (struct Data *)buffer;
   1.128 +  data->count = 1;
   1.129 +  data->size = size;
   1.130 +  data->dirty = 0;
   1.131 +  return data;
   1.132 +}
   1.133 +
   1.134 +void 
   1.135 +TagList::Deallocate (struct Data *data)
   1.136 +{
   1.137 +  if (data == 0)
   1.138 +    {
   1.139 +      return;
   1.140 +    }
   1.141 +  data->count--;
   1.142 +  if (data->count == 0)
   1.143 +    {
   1.144 +      uint8_t *buffer = (uint8_t *)data;
   1.145 +      delete [] buffer;
   1.146 +    }
   1.147 +}
   1.148 +
   1.149 +
   1.150  } // namespace ns3
     2.1 --- a/src/common/tag-list.h	Thu Apr 24 16:06:33 2008 -0700
     2.2 +++ b/src/common/tag-list.h	Tue May 06 14:18:05 2008 -0700
     2.3 @@ -58,8 +58,18 @@
     2.4  private:
     2.5    bool IsDirtyAtEnd (uint32_t appendOffset);
     2.6    bool IsDirtyAtStart (uint32_t prependOffset);
     2.7 -  uint8_t *m_buffer;
     2.8 -  uint32_t m_size;
     2.9 +
    2.10 +  struct Data {
    2.11 +    uint32_t size;
    2.12 +    uint32_t count;
    2.13 +    uint32_t dirty;
    2.14 +    uint8_t data[4];
    2.15 +  };
    2.16 +  struct TagList::Data *Allocate (uint32_t size);
    2.17 +  void Deallocate (struct Data *data);
    2.18 +
    2.19 +  uint16_t m_used;
    2.20 +  struct Data *m_data;
    2.21  };
    2.22  
    2.23  } // namespace ns3