/*
 * Copyright (C) 2010 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "VisitedLinkTable.h"

#include "SharedMemory.h"

using namespace WebCore;

namespace WebKit {

VisitedLinkTable::VisitedLinkTable()
    : m_tableSize(0)
    , m_tableSizeMask(0)
    , m_table(nullptr)
{
}

VisitedLinkTable::~VisitedLinkTable()
{
}

#if !ASSERT_DISABLED
static inline bool isPowerOf2(unsigned v)
{
    // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html
    
    return !(v & (v - 1)) && v;
}
#endif

void VisitedLinkTable::setSharedMemory(PassRefPtr<SharedMemory> sharedMemory)
{
    m_sharedMemory = sharedMemory;
    
    ASSERT(m_sharedMemory);
    ASSERT(!(m_sharedMemory->size() % sizeof(LinkHash)));

    m_table = static_cast<LinkHash*>(m_sharedMemory->data());
    m_tableSize = m_sharedMemory->size() / sizeof(LinkHash);
    ASSERT(isPowerOf2(m_tableSize));
    
    m_tableSizeMask = m_tableSize - 1;
}

static inline unsigned doubleHash(unsigned key)
{
    key = ~key + (key >> 23);
    key ^= (key << 12);
    key ^= (key >> 7);
    key ^= (key << 2);
    key ^= (key >> 20);
    return key;
}
    
bool VisitedLinkTable::addLinkHash(LinkHash linkHash)
{
    ASSERT(m_sharedMemory);

    int k = 0;
    LinkHash* table = m_table;
    int sizeMask = m_tableSizeMask;
    unsigned h = static_cast<unsigned>(linkHash);
    int i = h & sizeMask;
  
    LinkHash* entry;
    while (1) {
        entry = table + i;

        // Check if this bucket is empty.
        if (!*entry)
            break;

        // Check if the same link hash is in the table already.
        if (*entry == linkHash)
            return false;

        if (!k)
            k = 1 | doubleHash(h);
        i = (i + k) & sizeMask;
    }

    *entry = linkHash;
    return true;
}

bool VisitedLinkTable::isLinkVisited(LinkHash linkHash) const
{
    if (!m_sharedMemory)
        return false;

    int k = 0;
    LinkHash* table = m_table;
    int sizeMask = m_tableSizeMask;
    unsigned h = static_cast<unsigned>(linkHash);
    int i = h & sizeMask;
    
    LinkHash* entry;
    while (1) {
        entry = table + i;

        // Check if we've reached the end of the table.
        if (!*entry)
            break;
        
        if (*entry == linkHash)
            return true;
        
        if (!k)
            k = 1 | doubleHash(h);
        i = (i + k) & sizeMask;
    }

    return false;
}

void VisitedLinkTable::clear()
{
    m_tableSize = 0;
    m_tableSizeMask = 0;
    m_sharedMemory = nullptr;
}

} // namespace WebKit
