browsercore/core/network/featherweightcache_p.h
author hgs
Fri, 15 Oct 2010 17:30:59 -0400
changeset 16 3c88a81ff781
permissions -rw-r--r--
201041

/****************************************************************************
**
 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
 *
 * This file is part of Qt Web Runtime.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#ifndef FEATHERWEIGHTCACHE_P_H
#define FEATHERWEIGHTCACHE_P_H

#include <QBuffer>
#include <QHash>
#include <QTemporaryFile>
#include <QFile>
#include <QNetworkCacheMetaData>
#include <QObject>
#include <QQueue>
#include <QMutex>
#include <QWaitCondition>
#include <cacheworkerthread.h>

namespace WRT {
class CacheItem
{
public:
    CacheItem() : file(0)
    {
    }
    ~CacheItem()
    {
        reset();
    }

    QNetworkCacheMetaData metaData;
    QBuffer data;
    QTemporaryFile *file;
    inline qint64 size() const
        { return file ? file->size() : data.size(); }

    inline void reset() {
        metaData = QNetworkCacheMetaData();
        data.close();
        delete file;
        file = 0;
    }
    void writeHeader(QFile *device) const;
    void writeCompressedData(QFile *device) const;
    bool read(QFile *device, bool readData);

    bool canCompress() const;
};


class WorkerThread : public QThread
{

    Q_OBJECT

public:
    WorkerThread();
    ~WorkerThread();

    void expireLazily(QString cacheDir, qint64 maxCacheSize);

protected:
    void run();

private:
    QMutex mutex;
    QWaitCondition condition;
    bool abort;
    qint64 expireImpl();

    QString cacheDir;
    qint64 maxCacheSize;

signals:
    void onDiskSizeChanged(qint64 newSize);

};


#define URL2HASH(url) FeatherWeightCachePrivate::generateId(url).toUInt()

// Assume this much higher physical disk usage. Platform and media dependent
// TODO: On Symbian, we could instead round up number to multiple of TVolumeIOParamInfo.iClusterSize
#define FILESYSTEMOVERHEAD 2048
#define ROUNDUPTOMULTIPLE(x, multipleof)    ( (x + multipleof - 1) & ~(multipleof - 1) )

class FeatherWeightCachePrivate : public QObject
{
    Q_OBJECT

public:
    FeatherWeightCachePrivate(QObject* parent): QObject(parent)
        , maximumCacheSize(1024 * 1024 * 10) //set the maximum default cache to 10M 
        , currentCacheSize(-1)
    {
        // Queued connection because onDiskSizeChanged() is currently always triggered from run() method of worker thread
        QObject::connect( &beastOfBurden, SIGNAL( onDiskSizeChanged(qint64) ), this, SLOT( updateCacheSize(qint64) ), Qt::DirectConnection );
    }

    ~FeatherWeightCachePrivate()
    {
        // When beastOfBurden's d'tor is called
        // it will wait() and then auto-terminate

        QObject::disconnect(&beastOfBurden, SIGNAL( onDiskSizeChanged(qint64) ), this, SLOT( updateCacheSize(qint64)));
    }

    qint64 expire();
    static QByteArray generateId(const QUrl &url);
    QString cacheFileName(const QUrl &url) const;
    QString tmpCacheFileName() const;
    bool removeFile(const QString &file);
    void storeItem(CacheItem *item);
    void prepareLayout();
    static quint32 crc32(const char *data, uint len);

    mutable CacheItem lastItem;
    QString cacheDirectory;
    qint64 maximumCacheSize;
    qint64 currentCacheSize;

    QHash<QIODevice*, CacheItem*> inserting;

    WorkerThread beastOfBurden;

    // a look up table (LUT) that stores file sizes
    // corresponding to cached URLs. Helps speed up
    // cache eviction or expiration logic.
    // key = CRC32 hash of url , value = size of file on disk
    // QHash<quint32, qint64> lut;

    // bool isTrimPending;

    //Recommended buffer sizes for fast IO on caching volume
    struct {
        quint32 readBufSize;
        quint32 writeBufSize;
        quint32 clusterSize;
    } volumeInfo;

public slots:
    void updateCacheSize(qint64);
};
}

#endif // FEATHERWEIGHTCACHE_P_H