/*
 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
 *
 * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
 * 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 "IconDatabase.h"

#include "AutodrainedPool.h"
#include "CString.h"
#include "DocumentLoader.h"
#include "FileSystem.h"
#include "IconDatabaseClient.h"
#include "IconRecord.h"
#include "Image.h"
#include "IntSize.h"
#include "KURL.h"
#include "Logging.h"
#include "PageURLRecord.h"
#include "SQLiteStatement.h"
#include "SQLiteTransaction.h"
#include "SystemTime.h"

#if PLATFORM(WIN_OS)
#include <windows.h>
#include <winbase.h>
#include <shlobj.h>
#else
#include <sys/stat.h>
#endif

#if PLATFORM(DARWIN)
#include <pthread.h>
#endif

#include <errno.h>

// For methods that are meant to support API from the main thread - should not be called internally
#define ASSERT_NOT_SYNC_THREAD() ASSERT(!m_syncThreadRunning || !IS_ICON_SYNC_THREAD())

// For methods that are meant to support the sync thread ONLY
#define IS_ICON_SYNC_THREAD() (m_syncThread == currentThread())
#define ASSERT_ICON_SYNC_THREAD() ASSERT(IS_ICON_SYNC_THREAD())

namespace WebCore {

static IconDatabase* sharedIconDatabase = 0;
static int databaseCleanupCounter = 0;

// This version number is in the DB and marks the current generation of the schema
// Currently, a mismatched schema causes the DB to be wiped and reset.  This isn't 
// so bad during development but in the future, we would need to write a conversion
// function to advance older released schemas to "current"
const int currentDatabaseVersion = 6;

// Icons expire once every 4 days
const int iconExpirationTime = 60*60*24*4; 

const int updateTimerDelay = 5; 

static bool checkIntegrityOnOpen = false;

#ifndef NDEBUG
static String urlForLogging(const String& url)
{
    static unsigned urlTruncationLength = 120;

    if (url.length() < urlTruncationLength)
        return url;
    return url.substring(0, urlTruncationLength) + "...";
}
#endif

static IconDatabaseClient* defaultClient() 
{
    static IconDatabaseClient* defaultClient = new IconDatabaseClient();
    return defaultClient;
}

IconDatabase* iconDatabase()
{
    if (!sharedIconDatabase) {
        initializeThreading();
        sharedIconDatabase = new IconDatabase;
    }
    return sharedIconDatabase;
}

// ************************
// *** Main Thread Only ***
// ************************

void IconDatabase::setClient(IconDatabaseClient* client)
{
    // We don't allow a null client, because we never null check it anywhere in this code
    // Also don't allow a client change after the thread has already began 
    // (setting the client should occur before the database is opened)
    ASSERT(client);
    ASSERT(!m_syncThreadRunning);
    if (!client || m_syncThreadRunning)
        return;
        
    m_client = client;
}

bool IconDatabase::open(const String& databasePath)
{
    ASSERT_NOT_SYNC_THREAD();

    if (!m_isEnabled)
        return false;

    if (isOpen()) {
        LOG_ERROR("Attempt to reopen the IconDatabase which is already open.  Must close it first.");
        return false;
    }

    m_databaseDirectory = databasePath.copy();

    // Formulate the full path for the database file
    m_completeDatabasePath = pathByAppendingComponent(m_databaseDirectory, defaultDatabaseFilename());

    // Lock here as well as first thing in the thread so the thread doesn't actually commence until the createThread() call 
    // completes and m_syncThreadRunning is properly set
    m_syncLock.lock();
    m_syncThread = createThread(IconDatabase::iconDatabaseSyncThreadStart, this);
    m_syncLock.unlock();
    if (!m_syncThread)
        return false;
    return true;
}

void IconDatabase::close()
{
    ASSERT_NOT_SYNC_THREAD();
    
    if (m_syncThreadRunning) {
        // Set the flag to tell the sync thread to wrap it up
        m_threadTerminationRequested = true;

        // Wake up the sync thread if it's waiting
        wakeSyncThread();
        
        // Wait for the sync thread to terminate
        waitForThreadCompletion(m_syncThread, 0);
    }

    m_syncThreadRunning = false;    
    m_threadTerminationRequested = false;
    m_removeIconsRequested = false;
}

void IconDatabase::removeAllIcons()
{
    ASSERT_NOT_SYNC_THREAD();
    
    if (!isOpen())
        return;

    LOG(IconDatabase, "Requesting background thread to remove all icons");
    
    // Clear the in-memory record of every IconRecord, anything waiting to be read from disk, and anything waiting to be written to disk
    {
        MutexLocker locker(m_urlAndIconLock);
        
        // Clear the IconRecords for every page URL - RefCounting will cause the IconRecords themselves to be deleted
        // We don't delete the actual PageRecords because we have the "retain icon for url" count to keep track of
        HashMap<String, PageURLRecord*>::iterator iter = m_pageURLToRecordMap.begin();
        HashMap<String, PageURLRecord*>::iterator end = m_pageURLToRecordMap.end();
        for (; iter != end; ++iter)
            (*iter).second->setIconRecord(0);
            
        // Clear the iconURL -> IconRecord map
        m_iconURLToRecordMap.clear();
                    
        // Clear all in-memory records of things that need to be synced out to disk
        {
            MutexLocker locker(m_pendingSyncLock);
            m_pageURLsPendingSync.clear();
            m_iconsPendingSync.clear();
        }
        
        // Clear all in-memory records of things that need to be read in from disk
        {
            MutexLocker locker(m_pendingReadingLock);
            m_pageURLsPendingImport.clear();
            m_pageURLsInterestedInIcons.clear();
            m_iconsPendingReading.clear();
            m_loadersPendingDecision.clear();
        }
    }
    
    m_removeIconsRequested = true;
    wakeSyncThread();
}

Image* IconDatabase::iconForPageURL(const String& pageURLOriginal, const IntSize& size, bool cache)
{   
    ASSERT_NOT_SYNC_THREAD();
    
    ASSERT(!pageURLOriginal.isNull());

    // pageURLOriginal can not be stored without being deep copied first.  
    // We should go our of our way to only copy it if we have to store it
    
    if (!isOpen())
        return defaultIcon(size);

    MutexLocker locker(m_urlAndIconLock);
    
    String pageURLCopy; // Creates a null string for easy testing
    
    PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal);
    if (!pageRecord) {
        pageURLCopy = pageURLOriginal.copy();
        pageRecord = getOrCreatePageURLRecord(pageURLCopy);
    }
    
    // If pageRecord is NULL, one of two things is true -
    // 1 - The initial url import is incomplete and this pageURL was marked to be notified once it is complete if an iconURL exists
    // 2 - The initial url import IS complete and this pageURL has no icon
    if (!pageRecord) {
        MutexLocker locker(m_pendingReadingLock);
        
        // Import is ongoing, there might be an icon.  In this case, register to be notified when the icon comes in
        // If we ever reach this condition, we know we've already made the pageURL copy
        if (!m_iconURLImportComplete)
            m_pageURLsInterestedInIcons.add(pageURLCopy);
        
        return 0;
    }

    IconRecord* iconRecord = pageRecord->iconRecord();
    
    // If the initial URL import isn't complete, it's possible to have a PageURL record without an associated icon
    // In this case, the pageURL is already in the set to alert the client when the iconURL mapping is complete so
    // we can just bail now
    if (!m_iconURLImportComplete && !iconRecord)
        return 0;
    
    // The only way we should *not* have an icon record is if this pageURL is retained but has no icon yet - make sure of that
    ASSERT(iconRecord || m_retainedPageURLs.contains(pageURLOriginal));
    
    if (!iconRecord)
        return 0;
        
    // If it's a new IconRecord object that doesn't have its imageData set yet,
    // mark it to be read by the background thread
    if (iconRecord->imageDataStatus() == ImageDataStatusUnknown) {
        if (pageURLCopy.isNull())
            pageURLCopy = pageURLOriginal.copy();
    
        MutexLocker locker(m_pendingReadingLock);
        m_pageURLsInterestedInIcons.add(pageURLCopy);
        m_iconsPendingReading.add(iconRecord);
        wakeSyncThread();
        return 0;
    }
    
    // If the size parameter was (0, 0) that means the caller of this method just wanted the read from disk to be kicked off
    // and isn't actually interested in the image return value
    if (size == IntSize(0, 0))
        return 0;
        
    // PARANOID DISCUSSION: This method makes some assumptions.  It returns a WebCore::image which the icon database might dispose of at anytime in the future,
    // and Images aren't ref counted.  So there is no way for the client to guarantee continued existence of the image.
    // This has *always* been the case, but in practice clients would always create some other platform specific representation of the image
    // and drop the raw Image*.  On Mac an NSImage, and on windows drawing into an HBITMAP.
    // The async aspect adds a huge question - what if the image is deleted before the platform specific API has a chance to create its own
    // representation out of it?
    // If an image is read in from the icondatabase, we do *not* overwrite any image data that exists in the in-memory cache.  
    // This is because we make the assumption that anything in memory is newer than whatever is in the database.
    // So the only time the data will be set from the second thread is when it is INITIALLY being read in from the database, but we would never 
    // delete the image on the secondary thread if the image already exists.
    return iconRecord->image(size);
}

void IconDatabase::readIconForPageURLFromDisk(const String& pageURL)
{
    // The effect of asking for an Icon for a pageURL automatically queues it to be read from disk
    // if it hasn't already been set in memory.  The special IntSize (0, 0) is a special way of telling 
    // that method "I don't care about the actual Image, i just want you to make sure you're getting it from disk.
    iconForPageURL(pageURL, IntSize(0,0));
}

String IconDatabase::iconURLForPageURL(const String& pageURLOriginal)
{    
    ASSERT_NOT_SYNC_THREAD(); 
        
    // Cannot do anything with pageURLOriginal that would end up storing it without deep copying first
    // Also, in the case we have a real answer for the caller, we must deep copy that as well
    
    if (!isOpen() || pageURLOriginal.isEmpty())
        return String();
        
    MutexLocker locker(m_urlAndIconLock);
    
    PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal);
    if (!pageRecord)
        pageRecord = getOrCreatePageURLRecord(pageURLOriginal.copy());
    
    // If pageRecord is NULL, one of two things is true -
    // 1 - The initial url import is incomplete and this pageURL has already been marked to be notified once it is complete if an iconURL exists
    // 2 - The initial url import IS complete and this pageURL has no icon
    if (!pageRecord)
        return String();
    
    // Possible the pageRecord is around because it's a retained pageURL with no iconURL, so we have to check
    return pageRecord->iconRecord() ? pageRecord->iconRecord()->iconURL().copy() : String();
}

Image* IconDatabase::defaultIcon(const IntSize& size)
{
    ASSERT_NOT_SYNC_THREAD();

    static const unsigned char defaultIconData[] = { 0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x03, 0x32, 0x80, 0x00, 0x20, 0x50, 0x38, 0x24, 0x16, 0x0D, 0x07, 0x84, 0x42, 0x61, 0x50, 0xB8, 
        0x64, 0x08, 0x18, 0x0D, 0x0A, 0x0B, 0x84, 0xA2, 0xA1, 0xE2, 0x08, 0x5E, 0x39, 0x28, 0xAF, 0x48, 0x24, 0xD3, 0x53, 0x9A, 0x37, 0x1D, 0x18, 0x0E, 0x8A, 0x4B, 0xD1, 0x38, 
        0xB0, 0x7C, 0x82, 0x07, 0x03, 0x82, 0xA2, 0xE8, 0x6C, 0x2C, 0x03, 0x2F, 0x02, 0x82, 0x41, 0xA1, 0xE2, 0xF8, 0xC8, 0x84, 0x68, 0x6D, 0x1C, 0x11, 0x0A, 0xB7, 0xFA, 0x91, 
        0x6E, 0xD1, 0x7F, 0xAF, 0x9A, 0x4E, 0x87, 0xFB, 0x19, 0xB0, 0xEA, 0x7F, 0xA4, 0x95, 0x8C, 0xB7, 0xF9, 0xA9, 0x0A, 0xA9, 0x7F, 0x8C, 0x88, 0x66, 0x96, 0xD4, 0xCA, 0x69, 
        0x2F, 0x00, 0x81, 0x65, 0xB0, 0x29, 0x90, 0x7C, 0xBA, 0x2B, 0x21, 0x1E, 0x5C, 0xE6, 0xB4, 0xBD, 0x31, 0xB6, 0xE7, 0x7A, 0xBF, 0xDD, 0x6F, 0x37, 0xD3, 0xFD, 0xD8, 0xF2, 
        0xB6, 0xDB, 0xED, 0xAC, 0xF7, 0x03, 0xC5, 0xFE, 0x77, 0x53, 0xB6, 0x1F, 0xE6, 0x24, 0x8B, 0x1D, 0xFE, 0x26, 0x20, 0x9E, 0x1C, 0xE0, 0x80, 0x65, 0x7A, 0x18, 0x02, 0x01, 
        0x82, 0xC5, 0xA0, 0xC0, 0xF1, 0x89, 0xBA, 0x23, 0x30, 0xAD, 0x1F, 0xE7, 0xE5, 0x5B, 0x6D, 0xFE, 0xE7, 0x78, 0x3E, 0x1F, 0xEE, 0x97, 0x8B, 0xE7, 0x37, 0x9D, 0xCF, 0xE7, 
        0x92, 0x8B, 0x87, 0x0B, 0xFC, 0xA0, 0x8E, 0x68, 0x3F, 0xC6, 0x27, 0xA6, 0x33, 0xFC, 0x36, 0x5B, 0x59, 0x3F, 0xC1, 0x02, 0x63, 0x3B, 0x74, 0x00, 0x03, 0x07, 0x0B, 0x61, 
        0x00, 0x20, 0x60, 0xC9, 0x08, 0x00, 0x1C, 0x25, 0x9F, 0xE0, 0x12, 0x8A, 0xD5, 0xFE, 0x6B, 0x4F, 0x35, 0x9F, 0xED, 0xD7, 0x4B, 0xD9, 0xFE, 0x8A, 0x59, 0xB8, 0x1F, 0xEC, 
        0x56, 0xD3, 0xC1, 0xFE, 0x63, 0x4D, 0xF2, 0x83, 0xC6, 0xB6, 0x1B, 0xFC, 0x34, 0x68, 0x61, 0x3F, 0xC1, 0xA6, 0x25, 0xEB, 0xFC, 0x06, 0x58, 0x5C, 0x3F, 0xC0, 0x03, 0xE4, 
        0xC3, 0xFC, 0x04, 0x0F, 0x1A, 0x6F, 0xE0, 0xE0, 0x20, 0xF9, 0x61, 0x7A, 0x02, 0x28, 0x2B, 0xBC, 0x46, 0x25, 0xF3, 0xFC, 0x66, 0x3D, 0x99, 0x27, 0xF9, 0x7E, 0x6B, 0x1D, 
        0xC7, 0xF9, 0x2C, 0x5E, 0x1C, 0x87, 0xF8, 0xC0, 0x4D, 0x9A, 0xE7, 0xF8, 0xDA, 0x51, 0xB2, 0xC1, 0x68, 0xF2, 0x64, 0x1F, 0xE1, 0x50, 0xED, 0x0A, 0x04, 0x23, 0x79, 0x8A, 
        0x7F, 0x82, 0xA3, 0x39, 0x80, 0x7F, 0x80, 0xC2, 0xB1, 0x5E, 0xF7, 0x04, 0x2F, 0xB2, 0x10, 0x02, 0x86, 0x63, 0xC9, 0xCC, 0x07, 0xBF, 0x87, 0xF8, 0x4A, 0x38, 0xAF, 0xC1, 
        0x88, 0xF8, 0x66, 0x1F, 0xE1, 0xD9, 0x08, 0xD4, 0x8F, 0x25, 0x5B, 0x4A, 0x49, 0x97, 0x87, 0x39, 0xFE, 0x25, 0x12, 0x10, 0x68, 0xAA, 0x4A, 0x2F, 0x42, 0x29, 0x12, 0x69, 
        0x9F, 0xE1, 0xC1, 0x00, 0x67, 0x1F, 0xE1, 0x58, 0xED, 0x00, 0x83, 0x23, 0x49, 0x82, 0x7F, 0x81, 0x21, 0xE0, 0xFC, 0x73, 0x21, 0x00, 0x50, 0x7D, 0x2B, 0x84, 0x03, 0x83, 
        0xC2, 0x1B, 0x90, 0x06, 0x69, 0xFE, 0x23, 0x91, 0xAE, 0x50, 0x9A, 0x49, 0x32, 0xC2, 0x89, 0x30, 0xE9, 0x0A, 0xC4, 0xD9, 0xC4, 0x7F, 0x94, 0xA6, 0x51, 0xDE, 0x7F, 0x9D, 
        0x07, 0x89, 0xF6, 0x7F, 0x91, 0x85, 0xCA, 0x88, 0x25, 0x11, 0xEE, 0x50, 0x7C, 0x43, 0x35, 0x21, 0x60, 0xF1, 0x0D, 0x82, 0x62, 0x39, 0x07, 0x2C, 0x20, 0xE0, 0x80, 0x72, 
        0x34, 0x17, 0xA1, 0x80, 0xEE, 0xF0, 0x89, 0x24, 0x74, 0x1A, 0x2C, 0x93, 0xB3, 0x78, 0xCC, 0x52, 0x9D, 0x6A, 0x69, 0x56, 0xBB, 0x0D, 0x85, 0x69, 0xE6, 0x7F, 0x9E, 0x27, 
        0xB9, 0xFD, 0x50, 0x54, 0x47, 0xF9, 0xCC, 0x78, 0x9F, 0x87, 0xF9, 0x98, 0x70, 0xB9, 0xC2, 0x91, 0x2C, 0x6D, 0x1F, 0xE1, 0xE1, 0x00, 0xBF, 0x02, 0xC1, 0xF5, 0x18, 0x84,
        0x01, 0xE1, 0x48, 0x8C, 0x42, 0x07, 0x43, 0xC9, 0x76, 0x7F, 0x8B, 0x04, 0xE4, 0xDE, 0x35, 0x95, 0xAB, 0xB0, 0xF0, 0x5C, 0x55, 0x23, 0xF9, 0x7E, 0x7E, 0x9F, 0xE4, 0x0C, 
        0xA7, 0x55, 0x47, 0xC7, 0xF9, 0xE6, 0xCF, 0x1F, 0xE7, 0x93, 0x35, 0x52, 0x54, 0x63, 0x19, 0x46, 0x73, 0x1F, 0xE2, 0x61, 0x08, 0xF0, 0x82, 0xE1, 0x80, 0x92, 0xF9, 0x20, 
        0xC0, 0x28, 0x18, 0x0A, 0x05, 0xA1, 0xA2, 0xF8, 0x6E, 0xDB, 0x47, 0x49, 0xFE, 0x3E, 0x17, 0xB6, 0x61, 0x13, 0x1A, 0x29, 0x26, 0xA9, 0xFE, 0x7F, 0x92, 0x70, 0x69, 0xFE, 
        0x4C, 0x2F, 0x55, 0x01, 0xF1, 0x54, 0xD4, 0x35, 0x49, 0x4A, 0x69, 0x59, 0x83, 0x81, 0x58, 0x76, 0x9F, 0xE2, 0x20, 0xD6, 0x4C, 0x9B, 0xA0, 0x48, 0x1E, 0x0B, 0xB7, 0x48, 
        0x58, 0x26, 0x11, 0x06, 0x42, 0xE8, 0xA4, 0x40, 0x17, 0x27, 0x39, 0x00, 0x60, 0x2D, 0xA4, 0xC3, 0x2C, 0x7F, 0x94, 0x56, 0xE4, 0xE1, 0x77, 0x1F, 0xE5, 0xB9, 0xD7, 0x66, 
        0x1E, 0x07, 0xB3, 0x3C, 0x63, 0x1D, 0x35, 0x49, 0x0E, 0x63, 0x2D, 0xA2, 0xF1, 0x12, 0x60, 0x1C, 0xE0, 0xE0, 0x52, 0x1B, 0x8B, 0xAC, 0x38, 0x0E, 0x07, 0x03, 0x60, 0x28, 
        0x1C, 0x0E, 0x87, 0x00, 0xF0, 0x66, 0x27, 0x11, 0xA2, 0xC1, 0x02, 0x5A, 0x1C, 0xE4, 0x21, 0x83, 0x1F, 0x13, 0x86, 0xFA, 0xD2, 0x55, 0x1D, 0xD6, 0x61, 0xBC, 0x77, 0xD3, 
        0xE6, 0x91, 0xCB, 0x4C, 0x90, 0xA6, 0x25, 0xB8, 0x2F, 0x90, 0xC5, 0xA9, 0xCE, 0x12, 0x07, 0x02, 0x91, 0x1B, 0x9F, 0x68, 0x00, 0x16, 0x76, 0x0D, 0xA1, 0x00, 0x08, 0x06, 
        0x03, 0x81, 0xA0, 0x20, 0x1A, 0x0D, 0x06, 0x80, 0x30, 0x24, 0x12, 0x89, 0x20, 0x98, 0x4A, 0x1F, 0x0F, 0x21, 0xA0, 0x9E, 0x36, 0x16, 0xC2, 0x88, 0xE6, 0x48, 0x9B, 0x83, 
        0x31, 0x1C, 0x55, 0x1E, 0x43, 0x59, 0x1A, 0x56, 0x1E, 0x42, 0xF0, 0xFA, 0x4D, 0x1B, 0x9B, 0x08, 0xDC, 0x5B, 0x02, 0xA1, 0x30, 0x7E, 0x3C, 0xEE, 0x5B, 0xA6, 0xDD, 0xB8, 
        0x6D, 0x5B, 0x62, 0xB7, 0xCD, 0xF3, 0x9C, 0xEA, 0x04, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x01, 
        0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0xE0, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 
        0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x11, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 
        0x00, 0x08, 0x01, 0x15, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x01, 0x16, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x17, 
        0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x29, 0x01, 0x1A, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xE8, 0x01, 0x1B, 0x00, 0x05, 0x00, 0x00, 
        0x00, 0x01, 0x00, 0x00, 0x03, 0xF0, 0x01, 0x1C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x28, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 
        0x00, 0x00, 0x01, 0x52, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0A, 
        0xFC, 0x80, 0x00, 0x00, 0x27, 0x10, 0x00, 0x0A, 0xFC, 0x80, 0x00, 0x00, 0x27, 0x10 };
        
    static RefPtr<SharedBuffer> defaultIconBuffer(new SharedBuffer(defaultIconData, sizeof(defaultIconData)));
    
    if (!m_defaultIconRecord) {
        m_defaultIconRecord = new IconRecord("urlIcon");
        m_defaultIconRecord->setImageData(defaultIconBuffer);
    }
    
    return m_defaultIconRecord->image(size);
}


void IconDatabase::retainIconForPageURL(const String& pageURLOriginal)
{    
    ASSERT_NOT_SYNC_THREAD();
    
    // Cannot do anything with pageURLOriginal that would end up storing it without deep copying first
    
    if (!isEnabled() || pageURLOriginal.isEmpty())
        return;
       
    MutexLocker locker(m_urlAndIconLock);

    PageURLRecord* record = m_pageURLToRecordMap.get(pageURLOriginal);
    
    String pageURL;
    
    if (!record) {
        pageURL = pageURLOriginal.copy();

        record = new PageURLRecord(pageURL);
        m_pageURLToRecordMap.set(pageURL, record);
    }
    
    if (!record->retain()) {
        if (pageURL.isNull())
            pageURL = pageURLOriginal.copy();

        // This page just had its retain count bumped from 0 to 1 - Record that fact
        m_retainedPageURLs.add(pageURL);

        // If we read the iconURLs yet, we want to avoid any pageURL->iconURL lookups and the pageURLsPendingDeletion is moot, 
        // so we bail here and skip those steps
        if (!m_iconURLImportComplete)
            return;

        MutexLocker locker(m_pendingSyncLock);
        // If this pageURL waiting to be sync'ed, update the sync record
        // This saves us in the case where a page was ready to be deleted from the database but was just retained - so theres no need to delete it!
        if (!m_privateBrowsingEnabled && m_pageURLsPendingSync.contains(pageURL)) {
            LOG(IconDatabase, "Bringing %s back from the brink", pageURL.ascii().data());
            m_pageURLsPendingSync.set(pageURL, record->snapshot());
        }
    }
}

void IconDatabase::releaseIconForPageURL(const String& pageURLOriginal)
{
    ASSERT_NOT_SYNC_THREAD();
        
    // Cannot do anything with pageURLOriginal that would end up storing it without deep copying first
    
    if (!isEnabled() || pageURLOriginal.isEmpty())
        return;
    
    MutexLocker locker(m_urlAndIconLock);

    // Check if this pageURL is actually retained
    if (!m_retainedPageURLs.contains(pageURLOriginal)) {
        LOG_ERROR("Attempting to release icon for URL %s which is not retained", urlForLogging(pageURLOriginal).ascii().data());
        return;
    }
    
    // Get its retain count - if it's retained, we'd better have a PageURLRecord for it
    PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal);
    ASSERT(pageRecord);
    LOG(IconDatabase, "Releasing pageURL %s to a retain count of %i", urlForLogging(pageURLOriginal).ascii().data(), pageRecord->retainCount() - 1);
    ASSERT(pageRecord->retainCount() > 0);
        
    // If it still has a positive retain count, store the new count and bail
    if (pageRecord->release())
        return;
        
    // This pageRecord has now been fully released.  Do the appropriate cleanup
    LOG(IconDatabase, "No more retainers for PageURL %s", urlForLogging(pageURLOriginal).ascii().data());
    m_pageURLToRecordMap.remove(pageURLOriginal);
    m_retainedPageURLs.remove(pageURLOriginal);       
    
    // Grab the iconRecord for later use (and do a sanity check on it for kicks)
    IconRecord* iconRecord = pageRecord->iconRecord();
    
    ASSERT(!iconRecord || (iconRecord && m_iconURLToRecordMap.get(iconRecord->iconURL()) == iconRecord));

    {
        MutexLocker locker(m_pendingReadingLock);
        
        // Since this pageURL is going away, there's no reason anyone would ever be interested in its read results    
        if (!m_iconURLImportComplete)
            m_pageURLsPendingImport.remove(pageURLOriginal);
        m_pageURLsInterestedInIcons.remove(pageURLOriginal);
        
        // If this icon is down to it's last retainer, we don't care about reading it in from disk anymore
        if (iconRecord && iconRecord->hasOneRef()) {
            m_iconURLToRecordMap.remove(iconRecord->iconURL());
            m_iconsPendingReading.remove(iconRecord);
        }
    }
    
    // Mark stuff for deletion from the database only if we're not in private browsing
    if (!m_privateBrowsingEnabled) {
        MutexLocker locker(m_pendingSyncLock);
        m_pageURLsPendingSync.set(pageURLOriginal.copy(), pageRecord->snapshot(true));
    
        // If this page is the last page to refer to a particular IconRecord, that IconRecord needs to
        // be marked for deletion
        if (iconRecord && iconRecord->hasOneRef())
            m_iconsPendingSync.set(iconRecord->iconURL(), iconRecord->snapshot(true));
    }
    
    delete pageRecord;

    if (isOpen())
        scheduleOrDeferSyncTimer();
}

void IconDatabase::setIconDataForIconURL(PassRefPtr<SharedBuffer> dataOriginal, const String& iconURLOriginal)
{    
    ASSERT_NOT_SYNC_THREAD();
    
    // Cannot do anything with dataOriginal or iconURLOriginal that would end up storing them without deep copying first
    
    if (!isOpen() || iconURLOriginal.isEmpty())
        return;
    
    RefPtr<SharedBuffer> data = dataOriginal ? dataOriginal->copy() : 0;
    String iconURL = iconURLOriginal.copy();
    
    Vector<String> pageURLs;
    {
        MutexLocker locker(m_urlAndIconLock);
    
        // If this icon was pending a read, remove it from that set because this new data should override what is on disk
        IconRecord* icon = m_iconURLToRecordMap.get(iconURL);
        if (icon) {
            MutexLocker locker(m_pendingReadingLock);
            m_iconsPendingReading.remove(icon);
        } else
            icon = getOrCreateIconRecord(iconURL);
    
        // Update the data and set the time stamp
        icon->setImageData(data);
        icon->setTimestamp((int)currentTime());
        
        // Copy the current retaining pageURLs - if any - to notify them of the change
        pageURLs.appendRange(icon->retainingPageURLs().begin(), icon->retainingPageURLs().end());
        
        // Mark the IconRecord as requiring an update to the database only if private browsing is disabled
        if (!m_privateBrowsingEnabled) {
            MutexLocker locker(m_pendingSyncLock);
            m_iconsPendingSync.set(iconURL, icon->snapshot());
        }
    }

    // Send notification out regarding all PageURLs that retain this icon
    // But not if we're on the sync thread because that implies this mapping
    // comes from the initial import which we don't want notifications for
    if (!IS_ICON_SYNC_THREAD()) {
        // Start the timer to commit this change - or further delay the timer if it was already started
        scheduleOrDeferSyncTimer();

        // Informal testing shows that draining the autorelease pool every 25 iterations is about as low as we can go
        // before performance starts to drop off, but we don't want to increase this number because then accumulated memory usage will go up        
        AutodrainedPool pool(25);

        for (unsigned i = 0; i < pageURLs.size(); ++i) {
            LOG(IconDatabase, "Dispatching notification that retaining pageURL %s has a new icon", urlForLogging(pageURLs[i]).ascii().data());
            m_client->dispatchDidAddIconForPageURL(pageURLs[i]);

            pool.cycle();
        }
    }
}

void IconDatabase::setIconURLForPageURL(const String& iconURLOriginal, const String& pageURLOriginal)
{    
    ASSERT_NOT_SYNC_THREAD();

    // Cannot do anything with iconURLOriginal or pageURLOriginal that would end up storing them without deep copying first
    
    ASSERT(!iconURLOriginal.isEmpty());
        
    if (!isOpen() || pageURLOriginal.isEmpty())
        return;
    
    String iconURL, pageURL;
    
    {
        MutexLocker locker(m_urlAndIconLock);

        PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal);
        
        // If the urls already map to each other, bail.
        // This happens surprisingly often, and seems to cream iBench performance
        if (pageRecord && pageRecord->iconRecord() && pageRecord->iconRecord()->iconURL() == iconURLOriginal)
            return;
            
        pageURL = pageURLOriginal.copy();
        iconURL = iconURLOriginal.copy();

        if (!pageRecord) {
            pageRecord = new PageURLRecord(pageURL);
            m_pageURLToRecordMap.set(pageURL, pageRecord);
        }

        RefPtr<IconRecord> iconRecord = pageRecord->iconRecord();

        // Otherwise, set the new icon record for this page
        IconRecord* newIconRecord = getOrCreateIconRecord(iconURL);
        pageRecord->setIconRecord(newIconRecord);

        // If the current icon has only a single ref left, it is about to get wiped out. 
        // Remove it from the in-memory records and don't bother reading it in from disk anymore
        if (iconRecord && iconRecord->hasOneRef()) {
            ASSERT(iconRecord->retainingPageURLs().size() == 0);
            LOG(IconDatabase, "Icon for icon url %s is about to be destroyed - removing mapping for it", urlForLogging(iconRecord->iconURL()).ascii().data());
            m_iconURLToRecordMap.remove(iconRecord->iconURL());
            MutexLocker locker(m_pendingReadingLock);
            m_iconsPendingReading.remove(iconRecord.get());
        }
        
        // And mark this mapping to be added to the database
        if (!m_privateBrowsingEnabled) {
            MutexLocker locker(m_pendingSyncLock);
            m_pageURLsPendingSync.set(pageURL, pageRecord->snapshot());
            
            // If the icon is on it's last ref, mark it for deletion
            if (iconRecord && iconRecord->hasOneRef())
                m_iconsPendingSync.set(iconRecord->iconURL(), iconRecord->snapshot(true));
        }
    }

    // Since this mapping is new, send the notification out - but not if we're on the sync thread because that implies this mapping
    // comes from the initial import which we don't want notifications for
    if (!IS_ICON_SYNC_THREAD()) {
        // Start the timer to commit this change - or further delay the timer if it was already started
        scheduleOrDeferSyncTimer();
        
        LOG(IconDatabase, "Dispatching notification that we changed an icon mapping for url %s", urlForLogging(pageURL).ascii().data());
        AutodrainedPool pool;
        m_client->dispatchDidAddIconForPageURL(pageURL);
    }
}

IconLoadDecision IconDatabase::loadDecisionForIconURL(const String& iconURL, DocumentLoader* notificationDocumentLoader)
{
    ASSERT_NOT_SYNC_THREAD();

    if (!isOpen() || iconURL.isEmpty())
        return IconLoadNo;
    
    // If we have a IconRecord, it should also have its timeStamp marked because there is only two times when we create the IconRecord:
    // 1 - When we read the icon urls from disk, getting the timeStamp at the same time
    // 2 - When we get a new icon from the loader, in which case the timestamp is set at that time
    {
        MutexLocker locker(m_urlAndIconLock);
        if (IconRecord* icon = m_iconURLToRecordMap.get(iconURL)) {
            LOG(IconDatabase, "Found expiration time on a present icon based on existing IconRecord");
            return (int)currentTime() - icon->getTimestamp() > iconExpirationTime ? IconLoadYes : IconLoadNo;
        }
    }
    
    // If we don't have a record for it, but we *have* imported all iconURLs from disk, then we should load it now
    MutexLocker readingLocker(m_pendingReadingLock);
    if (m_iconURLImportComplete)
        return IconLoadYes;
        
    // Otherwise - since we refuse to perform I/O on the main thread to find out for sure - we return the answer that says
    // "You might be asked to load this later, so flag that"
    LOG(IconDatabase, "Don't know if we should load %s or not - adding %p to the set of document loaders waiting on a decision", iconURL.ascii().data(), notificationDocumentLoader);
    m_loadersPendingDecision.add(notificationDocumentLoader);    

    return IconLoadUnknown;
}

bool IconDatabase::iconDataKnownForIconURL(const String& iconURL)
{
    ASSERT_NOT_SYNC_THREAD();
    
    MutexLocker locker(m_urlAndIconLock);
    if (IconRecord* icon = m_iconURLToRecordMap.get(iconURL))
        return icon->imageDataStatus() != ImageDataStatusUnknown;

    return false;
}

void IconDatabase::setEnabled(bool enabled)
{
    ASSERT_NOT_SYNC_THREAD();
    
    if (!enabled && isOpen())
        close();
    m_isEnabled = enabled;
}

bool IconDatabase::isEnabled() const
{
    ASSERT_NOT_SYNC_THREAD();
    
     return m_isEnabled;
}

void IconDatabase::setPrivateBrowsingEnabled(bool flag)
{
    m_privateBrowsingEnabled = flag;
}

bool IconDatabase::isPrivateBrowsingEnabled() const
{
    return m_privateBrowsingEnabled;
}

void IconDatabase::delayDatabaseCleanup()
{
    ++databaseCleanupCounter;
    if (databaseCleanupCounter == 1)
        LOG(IconDatabase, "Database cleanup is now DISABLED");
}

void IconDatabase::allowDatabaseCleanup()
{
    if (--databaseCleanupCounter < 0)
        databaseCleanupCounter = 0;
    if (databaseCleanupCounter == 0)
        LOG(IconDatabase, "Database cleanup is now ENABLED");
}

void IconDatabase::checkIntegrityBeforeOpening()
{
    checkIntegrityOnOpen = true;
}

size_t IconDatabase::pageURLMappingCount()
{
    MutexLocker locker(m_urlAndIconLock);
    return m_pageURLToRecordMap.size();
}

size_t IconDatabase::retainedPageURLCount()
{
    MutexLocker locker(m_urlAndIconLock);
    return m_retainedPageURLs.size();
}

size_t IconDatabase::iconRecordCount()
{
    MutexLocker locker(m_urlAndIconLock);
    return m_iconURLToRecordMap.size();
}

size_t IconDatabase::iconRecordCountWithData()
{
    MutexLocker locker(m_urlAndIconLock);
    size_t result = 0;
    
    HashMap<String, IconRecord*>::iterator i = m_iconURLToRecordMap.begin();
    HashMap<String, IconRecord*>::iterator end = m_iconURLToRecordMap.end();
    
    for (; i != end; ++i)
        result += ((*i).second->imageDataStatus() == ImageDataStatusPresent);
            
    return result;
}

IconDatabase::IconDatabase()
    : m_syncThreadRunning(false)
    , m_defaultIconRecord(0)
    , m_isEnabled(false)
    , m_privateBrowsingEnabled(false)
    , m_threadTerminationRequested(false)
    , m_removeIconsRequested(false)
    , m_iconURLImportComplete(false)
    , m_initialPruningComplete(false)
    , m_client(defaultClient())
    , m_imported(false)
    , m_isImportedSet(false)
{
#if PLATFORM(DARWIN)
    ASSERT(pthread_main_np());
#endif
}

IconDatabase::~IconDatabase()
{
    ASSERT_NOT_REACHED();
}

void IconDatabase::notifyPendingLoadDecisionsOnMainThread(void* context)
{
    static_cast<IconDatabase*>(context)->notifyPendingLoadDecisions();
}

void IconDatabase::notifyPendingLoadDecisions()
{
    ASSERT_NOT_SYNC_THREAD();
    
    // This method should only be called upon completion of the initial url import from the database
    ASSERT(m_iconURLImportComplete);
    LOG(IconDatabase, "Notifying all DocumentLoaders that were waiting on a load decision for thier icons");
    
    HashSet<RefPtr<DocumentLoader> >::iterator i = m_loadersPendingDecision.begin();
    HashSet<RefPtr<DocumentLoader> >::iterator end = m_loadersPendingDecision.end();
    
    for (; i != end; ++i)
        if ((*i)->refCount() > 1)
            (*i)->iconLoadDecisionAvailable();
            
    m_loadersPendingDecision.clear();
}

void IconDatabase::wakeSyncThread()
{
    MutexLocker locker(m_syncLock);
    m_syncCondition.signal();
}

void IconDatabase::scheduleOrDeferSyncTimer()
{
    ASSERT_NOT_SYNC_THREAD();
    if (!m_syncTimer)
        m_syncTimer.set(new Timer<IconDatabase>(this, &IconDatabase::syncTimerFired));

    m_syncTimer->startOneShot(updateTimerDelay);
}

void IconDatabase::syncTimerFired(Timer<IconDatabase>*)
{
    ASSERT_NOT_SYNC_THREAD();
    wakeSyncThread();
}

// ******************
// *** Any Thread ***
// ******************

bool IconDatabase::isOpen() const
{
    MutexLocker locker(m_syncLock);
    return m_syncDB.isOpen();
}

String IconDatabase::databasePath() const
{
    MutexLocker locker(m_syncLock);
    return m_completeDatabasePath.copy();
}

String IconDatabase::defaultDatabaseFilename()
{
    static String defaultDatabaseFilename = "WebpageIcons.db";
    return defaultDatabaseFilename.copy();
}

// Unlike getOrCreatePageURLRecord(), getOrCreateIconRecord() does not mark the icon as "interested in import"
IconRecord* IconDatabase::getOrCreateIconRecord(const String& iconURL)
{
    // Clients of getOrCreateIconRecord() are required to acquire the m_urlAndIconLock before calling this method
    ASSERT(!m_urlAndIconLock.tryLock());

    if (IconRecord* icon = m_iconURLToRecordMap.get(iconURL))
        return icon;
        
    IconRecord* newIcon = new IconRecord(iconURL);
    m_iconURLToRecordMap.set(iconURL, newIcon);
        
    return newIcon;    
}

// This method retrieves the existing PageURLRecord, or creates a new one and marks it as "interested in the import" for later notification
PageURLRecord* IconDatabase::getOrCreatePageURLRecord(const String& pageURL)
{
    // Clients of getOrCreatePageURLRecord() are required to acquire the m_urlAndIconLock before calling this method
    ASSERT(!m_urlAndIconLock.tryLock());

    if (pageURL.isEmpty())
        return 0;

    PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURL);
    
    MutexLocker locker(m_pendingReadingLock);
    if (!m_iconURLImportComplete) {
        // If the initial import of all URLs hasn't completed and we have no page record, we assume we *might* know about this later and create a record for it
        if (!pageRecord) {
            LOG(IconDatabase, "Creating new PageURLRecord for pageURL %s", urlForLogging(pageURL).ascii().data());
            pageRecord = new PageURLRecord(pageURL);
            m_pageURLToRecordMap.set(pageURL, pageRecord);
        }

        // If the pageRecord for this page does not have an iconRecord attached to it, then it is a new pageRecord still awaiting the initial import
        // Mark the URL as "interested in the result of the import" then bail
        if (!pageRecord->iconRecord()) {
            m_pageURLsPendingImport.add(pageURL);
            return 0;
        }
    }

    // We've done the initial import of all URLs known in the database.  If this record doesn't exist now, it never will    
     return pageRecord;
}


// ************************
// *** Sync Thread Only ***
// ************************

void IconDatabase::importIconURLForPageURL(const String& iconURL, const String& pageURL)
{
    ASSERT_ICON_SYNC_THREAD();
    
    // This function is only for setting actual existing url mappings so assert that neither of these URLs are empty
    ASSERT(!iconURL.isEmpty() && !pageURL.isEmpty());
    
    setIconURLForPageURLInSQLDatabase(iconURL, pageURL);    
}

void IconDatabase::importIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL)
{
    ASSERT_ICON_SYNC_THREAD();
    
    ASSERT(!iconURL.isEmpty());

    writeIconSnapshotToSQLDatabase(IconSnapshot(iconURL, (int)currentTime(), data.get()));
}

bool IconDatabase::shouldStopThreadActivity() const
{
    ASSERT_ICON_SYNC_THREAD();
    
    return m_threadTerminationRequested || m_removeIconsRequested;
}

void* IconDatabase::iconDatabaseSyncThreadStart(void* vIconDatabase)
{    
    IconDatabase* iconDB = static_cast<IconDatabase*>(vIconDatabase);
    
    return iconDB->iconDatabaseSyncThread();
}

void* IconDatabase::iconDatabaseSyncThread()
{
    // The call to create this thread might not complete before the thread actually starts, so we might fail this ASSERT_ICON_SYNC_THREAD() because the pointer 
    // to our thread structure hasn't been filled in yet.
    // To fix this, the main thread acquires this lock before creating us, then releases the lock after creation is complete.  A quick lock/unlock cycle here will 
    // prevent us from running before that call completes
    m_syncLock.lock();
    m_syncLock.unlock();

    ASSERT_ICON_SYNC_THREAD();
    
    LOG(IconDatabase, "(THREAD) IconDatabase sync thread started");

#ifndef NDEBUG
    double startTime = currentTime();
#endif

    // Need to create the database path if it doesn't already exist
    makeAllDirectories(m_databaseDirectory);

    // Existence of a journal file is evidence of a previous crash/force quit and automatically qualifies
    // us to do an integrity check
    String journalFilename = m_completeDatabasePath + "-journal";
    if (!checkIntegrityOnOpen) {
        AutodrainedPool pool;
        checkIntegrityOnOpen = fileExists(journalFilename);
    }
    
    {
        MutexLocker locker(m_syncLock);
        if (!m_syncDB.open(m_completeDatabasePath)) {
            LOG_ERROR("Unable to open icon database at path %s - %s", m_completeDatabasePath.ascii().data(), m_syncDB.lastErrorMsg());
            return 0;
        }
    }
    
    if (shouldStopThreadActivity())
        return syncThreadMainLoop();
        
#ifndef NDEBUG
    double timeStamp = currentTime();
    LOG(IconDatabase, "(THREAD) Open took %.4f seconds", timeStamp - startTime);
#endif    

    performOpenInitialization();
    if (shouldStopThreadActivity())
        return syncThreadMainLoop();
        
#ifndef NDEBUG
    double newStamp = currentTime();
    LOG(IconDatabase, "(THREAD) performOpenInitialization() took %.4f seconds, now %.4f seconds from thread start", newStamp - timeStamp, newStamp - startTime);
    timeStamp = newStamp;
#endif 

    if (!imported()) {
        LOG(IconDatabase, "(THREAD) Performing Safari2 import procedure");
        SQLiteTransaction importTransaction(m_syncDB);
        importTransaction.begin();
        
        // Commit the transaction only if the import completes (the import should be atomic)
        if (m_client->performImport()) {
            setImported(true);
            importTransaction.commit();
        } else {
            LOG(IconDatabase, "(THREAD) Safari 2 import was cancelled");
            importTransaction.rollback();
        }
        
        if (shouldStopThreadActivity())
            return syncThreadMainLoop();
            
#ifndef NDEBUG
        newStamp = currentTime();
        LOG(IconDatabase, "(THREAD) performImport() took %.4f seconds, now %.4f seconds from thread start", newStamp - timeStamp, newStamp - startTime);
        timeStamp = newStamp;
#endif 
    }
        
    // Uncomment the following line to simulate a long lasting URL import (*HUGE* icon databases, or network home directories)
    // while (currentTime() - timeStamp < 10);

    // Read in URL mappings from the database          
    LOG(IconDatabase, "(THREAD) Starting iconURL import");
    performURLImport();
    
    if (shouldStopThreadActivity())
        return syncThreadMainLoop();

#ifndef NDEBUG
    newStamp = currentTime();
    LOG(IconDatabase, "(THREAD) performURLImport() took %.4f seconds.  Entering main loop %.4f seconds from thread start", newStamp - timeStamp, newStamp - startTime);
#endif 

    LOG(IconDatabase, "(THREAD) Beginning sync");
    return syncThreadMainLoop();
}

static int databaseVersionNumber(SQLiteDatabase& db)
{
    return SQLiteStatement(db, "SELECT value FROM IconDatabaseInfo WHERE key = 'Version';").getColumnInt(0);
}

static bool isValidDatabase(SQLiteDatabase& db)
{

    // These four tables should always exist in a valid db
    if (!db.tableExists("IconInfo") || !db.tableExists("IconData") || !db.tableExists("PageURL") || !db.tableExists("IconDatabaseInfo"))
        return false;
    
    if (databaseVersionNumber(db) < currentDatabaseVersion) {
        LOG(IconDatabase, "DB version is not found or below expected valid version");
        return false;
    }
    
    return true;
}

static void createDatabaseTables(SQLiteDatabase& db)
{
    if (!db.executeCommand("CREATE TABLE PageURL (url TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,iconID INTEGER NOT NULL ON CONFLICT FAIL);")) {
        LOG_ERROR("Could not create PageURL table in database (%i) - %s", db.lastError(), db.lastErrorMsg());
        db.close();
        return;
    }
    if (!db.executeCommand("CREATE INDEX PageURLIndex ON PageURL (url);")) {
        LOG_ERROR("Could not create PageURL index in database (%i) - %s", db.lastError(), db.lastErrorMsg());
        db.close();
        return;
    }
    if (!db.executeCommand("CREATE TABLE IconInfo (iconID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE ON CONFLICT REPLACE, url TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, stamp INTEGER);")) {
        LOG_ERROR("Could not create IconInfo table in database (%i) - %s", db.lastError(), db.lastErrorMsg());
        db.close();
        return;
    }
    if (!db.executeCommand("CREATE INDEX IconInfoIndex ON IconInfo (url, iconID);")) {
        LOG_ERROR("Could not create PageURL index in database (%i) - %s", db.lastError(), db.lastErrorMsg());
        db.close();
        return;
    }
    if (!db.executeCommand("CREATE TABLE IconData (iconID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE ON CONFLICT REPLACE, data BLOB);")) {
        LOG_ERROR("Could not create IconData table in database (%i) - %s", db.lastError(), db.lastErrorMsg());
        db.close();
        return;
    }
    if (!db.executeCommand("CREATE INDEX IconDataIndex ON IconData (iconID);")) {
        LOG_ERROR("Could not create PageURL index in database (%i) - %s", db.lastError(), db.lastErrorMsg());
        db.close();
        return;
    }
    if (!db.executeCommand("CREATE TABLE IconDatabaseInfo (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) {
        LOG_ERROR("Could not create IconDatabaseInfo table in database (%i) - %s", db.lastError(), db.lastErrorMsg());
        db.close();
        return;
    }
    if (!db.executeCommand(String("INSERT INTO IconDatabaseInfo VALUES ('Version', ") + String::number(currentDatabaseVersion) + ");")) {
        LOG_ERROR("Could not insert icon database version into IconDatabaseInfo table (%i) - %s", db.lastError(), db.lastErrorMsg());
        db.close();
        return;
    }
}    

void IconDatabase::performOpenInitialization()
{
    ASSERT_ICON_SYNC_THREAD();
    
    if (!isOpen())
        return;
    
    if (checkIntegrityOnOpen) {
        checkIntegrityOnOpen = false;
        if (!checkIntegrity()) {
            LOG(IconDatabase, "Integrity check was bad - dumping IconDatabase");

            m_syncDB.close();
            
            {
                MutexLocker locker(m_syncLock);
                // Should've been consumed by SQLite, delete just to make sure we don't see it again in the future;
                deleteFile(m_completeDatabasePath + "-journal");
                deleteFile(m_completeDatabasePath);
            }
            
            // Reopen the write database, creating it from scratch
            if (!m_syncDB.open(m_completeDatabasePath)) {
                LOG_ERROR("Unable to open icon database at path %s - %s", m_completeDatabasePath.ascii().data(), m_syncDB.lastErrorMsg());
                return;
            }          
        }
    }
    
    int version = databaseVersionNumber(m_syncDB);
    
    if (version > currentDatabaseVersion) {
        LOG(IconDatabase, "Database version number %i is greater than our current version number %i - closing the database to prevent overwriting newer versions", version, currentDatabaseVersion);
        m_syncDB.close();
        m_threadTerminationRequested = true;
        return;
    }
    
    if (!isValidDatabase(m_syncDB)) {
        LOG(IconDatabase, "%s is missing or in an invalid state - reconstructing", m_completeDatabasePath.ascii().data());
        m_syncDB.clearAllTables();
        createDatabaseTables(m_syncDB);
    }

    // Reduce sqlite RAM cache size from default 2000 pages (~1.5kB per page). 3MB of cache for icon database is overkill
    if (!SQLiteStatement(m_syncDB, "PRAGMA cache_size = 200;").executeCommand())         
        LOG_ERROR("SQLite database could not set cache_size");
}

bool IconDatabase::checkIntegrity()
{
    ASSERT_ICON_SYNC_THREAD();
    
    SQLiteStatement integrity(m_syncDB, "PRAGMA integrity_check;");
    if (integrity.prepare() != SQLResultOk) {
        LOG_ERROR("checkIntegrity failed to execute");
        return false;
    }
    
    int resultCode = integrity.step();
    if (resultCode == SQLResultOk)
        return true;
        
    if (resultCode != SQLResultRow)
        return false;

    int columns = integrity.columnCount();
    if (columns != 1) {
        LOG_ERROR("Received %i columns performing integrity check, should be 1", columns);
        return false;
    }
        
    String resultText = integrity.getColumnText(0);
        
    // A successful, no-error integrity check will be "ok" - all other strings imply failure
    if (resultText == "ok")
        return true;
    
    LOG_ERROR("Icon database integrity check failed - \n%s", resultText.ascii().data());
    return false;
}

void IconDatabase::performURLImport()
{
    ASSERT_ICON_SYNC_THREAD();

    SQLiteStatement query(m_syncDB, "SELECT PageURL.url, IconInfo.url, IconInfo.stamp FROM PageURL INNER JOIN IconInfo ON PageURL.iconID=IconInfo.iconID;");
    
    if (query.prepare() != SQLResultOk) {
        LOG_ERROR("Unable to prepare icon url import query");
        return;
    }
    
    // Informal testing shows that draining the autorelease pool every 25 iterations is about as low as we can go
    // before performance starts to drop off, but we don't want to increase this number because then accumulated memory usage will go up
    AutodrainedPool pool(25);
        
    int result = query.step();
    while (result == SQLResultRow) {
        String pageURL = query.getColumnText(0);
        String iconURL = query.getColumnText(1);

        {
            MutexLocker locker(m_urlAndIconLock);
            
            PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURL);
            
            // If the pageRecord doesn't exist in this map, then no one has retained this pageURL
            // If the s_databaseCleanupCounter count is non-zero, then we're not supposed to be pruning the database in any manner,
            // so go ahead and actually create a pageURLRecord for this url even though it's not retained.
            // If database cleanup *is* allowed, we don't want to bother pulling in a page url from disk that noone is actually interested
            // in - we'll prune it later instead!
            if (!pageRecord && databaseCleanupCounter && !pageURL.isEmpty()) {
                pageRecord = new PageURLRecord(pageURL);
                m_pageURLToRecordMap.set(pageURL, pageRecord);
            }
            
            if (pageRecord) {
                IconRecord* currentIcon = pageRecord->iconRecord();

                if (!currentIcon || currentIcon->iconURL() != iconURL) {
                    currentIcon = getOrCreateIconRecord(iconURL);
                    pageRecord->setIconRecord(currentIcon);
                }
            
                // Regardless, the time stamp from disk still takes precedence.  Until we read this icon from disk, we didn't think we'd seen it before
                // so we marked the timestamp as "now", but it's really much older
                currentIcon->setTimestamp(query.getColumnInt(2));
            }            
        }
        
        // FIXME: Currently the WebKit API supports 1 type of notification that is sent whenever we get an Icon URL for a Page URL.  We might want to re-purpose it to work for 
        // getting the actually icon itself also (so each pageurl would get this notification twice) or we might want to add a second type of notification -
        // one for the URL and one for the Image itself
        // Note that WebIconDatabase is not neccessarily API so we might be able to make this change
        {
            MutexLocker locker(m_pendingReadingLock);
            if (m_pageURLsPendingImport.contains(pageURL)) {
                m_client->dispatchDidAddIconForPageURL(pageURL);
                m_pageURLsPendingImport.remove(pageURL);
            
                pool.cycle();
            }
        }
        
        // Stop the import at any time of the thread has been asked to shutdown
        if (shouldStopThreadActivity()) {
            LOG(IconDatabase, "IconDatabase asked to terminate during performURLImport()");
            return;
        }
        
        result = query.step();
    }
    
    if (result != SQLResultDone)
        LOG(IconDatabase, "Error reading page->icon url mappings from database");

    // Clear the m_pageURLsPendingImport set - either the page URLs ended up with an iconURL (that we'll notify about) or not, 
    // but after m_iconURLImportComplete is set to true, we don't care about this set anymore
    Vector<String> urls;
    {
        MutexLocker locker(m_pendingReadingLock);

        urls.appendRange(m_pageURLsPendingImport.begin(), m_pageURLsPendingImport.end());
        m_pageURLsPendingImport.clear();        
        m_iconURLImportComplete = true;
    }
    
    Vector<String> urlsToNotify;
    
    // Loop through the urls pending import
    // Remove unretained ones if database cleanup is allowed
    // Keep a set of ones that are retained and pending notification
    
    {
        MutexLocker locker(m_urlAndIconLock);
        
        for (unsigned i = 0; i < urls.size(); ++i) {
            if (!m_retainedPageURLs.contains(urls[i])) {
                PageURLRecord* record = m_pageURLToRecordMap.get(urls[i]);
                if (record && !databaseCleanupCounter) {
                    m_pageURLToRecordMap.remove(urls[i]);
                    IconRecord* iconRecord = record->iconRecord();
                    
                    // If this page is the only remaining retainer of its icon, mark that icon for deletion and don't bother
                    // reading anything related to it 
                    if (iconRecord && iconRecord->hasOneRef()) {
                        m_iconURLToRecordMap.remove(iconRecord->iconURL());
                        
                        {
                            MutexLocker locker(m_pendingReadingLock);
                            m_pageURLsInterestedInIcons.remove(urls[i]);
                            m_iconsPendingReading.remove(iconRecord);
                        }
                        {
                            MutexLocker locker(m_pendingSyncLock);
                            m_iconsPendingSync.set(iconRecord->iconURL(), iconRecord->snapshot(true));                    
                        }
                    }
                    
                    delete record;
                }
            } else {
                urlsToNotify.append(urls[i]);
            }
        }
    }

    LOG(IconDatabase, "Notifying %zu interested page URLs that their icon URL is known due to the import", urlsToNotify.size());
    // Now that we don't hold any locks, perform the actual notifications
    for (unsigned i = 0; i < urlsToNotify.size(); ++i) {
        LOG(IconDatabase, "Notifying icon info known for pageURL %s", urlsToNotify[i].ascii().data());
        m_client->dispatchDidAddIconForPageURL(urlsToNotify[i]);
        if (shouldStopThreadActivity())
            return;

        pool.cycle();
    }
    
    // Notify all DocumentLoaders that were waiting for an icon load decision on the main thread
    callOnMainThread(notifyPendingLoadDecisionsOnMainThread, this);
}

void* IconDatabase::syncThreadMainLoop()
{
    ASSERT_ICON_SYNC_THREAD();
    static bool prunedUnretainedIcons = false;

    m_syncLock.lock();

    // It's possible thread termination is requested before the main loop even starts - in that case, just skip straight to cleanup
    while (!m_threadTerminationRequested) {
        m_syncLock.unlock();

#ifndef NDEBUG
        double timeStamp = currentTime();
#endif
        LOG(IconDatabase, "(THREAD) Main work loop starting");

        // If we should remove all icons, do it now.  This is an uninteruptible procedure that we will always do before quitting if it is requested
        if (m_removeIconsRequested) {
            removeAllIconsOnThread();
            m_removeIconsRequested = false;
        }
        
        // Then, if the thread should be quitting, quit now!
        if (m_threadTerminationRequested)
            break;
        
        bool didAnyWork = true;
        while (didAnyWork) {
            didAnyWork = readFromDatabase();
            if (shouldStopThreadActivity())
                break;
                
            bool didWrite = writeToDatabase();
            if (shouldStopThreadActivity())
                break;
                
            // Prune unretained icons after the first time we sync anything out to the database
            // This way, pruning won't be the only operation we perform to the database by itself
            // We also don't want to bother doing this if the thread should be terminating (the user is quitting)
            // or if private browsing is enabled
            // We also don't want to prune if the m_databaseCleanupCounter count is non-zero - that means someone
            // has asked to delay pruning
            if (didWrite && !m_privateBrowsingEnabled && !prunedUnretainedIcons && !databaseCleanupCounter) {
#ifndef NDEBUG
                double time = currentTime();
#endif
                LOG(IconDatabase, "(THREAD) Starting pruneUnretainedIcons()");
                
                pruneUnretainedIcons();
                
                LOG(IconDatabase, "(THREAD) pruneUnretainedIcons() took %.4f seconds", currentTime() - time);
                
                // If pruneUnretainedIcons() returned early due to requested thread termination, its still okay
                // to mark prunedUnretainedIcons true because we're about to terminate anyway
                prunedUnretainedIcons = true;
            }
            
            didAnyWork = didAnyWork || didWrite;
            if (shouldStopThreadActivity())
                break;
        }
        
#ifndef NDEBUG
        double newstamp = currentTime();
        LOG(IconDatabase, "(THREAD) Main work loop ran for %.4f seconds, %s requested to terminate", newstamp - timeStamp, shouldStopThreadActivity() ? "was" : "was not");
#endif
                    
        m_syncLock.lock();
        
        // There is some condition that is asking us to stop what we're doing now and handle a special case
        // This is either removing all icons, or shutting down the thread to quit the app
        // We handle those at the top of this main loop so continue to jump back up there
        if (shouldStopThreadActivity())
            continue;
            
        m_syncCondition.wait(m_syncLock); 
    }
    m_syncLock.unlock();
    
    // Thread is terminating at this point
    return cleanupSyncThread();
}

bool IconDatabase::readFromDatabase()
{
    ASSERT_ICON_SYNC_THREAD();
    
#ifndef NDEBUG
    double timeStamp = currentTime();
#endif

    bool didAnyWork = false;

    // We'll make a copy of the sets of things that need to be read.  Then we'll verify at the time of updating the record that it still wants to be updated
    // This way we won't hold the lock for a long period of time
    Vector<IconRecord*> icons;
    {
        MutexLocker locker(m_pendingReadingLock);
        icons.appendRange(m_iconsPendingReading.begin(), m_iconsPendingReading.end());
    }
    
    // Keep track of icons we actually read to notify them of the new icon    
    HashSet<String> urlsToNotify;
    
    for (unsigned i = 0; i < icons.size(); ++i) {
        didAnyWork = true;
        RefPtr<SharedBuffer> imageData = getImageDataForIconURLFromSQLDatabase(icons[i]->iconURL());

        // Verify this icon still wants to be read from disk
        {
            MutexLocker urlLocker(m_urlAndIconLock);
            {
                MutexLocker readLocker(m_pendingReadingLock);
                
                if (m_iconsPendingReading.contains(icons[i])) {
                    // Set the new data
                    icons[i]->setImageData(imageData.get());
                    
                    // Remove this icon from the set that needs to be read
                    m_iconsPendingReading.remove(icons[i]);
                    
                    // We have a set of all Page URLs that retain this icon as well as all PageURLs waiting for an icon
                    // We want to find the intersection of these two sets to notify them
                    // Check the sizes of these two sets to minimize the number of iterations
                    const HashSet<String>* outerHash;
                    const HashSet<String>* innerHash;
                    
                    if (icons[i]->retainingPageURLs().size() > m_pageURLsInterestedInIcons.size()) {
                        outerHash = &m_pageURLsInterestedInIcons;
                        innerHash = &(icons[i]->retainingPageURLs());
                    } else {
                        innerHash = &m_pageURLsInterestedInIcons;
                        outerHash = &(icons[i]->retainingPageURLs());
                    }
                    
                    HashSet<String>::const_iterator iter = outerHash->begin();
                    HashSet<String>::const_iterator end = outerHash->end();
                    for (; iter != end; ++iter) {
                        if (innerHash->contains(*iter)) {
                            LOG(IconDatabase, "%s is interesting in the icon we just read.  Adding it to the list and removing it from the interested set", urlForLogging(*iter).ascii().data());
                            urlsToNotify.add(*iter);
                        }
                        
                        // If we ever get to the point were we've seen every url interested in this icon, break early
                        if (urlsToNotify.size() == m_pageURLsInterestedInIcons.size())
                            break;
                    }
                    
                    // We don't need to notify a PageURL twice, so all the ones we're about to notify can be removed from the interested set
                    if (urlsToNotify.size() == m_pageURLsInterestedInIcons.size())
                        m_pageURLsInterestedInIcons.clear();
                    else {
                        iter = urlsToNotify.begin();
                        end = urlsToNotify.end();
                        for (; iter != end; ++iter)
                            m_pageURLsInterestedInIcons.remove(*iter);
                    }
                }
            }
        }
    
        if (shouldStopThreadActivity())
            return didAnyWork;
        
        // Informal testing shows that draining the autorelease pool every 25 iterations is about as low as we can go
        // before performance starts to drop off, but we don't want to increase this number because then accumulated memory usage will go up
        AutodrainedPool pool(25);

        // Now that we don't hold any locks, perform the actual notifications
        HashSet<String>::iterator iter = urlsToNotify.begin();
        HashSet<String>::iterator end = urlsToNotify.end();
        for (unsigned iteration = 0; iter != end; ++iter, ++iteration) {
            LOG(IconDatabase, "Notifying icon received for pageURL %s", urlForLogging(*iter).ascii().data());
            m_client->dispatchDidAddIconForPageURL(*iter);
            if (shouldStopThreadActivity())
                return didAnyWork;
            
            pool.cycle();
        }

        LOG(IconDatabase, "Done notifying %i pageURLs who just received their icons", urlsToNotify.size());
        urlsToNotify.clear();
        
        if (shouldStopThreadActivity())
            return didAnyWork;
    }

    LOG(IconDatabase, "Reading from database took %.4f seconds", currentTime() - timeStamp);

    return didAnyWork;
}

bool IconDatabase::writeToDatabase()
{
    ASSERT_ICON_SYNC_THREAD();

#ifndef NDEBUG
    double timeStamp = currentTime();
#endif

    bool didAnyWork = false;
    
    // We can copy the current work queue then clear it out - If any new work comes in while we're writing out,
    // we'll pick it up on the next pass.  This greatly simplifies the locking strategy for this method and remains cohesive with changes
    // asked for by the database on the main thread
    Vector<IconSnapshot> iconSnapshots;
    Vector<PageURLSnapshot> pageSnapshots;
    {
        MutexLocker locker(m_pendingSyncLock);
        
        iconSnapshots.appendRange(m_iconsPendingSync.begin().values(), m_iconsPendingSync.end().values());
        m_iconsPendingSync.clear();
        
        pageSnapshots.appendRange(m_pageURLsPendingSync.begin().values(), m_pageURLsPendingSync.end().values());
        m_pageURLsPendingSync.clear();
    }
    
    if (iconSnapshots.size() || pageSnapshots.size())
        didAnyWork = true;
        
    SQLiteTransaction syncTransaction(m_syncDB);
    syncTransaction.begin();
    
    for (unsigned i = 0; i < iconSnapshots.size(); ++i) {
        writeIconSnapshotToSQLDatabase(iconSnapshots[i]);
        LOG(IconDatabase, "Wrote IconRecord for IconURL %s with timeStamp of %i to the DB", urlForLogging(iconSnapshots[i].iconURL).ascii().data(), iconSnapshots[i].timestamp);
    }
    
    for (unsigned i = 0; i < pageSnapshots.size(); ++i) {
        String iconURL = pageSnapshots[i].iconURL;

        // If the icon URL is empty, this page is meant to be deleted
        // ASSERTs are sanity checks to make sure the mappings exist if they should and don't if they shouldn't
        if (pageSnapshots[i].iconURL.isEmpty())
            removePageURLFromSQLDatabase(pageSnapshots[i].pageURL);
        else {
            setIconURLForPageURLInSQLDatabase(pageSnapshots[i].iconURL, pageSnapshots[i].pageURL);
        }
        LOG(IconDatabase, "Committed IconURL for PageURL %s to database", urlForLogging(pageSnapshots[i].pageURL).ascii().data());
    }

    syncTransaction.commit();
    
    // Check to make sure there are no dangling PageURLs - If there are, we want to output one log message but not spam the console potentially every few seconds
    checkForDanglingPageURLs(false);

    LOG(IconDatabase, "Updating the database took %.4f seconds", currentTime() - timeStamp);

    return didAnyWork;
}

void IconDatabase::pruneUnretainedIcons()
{
    ASSERT_ICON_SYNC_THREAD();

    if (!isOpen())
        return;        
    
    // This method should only be called once per run
    ASSERT(!m_initialPruningComplete);

    // This method relies on having read in all page URLs from the database earlier.
    ASSERT(m_iconURLImportComplete);

    // Get the known PageURLs from the db, and record the ID of any that are not in the retain count set.
    Vector<int64_t> pageIDsToDelete; 

    SQLiteStatement pageSQL(m_syncDB, "SELECT rowid, url FROM PageURL;");
    pageSQL.prepare();
    
    int result;
    while ((result = pageSQL.step()) == SQLResultRow) {
        MutexLocker locker(m_urlAndIconLock);
        if (!m_pageURLToRecordMap.contains(pageSQL.getColumnText(1)))
            pageIDsToDelete.append(pageSQL.getColumnInt64(0));
    }
    
    if (result != SQLResultDone)
        LOG_ERROR("Error reading PageURL table from on-disk DB");
    pageSQL.finalize();
    
    // Delete page URLs that were in the table, but not in our retain count set.
    size_t numToDelete = pageIDsToDelete.size();
    if (numToDelete) {
        SQLiteTransaction pruningTransaction(m_syncDB);
        pruningTransaction.begin();
        
        SQLiteStatement pageDeleteSQL(m_syncDB, "DELETE FROM PageURL WHERE rowid = (?);");
        pageDeleteSQL.prepare();
        for (size_t i = 0; i < numToDelete; ++i) {
            LOG(IconDatabase, "Pruning page with rowid %lli from disk", pageIDsToDelete[i]);
            pageDeleteSQL.bindInt64(1, pageIDsToDelete[i]);
            int result = pageDeleteSQL.step();
            if (result != SQLResultDone)
                LOG_ERROR("Unabled to delete page with id %lli from disk", pageIDsToDelete[i]);
            pageDeleteSQL.reset();
            
            // If the thread was asked to terminate, we should commit what pruning we've done so far, figuring we can
            // finish the rest later (hopefully)
            if (shouldStopThreadActivity()) {
                pruningTransaction.commit();
                return;
            }
        }
        pruningTransaction.commit();
        pageDeleteSQL.finalize();
    }
    
    // Deleting unreferenced icons from the Icon tables has to be atomic - 
    // If the user quits while these are taking place, they might have to wait.  Thankfully this will rarely be an issue
    // A user on a network home directory with a wildly inconsistent database might see quite a pause...

    SQLiteTransaction pruningTransaction(m_syncDB);
    pruningTransaction.begin();
    
    // Wipe Icons that aren't retained
    if (!m_syncDB.executeCommand("DELETE FROM IconData WHERE iconID NOT IN (SELECT iconID FROM PageURL);"))
        LOG_ERROR("Failed to execute SQL to prune unretained icons from the on-disk IconData table");    
    if (!m_syncDB.executeCommand("DELETE FROM IconInfo WHERE iconID NOT IN (SELECT iconID FROM PageURL);"))
        LOG_ERROR("Failed to execute SQL to prune unretained icons from the on-disk IconInfo table");    
    
    pruningTransaction.commit();
        
    checkForDanglingPageURLs(true);

    m_initialPruningComplete = true;
}

void IconDatabase::checkForDanglingPageURLs(bool pruneIfFound)
{
    ASSERT_ICON_SYNC_THREAD();
    
    // We don't want to keep performing this check and reporting this error if it has already found danglers so we keep track
    static bool danglersFound = false;
    
    // However, if the caller wants us to prune the danglers, we will reset this flag and prune every time
    if (pruneIfFound)
        danglersFound = false;
        
    if (!danglersFound && SQLiteStatement(m_syncDB, "SELECT url FROM PageURL WHERE PageURL.iconID NOT IN (SELECT iconID FROM IconInfo) LIMIT 1;").returnsAtLeastOneResult()) {
        danglersFound = true;
        LOG_ERROR("Dangling PageURL entries found");
        if (pruneIfFound && !m_syncDB.executeCommand("DELETE FROM PageURL WHERE iconID NOT IN (SELECT iconID FROM IconInfo);"))
            LOG_ERROR("Unable to prune dangling PageURLs");
    }
}

void IconDatabase::removeAllIconsOnThread()
{
    ASSERT_ICON_SYNC_THREAD();

    LOG(IconDatabase, "Removing all icons on the sync thread");
        
    // Delete all the prepared statements so they can start over
    deleteAllPreparedStatements();    
    
    // To reset the on-disk database, we'll wipe all its tables then vacuum it
    // This is easier and safer than closing it, deleting the file, and recreating from scratch
    m_syncDB.clearAllTables();
    m_syncDB.runVacuumCommand();
    createDatabaseTables(m_syncDB);
    
    LOG(IconDatabase, "Dispatching notification that we removed all icons");
    m_client->dispatchDidRemoveAllIcons();    
}

void IconDatabase::deleteAllPreparedStatements()
{        
    ASSERT_ICON_SYNC_THREAD();
    
    m_setIconIDForPageURLStatement.set(0);
    m_removePageURLStatement.set(0);
    m_getIconIDForIconURLStatement.set(0);
    m_getImageDataForIconURLStatement.set(0);
    m_addIconToIconInfoStatement.set(0);
    m_addIconToIconDataStatement.set(0);
    m_getImageDataStatement.set(0);
    m_deletePageURLsForIconURLStatement.set(0);
    m_deleteIconFromIconInfoStatement.set(0);
    m_deleteIconFromIconDataStatement.set(0);
    m_updateIconInfoStatement.set(0);
    m_updateIconDataStatement.set(0);
    m_setIconInfoStatement.set(0);
    m_setIconDataStatement.set(0);
}

void* IconDatabase::cleanupSyncThread()
{
    ASSERT_ICON_SYNC_THREAD();
    
#ifndef NDEBUG
    double timeStamp = currentTime();
#endif 

    // If the removeIcons flag is set, remove all icons from the db.
    if (m_removeIconsRequested)
        removeAllIconsOnThread();

    // Sync remaining icons out
    LOG(IconDatabase, "(THREAD) Doing final writeout and closure of sync thread");
    writeToDatabase();
    
    // Close the database
    MutexLocker locker(m_syncLock);
    
    m_databaseDirectory = String();
    m_completeDatabasePath = String();
    deleteAllPreparedStatements();    
    m_syncDB.close();
    
#ifndef NDEBUG
    LOG(IconDatabase, "(THREAD) Final closure took %.4f seconds", currentTime() - timeStamp);
#endif
    
    m_syncThreadRunning = false;
    return 0;
}

bool IconDatabase::imported()
{
    ASSERT_ICON_SYNC_THREAD();
    
    if (m_isImportedSet)
        return m_imported;
        
    SQLiteStatement query(m_syncDB, "SELECT IconDatabaseInfo.value FROM IconDatabaseInfo WHERE IconDatabaseInfo.key = \"ImportedSafari2Icons\";");
    if (query.prepare() != SQLResultOk) {
        LOG_ERROR("Unable to prepare imported statement");
        return false;
    }
    
    int result = query.step();
    if (result == SQLResultRow)
        result = query.getColumnInt(0);
    else {
        if (result != SQLResultDone)
            LOG_ERROR("imported statement failed");
        result = 0;
    }
    
    m_isImportedSet = true;
    return m_imported = result;
}

void IconDatabase::setImported(bool import)
{
    ASSERT_ICON_SYNC_THREAD();

    m_imported = import;
    m_isImportedSet = true;
    
    String queryString = import ?
        "INSERT INTO IconDatabaseInfo (key, value) VALUES (\"ImportedSafari2Icons\", 1);" :
        "INSERT INTO IconDatabaseInfo (key, value) VALUES (\"ImportedSafari2Icons\", 0);";
        
    SQLiteStatement query(m_syncDB, queryString);
    
    if (query.prepare() != SQLResultOk) {
        LOG_ERROR("Unable to prepare set imported statement");
        return;
    }    
    
    if (query.step() != SQLResultDone)
        LOG_ERROR("set imported statement failed");
}

// readySQLiteStatement() handles two things
// 1 - If the SQLDatabase& argument is different, the statement must be destroyed and remade.  This happens when the user
//     switches to and from private browsing
// 2 - Lazy construction of the Statement in the first place, in case we've never made this query before
inline void readySQLiteStatement(OwnPtr<SQLiteStatement>& statement, SQLiteDatabase& db, const String& str)
{
    if (statement && (statement->database() != &db || statement->isExpired())) {
        if (statement->isExpired())
            LOG(IconDatabase, "SQLiteStatement associated with %s is expired", str.ascii().data());
        statement.set(0);
    }
    if (!statement) {
        statement.set(new SQLiteStatement(db, str));
        if (statement->prepare() != SQLResultOk)
            LOG_ERROR("Preparing statement %s failed", str.ascii().data());
    }
}

void IconDatabase::setIconURLForPageURLInSQLDatabase(const String& iconURL, const String& pageURL)
{
    ASSERT_ICON_SYNC_THREAD();
    
    int64_t iconID = getIconIDForIconURLFromSQLDatabase(iconURL);

    if (!iconID)
        iconID = addIconURLToSQLDatabase(iconURL);
    
    if (!iconID) {
        LOG_ERROR("Failed to establish an ID for iconURL %s", urlForLogging(iconURL).ascii().data());
        ASSERT(false);
        return;
    }
    
    setIconIDForPageURLInSQLDatabase(iconID, pageURL);
}

void IconDatabase::setIconIDForPageURLInSQLDatabase(int64_t iconID, const String& pageURL)
{
    ASSERT_ICON_SYNC_THREAD();
    
    readySQLiteStatement(m_setIconIDForPageURLStatement, m_syncDB, "INSERT INTO PageURL (url, iconID) VALUES ((?), ?);");
    m_setIconIDForPageURLStatement->bindText(1, pageURL);
    m_setIconIDForPageURLStatement->bindInt64(2, iconID);

    int result = m_setIconIDForPageURLStatement->step();
    if (result != SQLResultDone) {
        ASSERT(false);
        LOG_ERROR("setIconIDForPageURLQuery failed for url %s", urlForLogging(pageURL).ascii().data());
    }

    m_setIconIDForPageURLStatement->reset();
}

void IconDatabase::removePageURLFromSQLDatabase(const String& pageURL)
{
    ASSERT_ICON_SYNC_THREAD();
    
    readySQLiteStatement(m_removePageURLStatement, m_syncDB, "DELETE FROM PageURL WHERE url = (?);");
    m_removePageURLStatement->bindText(1, pageURL);

    if (m_removePageURLStatement->step() != SQLResultDone)
        LOG_ERROR("removePageURLFromSQLDatabase failed for url %s", urlForLogging(pageURL).ascii().data());
    
    m_removePageURLStatement->reset();
}


int64_t IconDatabase::getIconIDForIconURLFromSQLDatabase(const String& iconURL)
{
    ASSERT_ICON_SYNC_THREAD();
    
    readySQLiteStatement(m_getIconIDForIconURLStatement, m_syncDB, "SELECT IconInfo.iconID FROM IconInfo WHERE IconInfo.url = (?);");
    m_getIconIDForIconURLStatement->bindText(1, iconURL);
    
    int64_t result = m_getIconIDForIconURLStatement->step();
    if (result == SQLResultRow)
        result = m_getIconIDForIconURLStatement->getColumnInt64(0);
    else {
        if (result != SQLResultDone)
            LOG_ERROR("getIconIDForIconURLFromSQLDatabase failed for url %s", urlForLogging(iconURL).ascii().data());
        result = 0;
    }

    m_getIconIDForIconURLStatement->reset();
    return result;
}

int64_t IconDatabase::addIconURLToSQLDatabase(const String& iconURL)
{
    ASSERT_ICON_SYNC_THREAD();
    
    // There would be a transaction here to make sure these two inserts are atomic
    // In practice the only caller of this method is always wrapped in a transaction itself so placing another
    // here is unnecessary
    
    readySQLiteStatement(m_addIconToIconInfoStatement, m_syncDB, "INSERT INTO IconInfo (url, stamp) VALUES (?, 0);");
    m_addIconToIconInfoStatement->bindText(1, iconURL);
    
    int result = m_addIconToIconInfoStatement->step();
    m_addIconToIconInfoStatement->reset();
    if (result != SQLResultDone) {
        LOG_ERROR("addIconURLToSQLDatabase failed to insert %s into IconInfo", urlForLogging(iconURL).ascii().data());
        return 0;
    }
    int64_t iconID = m_syncDB.lastInsertRowID();
    
    readySQLiteStatement(m_addIconToIconDataStatement, m_syncDB, "INSERT INTO IconData (iconID, data) VALUES (?, ?);");
    m_addIconToIconDataStatement->bindInt64(1, iconID);
    
    result = m_addIconToIconDataStatement->step();
    m_addIconToIconDataStatement->reset();
    if (result != SQLResultDone) {
        LOG_ERROR("addIconURLToSQLDatabase failed to insert %s into IconData", urlForLogging(iconURL).ascii().data());
        return 0;
    }
    
    return iconID;
}

PassRefPtr<SharedBuffer> IconDatabase::getImageDataForIconURLFromSQLDatabase(const String& iconURL)
{
    ASSERT_ICON_SYNC_THREAD();
    
    RefPtr<SharedBuffer> imageData;
    
    readySQLiteStatement(m_getImageDataForIconURLStatement, m_syncDB, "SELECT IconData.data FROM IconData WHERE IconData.iconID IN (SELECT iconID FROM IconInfo WHERE IconInfo.url = (?));");
    m_getImageDataForIconURLStatement->bindText(1, iconURL);
    
    int result = m_getImageDataForIconURLStatement->step();
    if (result == SQLResultRow) {
        Vector<char> data;
        m_getImageDataForIconURLStatement->getColumnBlobAsVector(0, data);
        imageData = new SharedBuffer;
        imageData->append(data.data(), data.size());
    } else if (result != SQLResultDone)
        LOG_ERROR("getImageDataForIconURLFromSQLDatabase failed for url %s", urlForLogging(iconURL).ascii().data());

    m_getImageDataForIconURLStatement->reset();
    
    return imageData.release();
}

void IconDatabase::removeIconFromSQLDatabase(const String& iconURL)
{
    ASSERT_ICON_SYNC_THREAD();
    
    if (iconURL.isEmpty())
        return;

    // There would be a transaction here to make sure these removals are atomic
    // In practice the only caller of this method is always wrapped in a transaction itself so placing another here is unnecessary
    
    // It's possible this icon is not in the database because of certain rapid browsing patterns (such as a stress test) where the
    // icon is marked to be added then marked for removal before it is ever written to disk.  No big deal, early return
    int64_t iconID = getIconIDForIconURLFromSQLDatabase(iconURL);
    if (!iconID)
        return;
    
    readySQLiteStatement(m_deletePageURLsForIconURLStatement, m_syncDB, "DELETE FROM PageURL WHERE PageURL.iconID = (?);");
    m_deletePageURLsForIconURLStatement->bindInt64(1, iconID);
    
    if (m_deletePageURLsForIconURLStatement->step() != SQLResultDone)
        LOG_ERROR("m_deletePageURLsForIconURLStatement failed for url %s", urlForLogging(iconURL).ascii().data());
    
    readySQLiteStatement(m_deleteIconFromIconInfoStatement, m_syncDB, "DELETE FROM IconInfo WHERE IconInfo.iconID = (?);");
    m_deleteIconFromIconInfoStatement->bindInt64(1, iconID);
    
    if (m_deleteIconFromIconInfoStatement->step() != SQLResultDone)
        LOG_ERROR("m_deleteIconFromIconInfoStatement failed for url %s", urlForLogging(iconURL).ascii().data());
        
    readySQLiteStatement(m_deleteIconFromIconDataStatement, m_syncDB, "DELETE FROM IconData WHERE IconData.iconID = (?);");
    m_deleteIconFromIconDataStatement->bindInt64(1, iconID);
    
    if (m_deleteIconFromIconDataStatement->step() != SQLResultDone)
        LOG_ERROR("m_deleteIconFromIconDataStatement failed for url %s", urlForLogging(iconURL).ascii().data());
        
    m_deletePageURLsForIconURLStatement->reset();
    m_deleteIconFromIconInfoStatement->reset();
    m_deleteIconFromIconDataStatement->reset();
}

void IconDatabase::writeIconSnapshotToSQLDatabase(const IconSnapshot& snapshot)
{
    ASSERT_ICON_SYNC_THREAD();
    
    if (snapshot.iconURL.isEmpty())
        return;
        
    // A nulled out timestamp and data means this icon is destined to be deleted - do that instead of writing it out
    if (!snapshot.timestamp && !snapshot.data) {
        LOG(IconDatabase, "Removing %s from on-disk database", urlForLogging(snapshot.iconURL).ascii().data());
        removeIconFromSQLDatabase(snapshot.iconURL);
        return;
    }

    // There would be a transaction here to make sure these removals are atomic
    // In practice the only caller of this method is always wrapped in a transaction itself so placing another here is unnecessary
        
    // Get the iconID for this url
    int64_t iconID = getIconIDForIconURLFromSQLDatabase(snapshot.iconURL);
    
    // If there is already an iconID in place, update the database.  
    // Otherwise, insert new records
    if (iconID) {    
        readySQLiteStatement(m_updateIconInfoStatement, m_syncDB, "UPDATE IconInfo SET stamp = ?, url = ? WHERE iconID = ?;");
        m_updateIconInfoStatement->bindInt64(1, snapshot.timestamp);
        m_updateIconInfoStatement->bindText(2, snapshot.iconURL);
        m_updateIconInfoStatement->bindInt64(3, iconID);

        if (m_updateIconInfoStatement->step() != SQLResultDone)
            LOG_ERROR("Failed to update icon info for url %s", urlForLogging(snapshot.iconURL).ascii().data());
        
        m_updateIconInfoStatement->reset();
        
        readySQLiteStatement(m_updateIconDataStatement, m_syncDB, "UPDATE IconData SET data = ? WHERE iconID = ?;");
        m_updateIconDataStatement->bindInt64(2, iconID);
                
        // If we *have* image data, bind it to this statement - Otherwise bind "null" for the blob data, 
        // signifying that this icon doesn't have any data    
        if (snapshot.data && snapshot.data->size())
            m_updateIconDataStatement->bindBlob(1, snapshot.data->data(), snapshot.data->size());
        else
            m_updateIconDataStatement->bindNull(1);
        
        if (m_updateIconDataStatement->step() != SQLResultDone)
            LOG_ERROR("Failed to update icon data for url %s", urlForLogging(snapshot.iconURL).ascii().data());

        m_updateIconDataStatement->reset();
    } else {    
        readySQLiteStatement(m_setIconInfoStatement, m_syncDB, "INSERT INTO IconInfo (url,stamp) VALUES (?, ?);");
        m_setIconInfoStatement->bindText(1, snapshot.iconURL);
        m_setIconInfoStatement->bindInt64(2, snapshot.timestamp);

        if (m_setIconInfoStatement->step() != SQLResultDone)
            LOG_ERROR("Failed to set icon info for url %s", urlForLogging(snapshot.iconURL).ascii().data());
        
        m_setIconInfoStatement->reset();
        
        int64_t iconID = m_syncDB.lastInsertRowID();

        readySQLiteStatement(m_setIconDataStatement, m_syncDB, "INSERT INTO IconData (iconID, data) VALUES (?, ?);");
        m_setIconDataStatement->bindInt64(1, iconID);

        // If we *have* image data, bind it to this statement - Otherwise bind "null" for the blob data, 
        // signifying that this icon doesn't have any data    
        if (snapshot.data && snapshot.data->size())
            m_setIconDataStatement->bindBlob(2, snapshot.data->data(), snapshot.data->size());
        else
            m_setIconDataStatement->bindNull(2);
        
        if (m_setIconDataStatement->step() != SQLResultDone)
            LOG_ERROR("Failed to set icon data for url %s", urlForLogging(snapshot.iconURL).ascii().data());

        m_setIconDataStatement->reset();
    }
}

} // namespace WebCore
