--- 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
--- 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