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