|
Lines 28-177
NS_LOG_COMPONENT_DEFINE ("PacketTagList");
|
Link Here
|
|---|
|
| 28 |
|
28 |
|
| 29 |
namespace ns3 { |
29 |
namespace ns3 { |
| 30 |
|
30 |
|
| 31 |
#ifdef USE_FREE_LIST |
|
|
| 32 |
|
| 33 |
struct PacketTagList::TagData *PacketTagList::g_free = 0; |
| 34 |
uint32_t PacketTagList::g_nfree = 0; |
| 35 |
|
| 36 |
struct PacketTagList::TagData * |
| 37 |
PacketTagList::AllocData (void) const |
| 38 |
{ |
| 39 |
NS_LOG_FUNCTION (g_nfree); |
| 40 |
struct PacketTagList::TagData *retval; |
| 41 |
if (g_free != 0) |
| 42 |
{ |
| 43 |
retval = g_free; |
| 44 |
g_free = g_free->m_next; |
| 45 |
g_nfree--; |
| 46 |
} |
| 47 |
else |
| 48 |
{ |
| 49 |
retval = new struct PacketTagList::TagData (); |
| 50 |
} |
| 51 |
return retval; |
| 52 |
} |
| 53 |
|
| 54 |
void |
31 |
void |
| 55 |
PacketTagList::FreeData (struct TagData *data) const |
32 |
PacketTagList::Add (Ptr<const Tag> tag) |
| 56 |
{ |
|
|
| 57 |
NS_LOG_FUNCTION (g_nfree << data); |
| 58 |
if (g_nfree > 1000) |
| 59 |
{ |
| 60 |
delete data; |
| 61 |
return; |
| 62 |
} |
| 63 |
g_nfree++; |
| 64 |
data->next = g_free; |
| 65 |
data->tid = TypeId (); |
| 66 |
g_free = data; |
| 67 |
} |
| 68 |
#else |
| 69 |
struct PacketTagList::TagData * |
| 70 |
PacketTagList::AllocData (void) const |
| 71 |
{ |
33 |
{ |
| 72 |
NS_LOG_FUNCTION_NOARGS (); |
34 |
NS_LOG_FUNCTION (this << tag->GetInstanceTypeId ()); |
| 73 |
struct PacketTagList::TagData *retval; |
|
|
| 74 |
retval = new struct PacketTagList::TagData (); |
| 75 |
return retval; |
| 76 |
} |
| 77 |
|
35 |
|
| 78 |
void |
36 |
NS_ASSERT_MSG (Peek (tag->GetInstanceTypeId ()) == 0, |
| 79 |
PacketTagList::FreeData (struct TagData *data) const |
37 |
"Only one tag type per packet is allowed"); |
| 80 |
{ |
38 |
|
| 81 |
NS_LOG_FUNCTION (data); |
39 |
push_back (tag); |
| 82 |
delete data; |
|
|
| 83 |
} |
40 |
} |
| 84 |
#endif |
|
|
| 85 |
|
41 |
|
| 86 |
bool |
42 |
Ptr<const Tag> |
| 87 |
PacketTagList::Remove (Tag &tag) |
43 |
PacketTagList::Remove (TypeId tagType) |
| 88 |
{ |
44 |
{ |
| 89 |
NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); |
45 |
NS_LOG_FUNCTION (this << tagType); |
| 90 |
TypeId tid = tag.GetInstanceTypeId (); |
46 |
|
| 91 |
bool found = false; |
47 |
for (iterator tag = begin (); tag != end (); tag++) |
| 92 |
for (struct TagData *cur = m_next; cur != 0; cur = cur->next) |
|
|
| 93 |
{ |
| 94 |
if (cur->tid == tid) |
| 95 |
{ |
| 96 |
found = true; |
| 97 |
tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE)); |
| 98 |
} |
| 99 |
} |
| 100 |
if (!found) |
| 101 |
{ |
48 |
{ |
| 102 |
return false; |
49 |
if ((*tag)->GetInstanceTypeId () == tagType) |
| 103 |
} |
|
|
| 104 |
struct TagData *start = 0; |
| 105 |
struct TagData **prevNext = &start; |
| 106 |
for (struct TagData *cur = m_next; cur != 0; cur = cur->next) |
| 107 |
{ |
| 108 |
if (cur->tid == tid) |
| 109 |
{ |
50 |
{ |
| 110 |
/** |
51 |
Ptr<const Tag> retval = *tag; |
| 111 |
* XXX |
52 |
erase (tag); |
| 112 |
* Note: I believe that we could optimize this to |
53 |
return retval; |
| 113 |
* avoid copying each TagData located after the target id |
|
|
| 114 |
* and just link the already-copied list to the next tag. |
| 115 |
*/ |
| 116 |
continue; |
| 117 |
} |
54 |
} |
| 118 |
struct TagData *copy = AllocData (); |
|
|
| 119 |
copy->tid = cur->tid; |
| 120 |
copy->count = 1; |
| 121 |
copy->next = 0; |
| 122 |
memcpy (copy->data, cur->data, PACKET_TAG_MAX_SIZE); |
| 123 |
*prevNext = copy; |
| 124 |
prevNext = ©->next; |
| 125 |
} |
55 |
} |
| 126 |
*prevNext = 0; |
|
|
| 127 |
RemoveAll (); |
| 128 |
m_next = start; |
| 129 |
return true; |
| 130 |
} |
| 131 |
|
56 |
|
| 132 |
void |
57 |
return 0; |
| 133 |
PacketTagList::Add (const Tag &tag) const |
|
|
| 134 |
{ |
| 135 |
NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); |
| 136 |
// ensure this id was not yet added |
| 137 |
for (struct TagData *cur = m_next; cur != 0; cur = cur->next) |
| 138 |
{ |
| 139 |
NS_ASSERT (cur->tid != tag.GetInstanceTypeId ()); |
| 140 |
} |
| 141 |
struct TagData *head = AllocData (); |
| 142 |
head->count = 1; |
| 143 |
head->next = 0; |
| 144 |
head->tid = tag.GetInstanceTypeId (); |
| 145 |
head->next = m_next; |
| 146 |
NS_ASSERT (tag.GetSerializedSize () <= PACKET_TAG_MAX_SIZE); |
| 147 |
tag.Serialize (TagBuffer (head->data, head->data+tag.GetSerializedSize ())); |
| 148 |
|
| 149 |
const_cast<PacketTagList *> (this)->m_next = head; |
| 150 |
} |
58 |
} |
| 151 |
|
59 |
|
| 152 |
bool |
60 |
Ptr<const Tag> |
| 153 |
PacketTagList::Peek (Tag &tag) const |
61 |
PacketTagList::Peek (TypeId tagType) const |
| 154 |
{ |
62 |
{ |
| 155 |
NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); |
63 |
NS_LOG_FUNCTION (this << tagType); |
| 156 |
TypeId tid = tag.GetInstanceTypeId (); |
64 |
for (const_iterator tag = begin (); tag != end (); tag++) |
| 157 |
for (struct TagData *cur = m_next; cur != 0; cur = cur->next) |
|
|
| 158 |
{ |
65 |
{ |
| 159 |
if (cur->tid == tid) |
66 |
if ((*tag)->GetInstanceTypeId () == tagType) |
| 160 |
{ |
67 |
return *tag; |
| 161 |
/* found tag */ |
|
|
| 162 |
tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE)); |
| 163 |
return true; |
| 164 |
} |
| 165 |
} |
68 |
} |
| 166 |
/* no tag found */ |
|
|
| 167 |
return false; |
| 168 |
} |
| 169 |
|
69 |
|
| 170 |
const struct PacketTagList::TagData * |
70 |
return 0; |
| 171 |
PacketTagList::Head (void) const |
|
|
| 172 |
{ |
| 173 |
return m_next; |
| 174 |
} |
71 |
} |
| 175 |
|
72 |
|
|
|
73 |
|
| 74 |
// bool |
| 75 |
// PacketTagList::Remove (Tag &tag) |
| 76 |
// { |
| 77 |
// NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); |
| 78 |
|
| 79 |
// return false; |
| 80 |
|
| 81 |
// // TypeId tid = tag.GetInstanceTypeId (); |
| 82 |
// // bool found = false; |
| 83 |
// // for (struct TagData *cur = m_next; cur != 0; cur = cur->next) |
| 84 |
// // { |
| 85 |
// // if (cur->tid == tid) |
| 86 |
// // { |
| 87 |
// // found = true; |
| 88 |
// // tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE)); |
| 89 |
// // } |
| 90 |
// // } |
| 91 |
// // if (!found) |
| 92 |
// // { |
| 93 |
// // return false; |
| 94 |
// // } |
| 95 |
// // struct TagData *start = 0; |
| 96 |
// // struct TagData **prevNext = &start; |
| 97 |
// // for (struct TagData *cur = m_next; cur != 0; cur = cur->next) |
| 98 |
// // { |
| 99 |
// // if (cur->tid == tid) |
| 100 |
// // { |
| 101 |
// // /** |
| 102 |
// // * XXX |
| 103 |
// // * Note: I believe that we could optimize this to |
| 104 |
// // * avoid copying each TagData located after the target id |
| 105 |
// // * and just link the already-copied list to the next tag. |
| 106 |
// // */ |
| 107 |
// // continue; |
| 108 |
// // } |
| 109 |
// // struct TagData *copy = AllocData (); |
| 110 |
// // copy->tid = cur->tid; |
| 111 |
// // copy->count = 1; |
| 112 |
// // copy->next = 0; |
| 113 |
// // memcpy (copy->data, cur->data, PACKET_TAG_MAX_SIZE); |
| 114 |
// // *prevNext = copy; |
| 115 |
// // prevNext = ©->next; |
| 116 |
// // } |
| 117 |
// // *prevNext = 0; |
| 118 |
// // RemoveAll (); |
| 119 |
// // m_next = start; |
| 120 |
// // return true; |
| 121 |
// } |
| 122 |
|
| 123 |
// void |
| 124 |
// PacketTagList::Add (const Tag &tag) const |
| 125 |
// { |
| 126 |
// NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); |
| 127 |
// // ensure this id was not yet added |
| 128 |
|
| 129 |
// // for (struct TagData *cur = m_next; cur != 0; cur = cur->next) |
| 130 |
// // { |
| 131 |
// // NS_ASSERT (cur->tid != tag.GetInstanceTypeId ()); |
| 132 |
// // } |
| 133 |
|
| 134 |
// // struct TagData *head = AllocData (); |
| 135 |
// // head->count = 1; |
| 136 |
// // head->next = 0; |
| 137 |
// // head->tid = tag.GetInstanceTypeId (); |
| 138 |
// // head->next = m_next; |
| 139 |
// // NS_ASSERT (tag.GetSerializedSize () <= PACKET_TAG_MAX_SIZE); |
| 140 |
// // tag.Serialize (TagBuffer (head->data, head->data+tag.GetSerializedSize ())); |
| 141 |
|
| 142 |
// // const_cast<PacketTagList *> (this)->m_next = head; |
| 143 |
|
| 144 |
// // m_tags. |
| 145 |
// } |
| 146 |
|
| 147 |
// bool |
| 148 |
// PacketTagList::Peek (Tag &tag) const |
| 149 |
// { |
| 150 |
// NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); |
| 151 |
// // TypeId tid = tag.GetInstanceTypeId (); |
| 152 |
// // for (struct TagData *cur = m_next; cur != 0; cur = cur->next) |
| 153 |
// // { |
| 154 |
// // if (cur->tid == tid) |
| 155 |
// // { |
| 156 |
// // /* found tag */ |
| 157 |
// // tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE)); |
| 158 |
// // return true; |
| 159 |
// // } |
| 160 |
// // } |
| 161 |
|
| 162 |
// /* no tag found */ |
| 163 |
// return false; |
| 164 |
// } |
| 165 |
|
| 166 |
// // const struct PacketTagList::TagData * |
| 167 |
// // PacketTagList::Head (void) const |
| 168 |
// // { |
| 169 |
// // return m_next; |
| 170 |
// // } |
| 171 |
|
| 176 |
} // namespace ns3 |
172 |
} // namespace ns3 |
| 177 |
|
173 |
|