1.1 --- a/src/common/packet-metadata-test.cc Tue Jun 03 21:16:21 2008 +0100
1.2 +++ b/src/common/packet-metadata-test.cc Tue Jun 03 21:19:36 2008 +0100
1.3 @@ -746,7 +746,11 @@
1.4 CHECK_HISTORY (p, 3, 1, 1000, 3);
1.5 CHECK_HISTORY (p1, 3, 2, 1000, 3);
1.6
1.7 -
1.8 + p = Create<Packet> (200);
1.9 + ADD_HEADER (p, 24);
1.10 + p1 = p->CreateFragment(0, 100);
1.11 + p2 = p->CreateFragment(100, 100);
1.12 + p1->AddAtEnd (p2);
1.13
1.14 return result;
1.15 }
2.1 --- a/src/common/packet-metadata.cc Tue Jun 03 21:16:21 2008 +0100
2.2 +++ b/src/common/packet-metadata.cc Tue Jun 03 21:19:36 2008 +0100
2.3 @@ -186,101 +186,6 @@
2.4 buffer[2] = (value >> 16) & 0xff;
2.5 buffer[3] = (value >> 24) & 0xff;
2.6 }
2.7 -bool
2.8 -PacketMetadata::TryToAppend16 (uint16_t value, uint8_t **pBuffer, uint8_t *end)
2.9 -{
2.10 - uint8_t *start = *pBuffer;
2.11 - if (start + 1 < end)
2.12 - {
2.13 - start[0] = value & 0xff;
2.14 - start[1] = value >> 8;
2.15 - *pBuffer = start + 2;
2.16 - return true;
2.17 - }
2.18 - return false;
2.19 -}
2.20 -bool
2.21 -PacketMetadata::TryToAppend32 (uint32_t value, uint8_t **pBuffer, uint8_t *end)
2.22 -{
2.23 - uint8_t *start = *pBuffer;
2.24 - if (start + 3 < end)
2.25 - {
2.26 - start[0] = value & 0xff;
2.27 - start[1] = (value >> 8) & 0xff;
2.28 - start[2] = (value >> 16) & 0xff;
2.29 - start[3] = (value >> 24) & 0xff;
2.30 - *pBuffer = start + 4;
2.31 - return true;
2.32 - }
2.33 - return false;
2.34 -}
2.35 -bool
2.36 -PacketMetadata::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end)
2.37 -{
2.38 - uint8_t *start = *pBuffer;
2.39 - if (value < 0x80 && start < end)
2.40 - {
2.41 - start[0] = value;
2.42 - *pBuffer = start + 1;
2.43 - return true;
2.44 - }
2.45 - if (value < 0x4000 && start + 1 < end)
2.46 - {
2.47 - uint8_t byte = value & (~0x80);
2.48 - start[0] = 0x80 | byte;
2.49 - value >>= 7;
2.50 - start[1] = value;
2.51 - *pBuffer = start + 2;
2.52 - return true;
2.53 - }
2.54 - if (value < 0x200000 && start + 2 < end)
2.55 - {
2.56 - uint8_t byte = value & (~0x80);
2.57 - start[0] = 0x80 | byte;
2.58 - value >>= 7;
2.59 - byte = value & (~0x80);
2.60 - start[1] = 0x80 | byte;
2.61 - value >>= 7;
2.62 - byte = value & (~0x80);
2.63 - start[2] = value;
2.64 - *pBuffer = start + 3;
2.65 - return true;
2.66 - }
2.67 - if (value < 0x10000000 && start + 3 < end)
2.68 - {
2.69 - uint8_t byte = value & (~0x80);
2.70 - start[0] = 0x80 | byte;
2.71 - value >>= 7;
2.72 - byte = value & (~0x80);
2.73 - start[1] = 0x80 | byte;
2.74 - value >>= 7;
2.75 - byte = value & (~0x80);
2.76 - start[2] = 0x80 | byte;
2.77 - value >>= 7;
2.78 - start[3] = value;
2.79 - *pBuffer = start + 4;
2.80 - return true;
2.81 - }
2.82 - if (start + 4 < end)
2.83 - {
2.84 - uint8_t byte = value & (~0x80);
2.85 - start[0] = 0x80 | byte;
2.86 - value >>= 7;
2.87 - byte = value & (~0x80);
2.88 - start[1] = 0x80 | byte;
2.89 - value >>= 7;
2.90 - byte = value & (~0x80);
2.91 - start[2] = 0x80 | byte;
2.92 - value >>= 7;
2.93 - byte = value & (~0x80);
2.94 - start[3] = 0x80 | byte;
2.95 - value >>= 7;
2.96 - start[4] = value;
2.97 - *pBuffer = start + 5;
2.98 - return true;
2.99 - }
2.100 - return false;
2.101 -}
2.102
2.103 void
2.104 PacketMetadata::AppendValueExtra (uint32_t value, uint8_t *buffer)
2.105 @@ -350,6 +255,7 @@
2.106 void
2.107 PacketMetadata::UpdateTail (uint16_t written)
2.108 {
2.109 + NS_LOG_FUNCTION (this << written);
2.110 if (m_head == 0xffff)
2.111 {
2.112 NS_ASSERT (m_tail == 0xffff);
2.113 @@ -376,6 +282,7 @@
2.114 void
2.115 PacketMetadata::UpdateHead (uint16_t written)
2.116 {
2.117 + NS_LOG_FUNCTION (this << written);
2.118 if (m_head == 0xffff)
2.119 {
2.120 NS_ASSERT (m_tail == 0xffff);
2.121 @@ -401,6 +308,7 @@
2.122 uint16_t
2.123 PacketMetadata::AddSmall (const struct PacketMetadata::SmallItem *item)
2.124 {
2.125 + NS_LOG_FUNCTION (this << item->next << item->prev << item->typeUid << item->size << item->chunkUid);
2.126 NS_ASSERT (m_data != 0);
2.127 NS_ASSERT (m_used != item->prev && m_used != item->next);
2.128 uint32_t typeUidSize = GetUleb128Size (item->typeUid);
2.129 @@ -431,6 +339,9 @@
2.130 const PacketMetadata::SmallItem *item,
2.131 const PacketMetadata::ExtraItem *extraItem)
2.132 {
2.133 + NS_LOG_FUNCTION (this << next << prev <<
2.134 + item->next << item->prev << item->typeUid << item->size << item->chunkUid <<
2.135 + extraItem->fragmentStart << extraItem->fragmentEnd << extraItem->packetUid);
2.136 NS_ASSERT (m_data != 0);
2.137 uint32_t typeUid = ((item->typeUid & 0x1) == 0x1)?item->typeUid:item->typeUid+1;
2.138 NS_ASSERT (m_used != prev && m_used != next);
2.139 @@ -470,34 +381,68 @@
2.140 return n;
2.141 }
2.142
2.143 +/**
2.144 + * \param item the item data to write
2.145 + * \param extraItem the extra item data to write
2.146 + * \param available the number of bytes which can
2.147 + * be written without having to rewrite the buffer entirely.
2.148 + */
2.149 void
2.150 PacketMetadata::ReplaceTail (PacketMetadata::SmallItem *item,
2.151 PacketMetadata::ExtraItem *extraItem,
2.152 uint32_t available)
2.153 {
2.154 + NS_LOG_FUNCTION (this <<
2.155 + item->next << item->prev << item->typeUid << item->size << item->chunkUid <<
2.156 + extraItem->fragmentStart << extraItem->fragmentEnd << extraItem->packetUid <<
2.157 + available);
2.158 +
2.159 NS_ASSERT (m_data != 0);
2.160 - if (available >= 14 &&
2.161 + /* If the tail we want to replace is located at the end of the data array,
2.162 + * and if there is extra room at the end of this array, then,
2.163 + * we can try to use that extra space to avoid falling in the slow
2.164 + * path below.
2.165 + */
2.166 + if (m_tail + available == m_used &&
2.167 + m_used == m_data->m_dirtyEnd)
2.168 + {
2.169 + available = m_data->m_size - m_tail;
2.170 + }
2.171 +
2.172 + uint32_t typeUid = ((item->typeUid & 0x1) == 0x1)?item->typeUid:item->typeUid+1;
2.173 + uint32_t typeUidSize = GetUleb128Size (typeUid);
2.174 + uint32_t sizeSize = GetUleb128Size (item->size);
2.175 + uint32_t fragStartSize = GetUleb128Size (extraItem->fragmentStart);
2.176 + uint32_t fragEndSize = GetUleb128Size (extraItem->fragmentEnd);
2.177 + uint32_t n = 2 + 2 + typeUidSize + sizeSize + 2 + fragStartSize + fragEndSize + 4;
2.178 +
2.179 + if (available >= n &&
2.180 m_data->m_count == 1)
2.181 {
2.182 uint8_t *buffer = &m_data->m_data[m_tail];
2.183 - uint8_t *end = buffer + available;
2.184 -
2.185 Append16 (item->next, buffer);
2.186 buffer += 2;
2.187 Append16 (item->prev, buffer);
2.188 buffer += 2;
2.189 - if (TryToAppend (item->typeUid, &buffer, end) &&
2.190 - TryToAppend (item->size, &buffer, end) &&
2.191 - TryToAppend16 (item->chunkUid, &buffer, end) &&
2.192 - TryToAppend (extraItem->fragmentStart, &buffer, end) &&
2.193 - TryToAppend (extraItem->fragmentEnd, &buffer, end) &&
2.194 - TryToAppend32 (extraItem->packetUid, &buffer, end))
2.195 - {
2.196 - m_used = buffer - &m_data->m_data[0];
2.197 - m_data->m_dirtyEnd = m_used;
2.198 - return;
2.199 - }
2.200 + AppendValue (typeUid, buffer);
2.201 + buffer += typeUidSize;
2.202 + AppendValue (item->size, buffer);
2.203 + buffer += sizeSize;
2.204 + Append16 (item->chunkUid, buffer);
2.205 + buffer += 2;
2.206 + AppendValue (extraItem->fragmentStart, buffer);
2.207 + buffer += fragStartSize;
2.208 + AppendValue (extraItem->fragmentEnd, buffer);
2.209 + buffer += fragEndSize;
2.210 + Append32 (extraItem->packetUid, buffer);
2.211 + m_used = buffer - &m_data->m_data[0];
2.212 + m_data->m_dirtyEnd = m_used;
2.213 + return;
2.214 }
2.215 +
2.216 + /* Below is the slow path which is hit if the new tail we want
2.217 + * to append is bigger than the previous tail.
2.218 + */
2.219
2.220 // create a copy of the packet.
2.221 PacketMetadata h (m_packetUid, 0);
2.222 @@ -510,6 +455,7 @@
2.223 uint16_t written = h.AddBig (0xffff, h.m_tail,
2.224 &tmpItem, &tmpExtraItem);
2.225 h.UpdateTail (written);
2.226 + current = tmpItem.next;
2.227 }
2.228 // append new tail.
2.229 uint16_t written = h.AddBig (0xffff, h.m_tail, item, extraItem);
2.230 @@ -518,11 +464,18 @@
2.231 *this = h;
2.232 }
2.233
2.234 +/**
2.235 + * \param current the offset we should start reading the data from
2.236 + * \param item pointer to where we should store the data to return to the caller
2.237 + * \param extraItem pointer to where we should store the data to return to the caller
2.238 + * \returns the number of bytes read.
2.239 + */
2.240 uint32_t
2.241 PacketMetadata::ReadItems (uint16_t current,
2.242 struct PacketMetadata::SmallItem *item,
2.243 struct PacketMetadata::ExtraItem *extraItem) const
2.244 {
2.245 + NS_LOG_FUNCTION (this << current);
2.246 const uint8_t *buffer = &m_data->m_data[current];
2.247 item->next = buffer[0];
2.248 item->next |= (buffer[1]) << 8;
2.249 @@ -644,12 +597,12 @@
2.250 void
2.251 PacketMetadata::DoAddHeader (uint32_t uid, uint32_t size)
2.252 {
2.253 + NS_LOG_FUNCTION (this << uid << size);
2.254 if (!m_enable)
2.255 {
2.256 m_metadataSkipped = true;
2.257 return;
2.258 }
2.259 - NS_LOG_FUNCTION ("uid=" << uid << "size=" << size << "");
2.260
2.261 struct PacketMetadata::SmallItem item;
2.262 item.next = m_head;
2.263 @@ -665,12 +618,12 @@
2.264 PacketMetadata::RemoveHeader (const Header &header, uint32_t size)
2.265 {
2.266 uint32_t uid = header.GetInstanceTypeId ().GetUid () << 1;
2.267 + NS_LOG_FUNCTION (this << uid << size);
2.268 if (!m_enable)
2.269 {
2.270 m_metadataSkipped = true;
2.271 return;
2.272 }
2.273 - NS_LOG_FUNCTION ("(uid=" << uid << ", size=" << size << ")");
2.274 struct PacketMetadata::SmallItem item;
2.275 struct PacketMetadata::ExtraItem extraItem;
2.276 uint32_t read = ReadItems (m_head, &item, &extraItem);
2.277 @@ -703,12 +656,12 @@
2.278 PacketMetadata::AddTrailer (const Trailer &trailer, uint32_t size)
2.279 {
2.280 uint32_t uid = trailer.GetInstanceTypeId ().GetUid () << 1;
2.281 + NS_LOG_FUNCTION (this << uid << size);
2.282 if (!m_enable)
2.283 {
2.284 m_metadataSkipped = true;
2.285 return;
2.286 }
2.287 - NS_LOG_FUNCTION ("(uid=" << uid << ", size=" << size << ")");
2.288 struct PacketMetadata::SmallItem item;
2.289 item.next = 0xffff;
2.290 item.prev = m_tail;
2.291 @@ -723,12 +676,12 @@
2.292 PacketMetadata::RemoveTrailer (const Trailer &trailer, uint32_t size)
2.293 {
2.294 uint32_t uid = trailer.GetInstanceTypeId ().GetUid () << 1;
2.295 + NS_LOG_FUNCTION (this << uid << size);
2.296 if (!m_enable)
2.297 {
2.298 m_metadataSkipped = true;
2.299 return;
2.300 }
2.301 - NS_LOG_FUNCTION ("(uid=" << uid << ", size=" << size << ")");
2.302 struct PacketMetadata::SmallItem item;
2.303 struct PacketMetadata::ExtraItem extraItem;
2.304 uint32_t read = ReadItems (m_tail, &item, &extraItem);
2.305 @@ -760,6 +713,7 @@
2.306 void
2.307 PacketMetadata::AddAtEnd (PacketMetadata const&o)
2.308 {
2.309 + NS_LOG_FUNCTION (this << &o);
2.310 if (!m_enable)
2.311 {
2.312 m_metadataSkipped = true;
2.313 @@ -767,46 +721,53 @@
2.314 }
2.315 if (m_tail == 0xffff)
2.316 {
2.317 + // We have no items so 'AddAtEnd' is
2.318 + // equivalent to self-assignment.
2.319 *this = o;
2.320 return;
2.321 }
2.322 NS_ASSERT (m_head != 0xffff && m_tail != 0xffff);
2.323
2.324 - uint16_t lastTail;
2.325 - lastTail = m_tail;
2.326 - struct PacketMetadata::SmallItem lastItem;
2.327 - PacketMetadata::ExtraItem lastExtraItem;
2.328 - uint32_t lastTailSize = ReadItems (m_tail, &lastItem, &lastExtraItem);
2.329 - if (m_tail + lastTailSize == m_used &&
2.330 - m_used == m_data->m_dirtyEnd)
2.331 + // We read the current tail because we are going to append
2.332 + // after this item.
2.333 + struct PacketMetadata::SmallItem tailItem;
2.334 + PacketMetadata::ExtraItem tailExtraItem;
2.335 + uint32_t tailSize = ReadItems (m_tail, &tailItem, &tailExtraItem);
2.336 +
2.337 + uint16_t current;
2.338 + struct PacketMetadata::SmallItem item;
2.339 + PacketMetadata::ExtraItem extraItem;
2.340 + o.ReadItems (o.m_head, &item, &extraItem);
2.341 + if (extraItem.packetUid == tailExtraItem.packetUid &&
2.342 + item.typeUid == tailItem.typeUid &&
2.343 + item.chunkUid == tailItem.chunkUid &&
2.344 + item.size == tailItem.size &&
2.345 + extraItem.fragmentStart == tailExtraItem.fragmentEnd)
2.346 {
2.347 - lastTailSize = m_data->m_size - m_tail;
2.348 + /* If the previous tail came from the same header as
2.349 + * the next item we want to append to our array, then,
2.350 + * we merge them and attempt to reuse the previous tail's
2.351 + * location.
2.352 + */
2.353 + tailExtraItem.fragmentEnd = extraItem.fragmentEnd;
2.354 + // XXX This call might be wrong.
2.355 + ReplaceTail (&tailItem, &tailExtraItem, tailSize);
2.356 + current = item.next;
2.357 + }
2.358 + else
2.359 + {
2.360 + current = o.m_head;
2.361 }
2.362
2.363 - uint16_t current = o.m_head;
2.364 + /* Now that we have merged our current tail with the head of the
2.365 + * next packet, we just append all items from the next packet
2.366 + * to the current packet.
2.367 + */
2.368 while (current != 0xffff)
2.369 {
2.370 - struct PacketMetadata::SmallItem item;
2.371 - PacketMetadata::ExtraItem extraItem;
2.372 o.ReadItems (current, &item, &extraItem);
2.373 - if (extraItem.packetUid == lastExtraItem.packetUid &&
2.374 - item.typeUid == lastItem.typeUid &&
2.375 - item.chunkUid == lastItem.chunkUid &&
2.376 - item.size == lastItem.size &&
2.377 - extraItem.fragmentStart == lastExtraItem.fragmentEnd)
2.378 - {
2.379 - // replace previous tail.
2.380 - lastExtraItem.fragmentEnd = extraItem.fragmentEnd;
2.381 - NS_ASSERT (m_tail == lastTail);
2.382 - // XXX This call might be wrong.
2.383 - ReplaceTail (&lastItem, &lastExtraItem, lastTailSize);
2.384 - }
2.385 - else
2.386 - {
2.387 - // append the extra items.
2.388 - uint16_t written = AddBig (0xffff, m_tail, &item, &extraItem);
2.389 - UpdateTail (written);
2.390 - }
2.391 + uint16_t written = AddBig (0xffff, m_tail, &item, &extraItem);
2.392 + UpdateTail (written);
2.393 if (current == o.m_tail)
2.394 {
2.395 break;
2.396 @@ -826,6 +787,7 @@
2.397 void
2.398 PacketMetadata::RemoveAtStart (uint32_t start)
2.399 {
2.400 + NS_LOG_FUNCTION (this << start);
2.401 if (!m_enable)
2.402 {
2.403 m_metadataSkipped = true;
2.404 @@ -891,6 +853,7 @@
2.405 void
2.406 PacketMetadata::RemoveAtEnd (uint32_t end)
2.407 {
2.408 + NS_LOG_FUNCTION (this << end);
2.409 if (!m_enable)
2.410 {
2.411 m_metadataSkipped = true;
2.412 @@ -1069,6 +1032,7 @@
2.413 uint32_t
2.414 PacketMetadata::GetSerializedSize (void) const
2.415 {
2.416 + NS_LOG_FUNCTION (this);
2.417 uint32_t totalSize = 0;
2.418 totalSize += 4;
2.419 if (!m_enable)
2.420 @@ -1105,6 +1069,7 @@
2.421 void
2.422 PacketMetadata::Serialize (Buffer::Iterator i, uint32_t size) const
2.423 {
2.424 + NS_LOG_FUNCTION (this);
2.425 uint32_t bytesWritten = 0;
2.426 i.WriteU32 (size);
2.427 bytesWritten += 4;
2.428 @@ -1160,6 +1125,7 @@
2.429 uint32_t
2.430 PacketMetadata::Deserialize (Buffer::Iterator i)
2.431 {
2.432 + NS_LOG_FUNCTION (this);
2.433 struct PacketMetadata::SmallItem item;
2.434 struct PacketMetadata::ExtraItem extraItem;
2.435 uint32_t totalSize = i.ReadU32 ();
3.1 --- a/src/common/packet-metadata.h Tue Jun 03 21:16:21 2008 +0100
3.2 +++ b/src/common/packet-metadata.h Tue Jun 03 21:19:36 2008 +0100
3.3 @@ -254,9 +254,6 @@
3.4 uint32_t ReadUleb128 (const uint8_t **pBuffer) const;
3.5 inline void Append16 (uint16_t value, uint8_t *buffer);
3.6 inline void Append32 (uint32_t value, uint8_t *buffer);
3.7 - inline bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end);
3.8 - inline bool TryToAppend32 (uint32_t value, uint8_t **pBuffer, uint8_t *end);
3.9 - inline bool TryToAppend16 (uint16_t value, uint8_t **pBuffer, uint8_t *end);
3.10 inline void AppendValue (uint32_t value, uint8_t *buffer);
3.11 void AppendValueExtra (uint32_t value, uint8_t *buffer);
3.12 inline void Reserve (uint32_t n);