# HG changeset patch # User Mathieu Lacage # Date 1210108685 25200 # Node ID d0a9677d545262500b586811e593d28e651108c7 # Parent a624276a897bec22f2f8ba78b5e16c89822aef0d use a shared buffer diff -r a624276a897b -r d0a9677d5452 src/common/tag-list.cc --- a/src/common/tag-list.cc Thu Apr 24 16:06:33 2008 -0700 +++ b/src/common/tag-list.cc Tue May 06 14:18:05 2008 -0700 @@ -64,45 +64,68 @@ TagList::TagList () - : m_buffer (0), - m_size (0) + : m_used (0), + m_data (0) {} TagList::TagList (const TagList &o) - : m_size (o.m_size) + : m_used (o.m_used), + m_data (o.m_data) { - m_buffer = new uint8_t [o.m_size] (); - memcpy (m_buffer, o.m_buffer, o.m_size); + if (m_data != 0) + { + m_data->count++; + } } TagList & TagList::operator = (const TagList &o) { - delete [] m_buffer; - m_buffer = new uint8_t [o.m_size] (); - memcpy (m_buffer, o.m_buffer, m_size); - m_size = o.m_size; + if (this == &o) + { + return *this; + } + + Deallocate (m_data); + m_data = o.m_data; + m_used = o.m_used; + if (m_data != 0) + { + m_data->count++; + } return *this; } TagList::~TagList () { - delete [] m_buffer; - m_buffer = 0; - m_size = 0; + Deallocate (m_data); + m_data = 0; + m_used = 0; } TagBuffer TagList::Add (TypeId tid, uint32_t bufferSize, uint32_t start, uint32_t end) { - uint32_t newSize = m_size + bufferSize + 4 + 4 + 4 + 4; - uint8_t *newBuffer = new uint8_t [newSize] (); - memcpy (newBuffer, m_buffer, m_size); - TagBuffer tag = TagBuffer (newBuffer + m_size, newBuffer + newSize); + uint32_t spaceNeeded = m_used + bufferSize + 4 + 4 + 4 + 4; + NS_ASSERT (m_used <= spaceNeeded); + if (m_data == 0) + { + m_data = Allocate (spaceNeeded); + m_used = 0; + } + else if (m_data->size < spaceNeeded || + (m_data->count != 1 && m_data->dirty != m_used)) + { + struct TagList::Data *newData = Allocate (spaceNeeded); + memcpy (&newData->data, &m_data->data, m_used); + Deallocate (m_data); + m_data = newData; + } + TagBuffer tag = TagBuffer (&m_data->data[m_used], + &m_data->data[spaceNeeded]); tag.WriteU32 (tid.GetUid ()); tag.WriteU32 (bufferSize); tag.WriteU32 (start); tag.WriteU32 (end); - delete [] m_buffer; - m_buffer = newBuffer; - m_size = newSize; + m_used = spaceNeeded; + m_data->dirty = m_used; return tag; } @@ -127,15 +150,22 @@ void TagList::RemoveAll (void) { - delete [] m_buffer; - m_buffer = 0; - m_size = 0; + Deallocate (m_data); + m_data = 0; + m_used = 0; } TagList::Iterator TagList::Begin (uint32_t offsetStart, uint32_t offsetEnd) const { - return Iterator (m_buffer, m_buffer + m_size, offsetStart, offsetEnd); + if (m_data == 0) + { + return Iterator (0, 0, offsetStart, offsetEnd); + } + else + { + return Iterator (m_data->data, &m_data->data[m_used], offsetStart, offsetEnd); + } } bool @@ -234,4 +264,32 @@ *this = list; } + +struct TagList::Data * +TagList::Allocate (uint32_t size) +{ + uint8_t *buffer = new uint8_t [size + sizeof (struct TagList::Data) - 4]; + struct Data *data = (struct Data *)buffer; + data->count = 1; + data->size = size; + data->dirty = 0; + return data; +} + +void +TagList::Deallocate (struct Data *data) +{ + if (data == 0) + { + return; + } + data->count--; + if (data->count == 0) + { + uint8_t *buffer = (uint8_t *)data; + delete [] buffer; + } +} + + } // namespace ns3 diff -r a624276a897b -r d0a9677d5452 src/common/tag-list.h --- a/src/common/tag-list.h Thu Apr 24 16:06:33 2008 -0700 +++ b/src/common/tag-list.h Tue May 06 14:18:05 2008 -0700 @@ -58,8 +58,18 @@ private: bool IsDirtyAtEnd (uint32_t appendOffset); bool IsDirtyAtStart (uint32_t prependOffset); - uint8_t *m_buffer; - uint32_t m_size; + + struct Data { + uint32_t size; + uint32_t count; + uint32_t dirty; + uint8_t data[4]; + }; + struct TagList::Data *Allocate (uint32_t size); + void Deallocate (struct Data *data); + + uint16_t m_used; + struct Data *m_data; }; } // namespace ns3