OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/crypto/strike_register.h" | 5 #include "net/quic/crypto/strike_register.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 | 8 |
9 using std::pair; | 9 using std::pair; |
10 using std::set; | 10 using std::set; |
(...skipping 19 matching lines...) Expand all Loading... |
30 void SetCritByte(uint8 critbyte) { | 30 void SetCritByte(uint8 critbyte) { |
31 data_[0] &= 0xffffff00; | 31 data_[0] &= 0xffffff00; |
32 data_[0] |= critbyte; | 32 data_[0] |= critbyte; |
33 } | 33 } |
34 | 34 |
35 void SetOtherBits(uint8 otherbits) { | 35 void SetOtherBits(uint8 otherbits) { |
36 data_[1] &= 0xffffff00; | 36 data_[1] &= 0xffffff00; |
37 data_[1] |= otherbits; | 37 data_[1] |= otherbits; |
38 } | 38 } |
39 | 39 |
40 void SetNextPtr(uint32 next) { | 40 void SetNextPtr(uint32 next) { data_[0] = next; } |
41 data_[0] = next; | |
42 } | |
43 | 41 |
44 uint32 next() const { | 42 uint32 next() const { return data_[0]; } |
45 return data_[0]; | |
46 } | |
47 | 43 |
48 uint32 child(unsigned n) const { | 44 uint32 child(unsigned n) const { return data_[n] >> 8; } |
49 return data_[n] >> 8; | |
50 } | |
51 | 45 |
52 uint8 critbyte() const { | 46 uint8 critbyte() const { return data_[0]; } |
53 return data_[0]; | |
54 } | |
55 | 47 |
56 uint8 otherbits() const { | 48 uint8 otherbits() const { return data_[1]; } |
57 return data_[1]; | |
58 } | |
59 | 49 |
60 // These bytes are organised thus: | 50 // These bytes are organised thus: |
61 // <24 bits> left child | 51 // <24 bits> left child |
62 // <8 bits> crit-byte | 52 // <8 bits> crit-byte |
63 // <24 bits> right child | 53 // <24 bits> right child |
64 // <8 bits> other-bits | 54 // <8 bits> other-bits |
65 uint32 data_[2]; | 55 uint32 data_[2]; |
66 }; | 56 }; |
67 | 57 |
68 StrikeRegister::StrikeRegister(unsigned max_entries, | 58 StrikeRegister::StrikeRegister(unsigned max_entries, |
(...skipping 12 matching lines...) Expand all Loading... |
81 // We only have 23 bits of index available. | 71 // We only have 23 bits of index available. |
82 CHECK_LT(max_entries, 1u << 23); | 72 CHECK_LT(max_entries, 1u << 23); |
83 CHECK_GT(max_entries, 1u); // There must be at least two entries. | 73 CHECK_GT(max_entries, 1u); // There must be at least two entries. |
84 CHECK_EQ(sizeof(InternalNode), 8u); // in case of compiler changes. | 74 CHECK_EQ(sizeof(InternalNode), 8u); // in case of compiler changes. |
85 internal_nodes_ = new InternalNode[max_entries]; | 75 internal_nodes_ = new InternalNode[max_entries]; |
86 external_nodes_.reset(new uint8[kExternalNodeSize * max_entries]); | 76 external_nodes_.reset(new uint8[kExternalNodeSize * max_entries]); |
87 | 77 |
88 Reset(); | 78 Reset(); |
89 } | 79 } |
90 | 80 |
91 StrikeRegister::~StrikeRegister() { | 81 StrikeRegister::~StrikeRegister() { delete[] internal_nodes_; } |
92 delete[] internal_nodes_; | |
93 } | |
94 | 82 |
95 void StrikeRegister::Reset() { | 83 void StrikeRegister::Reset() { |
96 // Thread a free list through all of the internal nodes. | 84 // Thread a free list through all of the internal nodes. |
97 internal_node_free_head_ = 0; | 85 internal_node_free_head_ = 0; |
98 for (unsigned i = 0; i < max_entries_ - 1; i++) | 86 for (unsigned i = 0; i < max_entries_ - 1; i++) |
99 internal_nodes_[i].SetNextPtr(i + 1); | 87 internal_nodes_[i].SetNextPtr(i + 1); |
100 internal_nodes_[max_entries_ - 1].SetNextPtr(kNil); | 88 internal_nodes_[max_entries_ - 1].SetNextPtr(kNil); |
101 | 89 |
102 // Also thread a free list through the external nodes. | 90 // Also thread a free list through the external nodes. |
103 external_node_free_head_ = 0; | 91 external_node_free_head_ = 0; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 node->otherbits() > new_other_bits) { | 223 node->otherbits() > new_other_bits) { |
236 break; | 224 break; |
237 } | 225 } |
238 if (node->critbyte() == differing_byte && | 226 if (node->critbyte() == differing_byte && |
239 node->otherbits() == new_other_bits) { | 227 node->otherbits() == new_other_bits) { |
240 CHECK(false); | 228 CHECK(false); |
241 } | 229 } |
242 | 230 |
243 uint8 c = value[node->critbyte()]; | 231 uint8 c = value[node->critbyte()]; |
244 const int direction = | 232 const int direction = |
245 (1 + static_cast<unsigned>(node->otherbits() | c)) >> 8; | 233 (1 + static_cast<unsigned>(node->otherbits() | c)) >> 8; |
246 where_index = &node->data_[direction]; | 234 where_index = &node->data_[direction]; |
247 } | 235 } |
248 | 236 |
249 inode->SetChild(newdirection ^ 1, *where_index >> 8); | 237 inode->SetChild(newdirection ^ 1, *where_index >> 8); |
250 *where_index = (*where_index & 0xff) | (internal_node_index << 8); | 238 *where_index = (*where_index & 0xff) | (internal_node_index << 8); |
251 | 239 |
252 return true; | 240 return true; |
253 } | 241 } |
254 | 242 |
255 void StrikeRegister::Validate() { | 243 void StrikeRegister::Validate() { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 uint32 StrikeRegister::BestMatch(const uint8 v[24]) const { | 280 uint32 StrikeRegister::BestMatch(const uint8 v[24]) const { |
293 if (internal_node_head_ == kNil) { | 281 if (internal_node_head_ == kNil) { |
294 return kNil; | 282 return kNil; |
295 } | 283 } |
296 | 284 |
297 uint32 next = internal_node_head_ >> 8; | 285 uint32 next = internal_node_head_ >> 8; |
298 while ((next & kExternalFlag) == 0) { | 286 while ((next & kExternalFlag) == 0) { |
299 InternalNode* node = &internal_nodes_[next]; | 287 InternalNode* node = &internal_nodes_[next]; |
300 uint8 b = v[node->critbyte()]; | 288 uint8 b = v[node->critbyte()]; |
301 unsigned direction = | 289 unsigned direction = |
302 (1 + static_cast<unsigned>(node->otherbits() | b)) >> 8; | 290 (1 + static_cast<unsigned>(node->otherbits() | b)) >> 8; |
303 next = node->child(direction); | 291 next = node->child(direction); |
304 } | 292 } |
305 | 293 |
306 return next & ~kExternalFlag; | 294 return next & ~kExternalFlag; |
307 } | 295 } |
308 | 296 |
309 uint32& StrikeRegister::external_node_next_ptr(unsigned i) { | 297 uint32& StrikeRegister::external_node_next_ptr(unsigned i) { |
310 return *reinterpret_cast<uint32*>(&external_nodes_[i * kExternalNodeSize]); | 298 return *reinterpret_cast<uint32*>(&external_nodes_[i * kExternalNodeSize]); |
311 } | 299 } |
312 | 300 |
(...skipping 27 matching lines...) Expand all Loading... |
340 // DropNode should never be called on an empty tree. | 328 // DropNode should never be called on an empty tree. |
341 DCHECK(internal_node_head_ != kNil); | 329 DCHECK(internal_node_head_ != kNil); |
342 | 330 |
343 // An internal node in a crit-bit tree always has exactly two children. | 331 // An internal node in a crit-bit tree always has exactly two children. |
344 // This means that, if we are removing an external node (which is one of | 332 // This means that, if we are removing an external node (which is one of |
345 // those children), then we also need to remove an internal node. In order | 333 // those children), then we also need to remove an internal node. In order |
346 // to do that we keep pointers to the parent (wherep) and grandparent | 334 // to do that we keep pointers to the parent (wherep) and grandparent |
347 // (whereq) when walking down the tree. | 335 // (whereq) when walking down the tree. |
348 | 336 |
349 uint32 p = internal_node_head_ >> 8, *wherep = &internal_node_head_, | 337 uint32 p = internal_node_head_ >> 8, *wherep = &internal_node_head_, |
350 *whereq = NULL; | 338 *whereq = NULL; |
351 while ((p & kExternalFlag) == 0) { | 339 while ((p & kExternalFlag) == 0) { |
352 whereq = wherep; | 340 whereq = wherep; |
353 InternalNode* inode = &internal_nodes_[p]; | 341 InternalNode* inode = &internal_nodes_[p]; |
354 // We always go left, towards the smallest element, exploiting the fact | 342 // We always go left, towards the smallest element, exploiting the fact |
355 // that the timestamp is big-endian and at the start of the value. | 343 // that the timestamp is big-endian and at the start of the value. |
356 wherep = &inode->data_[0]; | 344 wherep = &inode->data_[0]; |
357 p = (*wherep) >> 8; | 345 p = (*wherep) >> 8; |
358 } | 346 } |
359 | 347 |
360 const uint32 ext_index = p & ~kExternalFlag; | 348 const uint32 ext_index = p & ~kExternalFlag; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 | 421 |
434 CHECK_EQ(free_internal_nodes.count(internal_node), 0u); | 422 CHECK_EQ(free_internal_nodes.count(internal_node), 0u); |
435 | 423 |
436 for (unsigned child = 0; child < 2; child++) { | 424 for (unsigned child = 0; child < 2; child++) { |
437 if (i->child(child) & kExternalFlag) { | 425 if (i->child(child) & kExternalFlag) { |
438 uint32 ext = i->child(child) & ~kExternalFlag; | 426 uint32 ext = i->child(child) & ~kExternalFlag; |
439 CHECK_EQ(free_external_nodes.count(ext), 0u); | 427 CHECK_EQ(free_external_nodes.count(ext), 0u); |
440 CHECK_EQ(used_external_nodes->count(ext), 0u); | 428 CHECK_EQ(used_external_nodes->count(ext), 0u); |
441 used_external_nodes->insert(ext); | 429 used_external_nodes->insert(ext); |
442 const uint8* bytes = external_node(ext); | 430 const uint8* bytes = external_node(ext); |
443 for (vector<pair<unsigned, bool> >::const_iterator | 431 for (vector<pair<unsigned, bool> >::const_iterator i = bits.begin(); |
444 i = bits.begin(); i != bits.end(); i++) { | 432 i != bits.end(); i++) { |
445 unsigned byte = i->first / 8; | 433 unsigned byte = i->first / 8; |
446 DCHECK_LE(byte, 0xffu); | 434 DCHECK_LE(byte, 0xffu); |
447 unsigned bit = i->first % 8; | 435 unsigned bit = i->first % 8; |
448 static const uint8 kMasks[8] = | 436 static const uint8 kMasks[8] = |
449 {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; | 437 {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; |
450 CHECK_EQ((bytes[byte] & kMasks[bit]) != 0, i->second); | 438 CHECK_EQ((bytes[byte] & kMasks[bit]) != 0, i->second); |
451 } | 439 } |
452 } else { | 440 } else { |
453 uint32 inter = i->child(child); | 441 uint32 inter = i->child(child); |
454 vector<pair<unsigned, bool> > new_bits(bits); | 442 vector<pair<unsigned, bool> > new_bits(bits); |
455 new_bits.push_back(pair<unsigned, bool>(bit, child != 0)); | 443 new_bits.push_back(pair<unsigned, bool>(bit, child != 0)); |
456 CHECK_EQ(free_internal_nodes.count(inter), 0u); | 444 CHECK_EQ(free_internal_nodes.count(inter), 0u); |
457 CHECK_EQ(used_internal_nodes->count(inter), 0u); | 445 CHECK_EQ(used_internal_nodes->count(inter), 0u); |
458 used_internal_nodes->insert(inter); | 446 used_internal_nodes->insert(inter); |
459 ValidateTree(inter, bit, bits, free_internal_nodes, free_external_nodes, | 447 ValidateTree(inter, bit, bits, free_internal_nodes, free_external_nodes, |
460 used_internal_nodes, used_external_nodes); | 448 used_internal_nodes, used_external_nodes); |
461 } | 449 } |
462 } | 450 } |
463 } | 451 } |
464 | 452 |
465 } // namespace net | 453 } // namespace net |
OLD | NEW |