VisitedLinkTable.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * Copyright (C) 2010 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  14. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  17. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  23. * THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include "VisitedLinkTable.h"
  27. #include "SharedMemory.h"
  28. using namespace WebCore;
  29. namespace WebKit {
  30. VisitedLinkTable::VisitedLinkTable()
  31. : m_tableSize(0)
  32. , m_table(0)
  33. {
  34. }
  35. VisitedLinkTable::~VisitedLinkTable()
  36. {
  37. }
  38. #if !ASSERT_DISABLED
  39. static inline bool isPowerOf2(unsigned v)
  40. {
  41. // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html
  42. return !(v & (v - 1)) && v;
  43. }
  44. #endif
  45. void VisitedLinkTable::setSharedMemory(PassRefPtr<SharedMemory> sharedMemory)
  46. {
  47. m_sharedMemory = sharedMemory;
  48. ASSERT(m_sharedMemory);
  49. ASSERT(!(m_sharedMemory->size() % sizeof(LinkHash)));
  50. m_table = static_cast<LinkHash*>(m_sharedMemory->data());
  51. m_tableSize = m_sharedMemory->size() / sizeof(LinkHash);
  52. ASSERT(isPowerOf2(m_tableSize));
  53. m_tableSizeMask = m_tableSize - 1;
  54. }
  55. static inline unsigned doubleHash(unsigned key)
  56. {
  57. key = ~key + (key >> 23);
  58. key ^= (key << 12);
  59. key ^= (key >> 7);
  60. key ^= (key << 2);
  61. key ^= (key >> 20);
  62. return key;
  63. }
  64. bool VisitedLinkTable::addLinkHash(LinkHash linkHash)
  65. {
  66. ASSERT(m_sharedMemory);
  67. int k = 0;
  68. LinkHash* table = m_table;
  69. int sizeMask = m_tableSizeMask;
  70. unsigned h = static_cast<unsigned>(linkHash);
  71. int i = h & sizeMask;
  72. LinkHash* entry;
  73. while (1) {
  74. entry = table + i;
  75. // Check if this bucket is empty.
  76. if (!*entry)
  77. break;
  78. // Check if the same link hash is in the table already.
  79. if (*entry == linkHash)
  80. return false;
  81. if (!k)
  82. k = 1 | doubleHash(h);
  83. i = (i + k) & sizeMask;
  84. }
  85. *entry = linkHash;
  86. return true;
  87. }
  88. bool VisitedLinkTable::isLinkVisited(LinkHash linkHash) const
  89. {
  90. if (!m_sharedMemory)
  91. return false;
  92. int k = 0;
  93. LinkHash* table = m_table;
  94. int sizeMask = m_tableSizeMask;
  95. unsigned h = static_cast<unsigned>(linkHash);
  96. int i = h & sizeMask;
  97. LinkHash* entry;
  98. while (1) {
  99. entry = table + i;
  100. // Check if we've reached the end of the table.
  101. if (!*entry)
  102. break;
  103. if (*entry == linkHash)
  104. return true;
  105. if (!k)
  106. k = 1 | doubleHash(h);
  107. i = (i + k) & sizeMask;
  108. }
  109. return false;
  110. }
  111. } // namespace WebKit