mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-19 18:26:34 +01:00
Significant memory savings in AdBlock (~ 30MB with just EasyList)
Even empty QRegExp can occupy a lot of space in memory, which can grow into a big number with tens of thousands AdBlock rules. QRegExp is now allocated with new, and only when really needed.
This commit is contained in:
parent
a1ad8dab9b
commit
9f226b9738
@ -184,7 +184,7 @@ void AdBlockIcon::toggleCustomFilter()
|
||||
customList->removeFilter(filter);
|
||||
}
|
||||
else {
|
||||
AdBlockRule rule(filter, customList);
|
||||
AdBlockRule* rule = new AdBlockRule(filter, customList);
|
||||
customList->addRule(rule);
|
||||
}
|
||||
}
|
||||
|
@ -375,3 +375,8 @@ void AdBlockManager::showRule()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AdBlockManager::~AdBlockManager()
|
||||
{
|
||||
qDeleteAll(m_subscriptions);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
|
||||
* Copyright (C) 2010-2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -38,6 +38,8 @@ class QT_QUPZILLA_EXPORT AdBlockManager : public QObject
|
||||
|
||||
public:
|
||||
AdBlockManager(QObject* parent = 0);
|
||||
~AdBlockManager();
|
||||
|
||||
static AdBlockManager* instance();
|
||||
|
||||
void load();
|
||||
|
@ -101,7 +101,7 @@ AdBlockRule::AdBlockRule(const QString &filter, AdBlockSubscription* subscriptio
|
||||
, m_exception(false)
|
||||
, m_internalDisabled(false)
|
||||
, m_domainRestricted(false)
|
||||
, m_useRegExp(false)
|
||||
, m_regExp(0)
|
||||
, m_useDomainMatch(false)
|
||||
, m_useEndsMatch(false)
|
||||
, m_thirdParty(false)
|
||||
@ -189,7 +189,7 @@ void AdBlockRule::setEnabled(bool enabled)
|
||||
|
||||
bool AdBlockRule::isSlow() const
|
||||
{
|
||||
return m_useRegExp;
|
||||
return m_regExp != 0;
|
||||
}
|
||||
|
||||
bool AdBlockRule::isInternalDisabled() const
|
||||
@ -211,8 +211,8 @@ bool AdBlockRule::networkMatch(const QNetworkRequest &request, const QString &do
|
||||
else if (m_useEndsMatch) {
|
||||
matched = encodedUrl.endsWith(m_matchString, m_caseSensitivity);
|
||||
}
|
||||
else if (m_useRegExp) {
|
||||
matched = (m_regExp.indexIn(encodedUrl) != -1);
|
||||
else if (m_regExp) {
|
||||
matched = (m_regExp->indexIn(encodedUrl) != -1);
|
||||
}
|
||||
else {
|
||||
matched = encodedUrl.contains(m_matchString, m_caseSensitivity);
|
||||
@ -466,8 +466,7 @@ void AdBlockRule::parseFilter()
|
||||
parsedLine = parsedLine.mid(1);
|
||||
parsedLine = parsedLine.left(parsedLine.size() - 1);
|
||||
|
||||
m_useRegExp = true;
|
||||
m_regExp = QzRegExp(parsedLine, m_caseSensitivity);
|
||||
m_regExp = new QzRegExp(parsedLine, m_caseSensitivity);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -518,13 +517,11 @@ void AdBlockRule::parseFilter()
|
||||
.replace(QzRegExp(QLatin1String("\\\\\\|$")), QLatin1String("$")) // process anchor at expression end
|
||||
.replace(QzRegExp(QLatin1String("\\\\\\*")), QLatin1String(".*")); // replace wildcards by .*
|
||||
|
||||
m_useRegExp = true;
|
||||
m_regExp = QzRegExp(parsedLine, m_caseSensitivity);
|
||||
m_regExp = new QzRegExp(parsedLine, m_caseSensitivity);
|
||||
return;
|
||||
}
|
||||
|
||||
// We haven't found anything that needs use of regexp, yay!
|
||||
m_useRegExp = false;
|
||||
m_matchString = parsedLine;
|
||||
}
|
||||
|
||||
@ -561,3 +558,8 @@ bool AdBlockRule::_matchDomain(const QString &domain, const QString &filter) con
|
||||
|
||||
return domain[index - 1] == QLatin1Char('.');
|
||||
}
|
||||
|
||||
AdBlockRule::~AdBlockRule()
|
||||
{
|
||||
delete m_regExp;
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ class AdBlockRule
|
||||
{
|
||||
public:
|
||||
AdBlockRule(const QString &filter = QString(), AdBlockSubscription* subscription = 0);
|
||||
~AdBlockRule();
|
||||
|
||||
AdBlockSubscription* subscription() const;
|
||||
void setSubscription(AdBlockSubscription* subscription);
|
||||
@ -110,8 +111,7 @@ private:
|
||||
bool m_internalDisabled;
|
||||
bool m_domainRestricted;
|
||||
|
||||
bool m_useRegExp;
|
||||
QzRegExp m_regExp;
|
||||
QzRegExp* m_regExp;
|
||||
|
||||
bool m_useDomainMatch;
|
||||
bool m_useEndsMatch;
|
||||
|
@ -118,10 +118,10 @@ void AdBlockSubscription::loadSubscription(const QStringList &disabledRules)
|
||||
m_rules.clear();
|
||||
|
||||
while (!textStream.atEnd()) {
|
||||
AdBlockRule rule(textStream.readLine(), this);
|
||||
AdBlockRule* rule = new AdBlockRule(textStream.readLine(), this);
|
||||
|
||||
if (disabledRules.contains(rule.filter())) {
|
||||
rule.setEnabled(false);
|
||||
if (disabledRules.contains(rule->filter())) {
|
||||
rule->setEnabled(false);
|
||||
}
|
||||
|
||||
m_rules.append(rule);
|
||||
@ -258,25 +258,25 @@ QString AdBlockSubscription::elementHidingRulesForDomain(const QString &domain)
|
||||
|
||||
const AdBlockRule* AdBlockSubscription::rule(int offset) const
|
||||
{
|
||||
if (!QzTools::listContainsIndex(m_rules, offset)) {
|
||||
if (!QzTools::vectorContainsIndex(m_rules, offset)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return &m_rules[offset];
|
||||
return m_rules[offset];
|
||||
}
|
||||
|
||||
QList<AdBlockRule> AdBlockSubscription::allRules() const
|
||||
QVector<AdBlockRule*> AdBlockSubscription::allRules() const
|
||||
{
|
||||
return m_rules;
|
||||
}
|
||||
|
||||
const AdBlockRule* AdBlockSubscription::enableRule(int offset)
|
||||
{
|
||||
if (!QzTools::listContainsIndex(m_rules, offset)) {
|
||||
if (!QzTools::vectorContainsIndex(m_rules, offset)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
AdBlockRule* rule = &m_rules[offset];
|
||||
AdBlockRule* rule = m_rules[offset];
|
||||
rule->setEnabled(true);
|
||||
AdBlockManager::instance()->removeDisabledRule(rule->filter());
|
||||
|
||||
@ -290,11 +290,11 @@ const AdBlockRule* AdBlockSubscription::enableRule(int offset)
|
||||
|
||||
const AdBlockRule* AdBlockSubscription::disableRule(int offset)
|
||||
{
|
||||
if (!QzTools::listContainsIndex(m_rules, offset)) {
|
||||
if (!QzTools::vectorContainsIndex(m_rules, offset)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
AdBlockRule* rule = &m_rules[offset];
|
||||
AdBlockRule* rule = m_rules[offset];
|
||||
rule->setEnabled(false);
|
||||
AdBlockManager::instance()->addDisabledRule(rule->filter());
|
||||
|
||||
@ -316,7 +316,7 @@ bool AdBlockSubscription::canBeRemoved() const
|
||||
return true;
|
||||
}
|
||||
|
||||
int AdBlockSubscription::addRule(const AdBlockRule &rule)
|
||||
int AdBlockSubscription::addRule(AdBlockRule* rule)
|
||||
{
|
||||
Q_UNUSED(rule)
|
||||
return -1;
|
||||
@ -328,7 +328,7 @@ bool AdBlockSubscription::removeRule(int offset)
|
||||
return false;
|
||||
}
|
||||
|
||||
const AdBlockRule* AdBlockSubscription::replaceRule(const AdBlockRule &rule, int offset)
|
||||
const AdBlockRule* AdBlockSubscription::replaceRule(AdBlockRule* rule, int offset)
|
||||
{
|
||||
Q_UNUSED(rule)
|
||||
Q_UNUSED(offset)
|
||||
@ -346,7 +346,7 @@ void AdBlockSubscription::populateCache()
|
||||
|
||||
int count = m_rules.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const AdBlockRule* rule = &m_rules.at(i);
|
||||
const AdBlockRule* rule = m_rules.at(i);
|
||||
if (!rule->isEnabled()) {
|
||||
continue;
|
||||
}
|
||||
@ -428,8 +428,8 @@ void AdBlockCustomList::saveSubscription()
|
||||
textStream << "Url: " << url().toString() << endl;
|
||||
textStream << "[Adblock Plus 1.1.1]" << endl;
|
||||
|
||||
foreach(const AdBlockRule & rule, m_rules) {
|
||||
textStream << rule.filter() << endl;
|
||||
foreach(const AdBlockRule * rule, m_rules) {
|
||||
textStream << rule->filter() << endl;
|
||||
}
|
||||
|
||||
file.close();
|
||||
@ -447,8 +447,8 @@ bool AdBlockCustomList::canBeRemoved() const
|
||||
|
||||
bool AdBlockCustomList::containsFilter(const QString &filter) const
|
||||
{
|
||||
foreach(const AdBlockRule & rule, m_rules) {
|
||||
if (rule.filter() == filter) {
|
||||
foreach(const AdBlockRule * rule, m_rules) {
|
||||
if (rule->filter() == filter) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -459,9 +459,9 @@ bool AdBlockCustomList::containsFilter(const QString &filter) const
|
||||
bool AdBlockCustomList::removeFilter(const QString &filter)
|
||||
{
|
||||
for (int i = 0; i < m_rules.count(); ++i) {
|
||||
const AdBlockRule rule = m_rules.at(i);
|
||||
const AdBlockRule* rule = m_rules.at(i);
|
||||
|
||||
if (rule.filter() == filter) {
|
||||
if (rule->filter() == filter) {
|
||||
return removeRule(i);
|
||||
}
|
||||
}
|
||||
@ -469,7 +469,7 @@ bool AdBlockCustomList::removeFilter(const QString &filter)
|
||||
return false;
|
||||
}
|
||||
|
||||
int AdBlockCustomList::addRule(const AdBlockRule &rule)
|
||||
int AdBlockCustomList::addRule(AdBlockRule* rule)
|
||||
{
|
||||
m_rules.append(rule);
|
||||
populateCache();
|
||||
@ -481,32 +481,41 @@ int AdBlockCustomList::addRule(const AdBlockRule &rule)
|
||||
|
||||
bool AdBlockCustomList::removeRule(int offset)
|
||||
{
|
||||
if (!QzTools::listContainsIndex(m_rules, offset)) {
|
||||
if (!QzTools::vectorContainsIndex(m_rules, offset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString &filter = m_rules[offset].filter();
|
||||
AdBlockRule* rule = m_rules.at(offset);
|
||||
const QString &filter = rule->filter();
|
||||
|
||||
m_rules.removeAt(offset);
|
||||
m_rules.remove(offset);
|
||||
populateCache();
|
||||
|
||||
emit subscriptionEdited();
|
||||
|
||||
AdBlockManager::instance()->removeDisabledRule(filter);
|
||||
|
||||
delete rule;
|
||||
return true;
|
||||
}
|
||||
|
||||
const AdBlockRule* AdBlockCustomList::replaceRule(const AdBlockRule &rule, int offset)
|
||||
const AdBlockRule* AdBlockCustomList::replaceRule(AdBlockRule* rule, int offset)
|
||||
{
|
||||
if (!QzTools::listContainsIndex(m_rules, offset)) {
|
||||
if (!QzTools::vectorContainsIndex(m_rules, offset)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
delete m_rules.at(offset);
|
||||
|
||||
m_rules[offset] = rule;
|
||||
populateCache();
|
||||
|
||||
emit subscriptionEdited();
|
||||
|
||||
return &m_rules[offset];
|
||||
return m_rules[offset];
|
||||
}
|
||||
|
||||
AdBlockSubscription::~AdBlockSubscription()
|
||||
{
|
||||
qDeleteAll(m_rules);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
|
||||
* Copyright (C) 2010-2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -46,8 +46,7 @@
|
||||
#ifndef ADBLOCKSUBSCRIPTION_H
|
||||
#define ADBLOCKSUBSCRIPTION_H
|
||||
|
||||
#include <QVarLengthArray>
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
#include <QUrl>
|
||||
|
||||
#include "qz_namespace.h"
|
||||
@ -64,6 +63,7 @@ class QT_QUPZILLA_EXPORT AdBlockSubscription : public QObject
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AdBlockSubscription(const QString &title, QObject* parent = 0);
|
||||
~AdBlockSubscription();
|
||||
|
||||
QString title() const;
|
||||
|
||||
@ -85,7 +85,7 @@ public:
|
||||
QString elementHidingRulesForDomain(const QString &domain) const;
|
||||
|
||||
const AdBlockRule* rule(int offset) const;
|
||||
QList<AdBlockRule> allRules() const;
|
||||
QVector<AdBlockRule*> allRules() const;
|
||||
|
||||
const AdBlockRule* enableRule(int offset);
|
||||
const AdBlockRule* disableRule(int offset);
|
||||
@ -93,9 +93,9 @@ public:
|
||||
virtual bool canEditRules() const;
|
||||
virtual bool canBeRemoved() const;
|
||||
|
||||
virtual int addRule(const AdBlockRule &rule);
|
||||
virtual int addRule(AdBlockRule* rule);
|
||||
virtual bool removeRule(int offset);
|
||||
virtual const AdBlockRule* replaceRule(const AdBlockRule &rule, int offset);
|
||||
virtual const AdBlockRule* replaceRule(AdBlockRule* rule, int offset);
|
||||
|
||||
public slots:
|
||||
void updateSubscription();
|
||||
@ -113,15 +113,15 @@ protected:
|
||||
|
||||
FollowRedirectReply* m_reply;
|
||||
|
||||
QList<AdBlockRule> m_rules;
|
||||
QVector<AdBlockRule*> m_rules;
|
||||
QString m_elementHidingRules;
|
||||
|
||||
QVarLengthArray<const AdBlockRule*> m_networkExceptionRules;
|
||||
QVarLengthArray<const AdBlockRule*> m_networkBlockRules;
|
||||
QVarLengthArray<const AdBlockRule*> m_domainRestrictedCssRules;
|
||||
QVector<const AdBlockRule*> m_networkExceptionRules;
|
||||
QVector<const AdBlockRule*> m_networkBlockRules;
|
||||
QVector<const AdBlockRule*> m_domainRestrictedCssRules;
|
||||
|
||||
QVarLengthArray<const AdBlockRule*> m_documentRules;
|
||||
QVarLengthArray<const AdBlockRule*> m_elemhideRules;
|
||||
QVector<const AdBlockRule*> m_documentRules;
|
||||
QVector<const AdBlockRule*> m_elemhideRules;
|
||||
|
||||
private:
|
||||
QString m_title;
|
||||
@ -157,9 +157,9 @@ public:
|
||||
bool containsFilter(const QString &filter) const;
|
||||
bool removeFilter(const QString &filter);
|
||||
|
||||
int addRule(const AdBlockRule &rule);
|
||||
int addRule(AdBlockRule* rule);
|
||||
bool removeRule(int offset);
|
||||
const AdBlockRule* replaceRule(const AdBlockRule &rule, int offset);
|
||||
const AdBlockRule* replaceRule(AdBlockRule* rule, int offset);
|
||||
|
||||
signals:
|
||||
void subscriptionEdited();
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
|
||||
* Copyright (C) 2010-2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -101,19 +101,20 @@ void AdBlockTreeWidget::itemChanged(QTreeWidgetItem* item)
|
||||
// Disable rule
|
||||
const AdBlockRule* rule = m_subscription->disableRule(offset);
|
||||
|
||||
adjustItemFeatures(item, *rule);
|
||||
adjustItemFeatures(item, rule);
|
||||
}
|
||||
else if (item->checkState(0) == Qt::Checked && !oldRule->isEnabled()) {
|
||||
// Enable rule
|
||||
const AdBlockRule* rule = m_subscription->enableRule(offset);
|
||||
|
||||
adjustItemFeatures(item, *rule);
|
||||
adjustItemFeatures(item, rule);
|
||||
}
|
||||
else if (m_subscription->canEditRules()) {
|
||||
// Custom rule has been changed
|
||||
const AdBlockRule* rule = m_subscription->replaceRule(AdBlockRule(item->text(0), m_subscription), offset);
|
||||
AdBlockRule* newRule = new AdBlockRule(item->text(0), m_subscription);
|
||||
const AdBlockRule* rule = m_subscription->replaceRule(newRule, offset);
|
||||
|
||||
adjustItemFeatures(item, *rule);
|
||||
adjustItemFeatures(item, rule);
|
||||
}
|
||||
|
||||
m_itemChangingBlock = false;
|
||||
@ -140,7 +141,7 @@ void AdBlockTreeWidget::addRule()
|
||||
return;
|
||||
}
|
||||
|
||||
AdBlockRule rule(newRule, m_subscription);
|
||||
AdBlockRule* rule = new AdBlockRule(newRule, m_subscription);
|
||||
int offset = m_subscription->addRule(rule);
|
||||
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
@ -177,14 +178,14 @@ void AdBlockTreeWidget::subscriptionUpdated()
|
||||
m_itemChangingBlock = false;
|
||||
}
|
||||
|
||||
void AdBlockTreeWidget::adjustItemFeatures(QTreeWidgetItem* item, const AdBlockRule &rule)
|
||||
void AdBlockTreeWidget::adjustItemFeatures(QTreeWidgetItem* item, const AdBlockRule* rule)
|
||||
{
|
||||
if (!rule.isEnabled()) {
|
||||
if (!rule->isEnabled()) {
|
||||
QFont font;
|
||||
font.setItalic(true);
|
||||
item->setForeground(0, QColor(Qt::gray));
|
||||
|
||||
if (!rule.isComment()) {
|
||||
if (!rule->isComment()) {
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setCheckState(0, Qt::Unchecked);
|
||||
item->setFont(0, font);
|
||||
@ -196,11 +197,11 @@ void AdBlockTreeWidget::adjustItemFeatures(QTreeWidgetItem* item, const AdBlockR
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setCheckState(0, Qt::Checked);
|
||||
|
||||
if (rule.isCssRule()) {
|
||||
if (rule->isCssRule()) {
|
||||
item->setForeground(0, QColor(Qt::darkBlue));
|
||||
item->setFont(0, QFont());
|
||||
}
|
||||
else if (rule.isException()) {
|
||||
else if (rule->isException()) {
|
||||
item->setForeground(0, QColor(Qt::darkGreen));
|
||||
item->setFont(0, QFont());
|
||||
}
|
||||
@ -236,12 +237,12 @@ void AdBlockTreeWidget::refresh()
|
||||
m_topItem->setFont(0, boldFont);
|
||||
addTopLevelItem(m_topItem);
|
||||
|
||||
const QList<AdBlockRule> &allRules = m_subscription->allRules();
|
||||
const QVector<AdBlockRule*> &allRules = m_subscription->allRules();
|
||||
|
||||
int index = 0;
|
||||
foreach(const AdBlockRule & rule, allRules) {
|
||||
foreach(const AdBlockRule * rule, allRules) {
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(m_topItem);
|
||||
item->setText(0, rule.filter());
|
||||
item->setText(0, rule->filter());
|
||||
item->setData(0, Qt::UserRole + 10, index);
|
||||
|
||||
if (m_subscription->canEditRules()) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
|
||||
* Copyright (C) 2010-2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -49,7 +49,7 @@ private slots:
|
||||
void subscriptionUpdated();
|
||||
|
||||
private:
|
||||
void adjustItemFeatures(QTreeWidgetItem* item, const AdBlockRule &rule);
|
||||
void adjustItemFeatures(QTreeWidgetItem* item, const AdBlockRule* rule);
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
|
||||
AdBlockSubscription* m_subscription;
|
||||
|
@ -79,6 +79,12 @@ bool listContainsIndex(const QList<T> &list, int index)
|
||||
return (index >= 0 && list.count() > index);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool vectorContainsIndex(const QVector<T> &list, int index)
|
||||
{
|
||||
return (index >= 0 && list.count() > index);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // GLOBALFUNCTIONS_H
|
||||
|
Loading…
Reference in New Issue
Block a user