Commit c052b2d9 authored by Michael Pyne's avatar Michael Pyne
Browse files

local8Bit encodings scare me, so save the QString in the shared...

local8Bit encodings scare me, so save the QString in the shared PlaylistItem/CollectionListItem metadata
instead of converting to QByteArray (I don't really think utf-8 would help much since QStrings can buy us
localeAwareCompare as well).

Also use a standard Qt collection for our StringShare instead of a constant sized hash table.  Probably a
better way to do this would be a simple cache that tracks how much each string is put in, not sure how much
that would help though.

svn path=/trunk/KDE/kdemultimedia/juk/; revision=923583
parent c9cc9814
......@@ -379,7 +379,7 @@ void CollectionListItem::refresh()
int offset = static_cast<Playlist *>(listView())->columnOffset();
int columns = lastColumn() + offset + 1;
data()->local8Bit.resize(columns);
data()->metadata.resize(columns);
data()->cachedWidths.resize(columns);
for(int i = offset; i < columns; i++) {
......@@ -387,7 +387,7 @@ void CollectionListItem::refresh()
if(id != TrackNumberColumn && id != LengthColumn) {
// All columns other than track num and length need local-encoded data for sorting
QByteArray toLower = text(i).toLower().toLocal8Bit();
QString toLower = text(i).toLower();
// For some columns, we may be able to share some strings
......@@ -397,13 +397,13 @@ void CollectionListItem::refresh()
{
toLower = StringShare::tryShare(toLower);
if(id != YearColumn && id != CommentColumn && data()->local8Bit[id] != toLower) {
CollectionList::instance()->removeStringFromDict(data()->local8Bit[id], id);
if(id != YearColumn && id != CommentColumn && data()->metadata[id] != toLower) {
CollectionList::instance()->removeStringFromDict(data()->metadata[id], id);
CollectionList::instance()->addStringToDict(text(i), id);
}
}
data()->local8Bit[id] = toLower;
data()->metadata[id] = toLower;
}
int newWidth = width(listView()->fontMetrics(), listView(), i);
......
......@@ -381,8 +381,8 @@ int PlaylistItem::compare(const PlaylistItem *firstItem, const PlaylistItem *sec
return 1;
break;
default:
return strcoll(firstItem->d->local8Bit[column - offset],
secondItem->d->local8Bit[column - offset]);
return QString::localeAwareCompare(firstItem->d->metadata[column - offset],
secondItem->d->metadata[column - offset]);
}
}
......
......@@ -178,6 +178,10 @@ protected:
bool isValid() const;
/**
* Shared data between all PlaylistItems from the same track (incl. the CollectionItem
* representing said track.
*/
struct Data : public KShared
{
Data() {}
......@@ -185,7 +189,7 @@ protected:
Data(const QString &path) : fileHandle(path) {}
FileHandle fileHandle;
QVector<QByteArray> local8Bit;
QVector<QString> metadata; ///< Artist, album, or genre tags. Other columns unfilled
QVector<int> cachedWidths;
};
......
......@@ -2,6 +2,9 @@
begin : Sat Oct 25 2003
copyright : (C) 2003 by Maksim Orlovich
email : maksim.orlovich@kdemail.net
copyright : (C) 2009 by Michael Pyne
email : michael.pyne@kdemail.net
***************************************************************************/
/***************************************************************************
......@@ -13,17 +16,17 @@
* *
***************************************************************************/
#include "stringshare.h"
#include "stringhash.h"
#include <QSet>
const int SIZE = 5003;
StringShare::Data* StringShare::s_data = 0;
/**
* We store the strings in two simple direct-mapped (i.e. no collision handling,
* just replace) hashes, which contain strings or null objects. This costs only
* 4 bytes per slot on 32-bit archs, so with the default constant size we only
* really use 40K or so.
* We store the strings in a simple direct-mapped (i.e. no collision handling,
* just replace) hash, which contains strings. We limit the number of entries
* in the set to SIZE to avoid excessive growth.
*
* The end result is that many strings end up pointing to the same underlying data
* object, instead of each one having its own little copy.
......@@ -31,8 +34,7 @@ StringShare::Data* StringShare::s_data = 0;
struct StringShare::Data
{
QString qstringHash [SIZE];
QByteArray qcstringHash[SIZE];
QSet<QString> qstringHash;
};
StringShare::Data* StringShare::data()
......@@ -44,32 +46,16 @@ StringShare::Data* StringShare::data()
QString StringShare::tryShare(const QString& in)
{
uint index = qHash(in) % SIZE;
Data* dat = data();
if (dat->qstringHash[index] == in) //Match
return dat->qstringHash[index];
else
{
//Else replace whatever was there before
dat->qstringHash[index] = in;
return in;
}
}
QByteArray StringShare::tryShare(const QByteArray& in)
{
uint index = qHash(in) % SIZE;
QSet<QString>::const_iterator found = dat->qstringHash.constFind(in);
if(found != dat->qstringHash.constEnd())
return *found;
Data* dat = data();
if (dat->qcstringHash[index] == in) //Match
return dat->qcstringHash[index];
else
{
//Else replace whatever was there before
dat->qcstringHash[index] = in;
return in;
}
// Insert if we have room and now this one is the standard
if(dat->qstringHash.size() < SIZE)
dat->qstringHash.insert(in);
return in;
}
// vim: set et sw=4 tw=0 sta:
......@@ -16,18 +16,17 @@
#ifndef STRING_SHARE_H
#define STRING_SHARE_H
#include <QString>
class QString;
/**
This class attempts to normalize repeated occurrences of strings to use
the same shared object, if possible, by using a small hash
*/
* This class attempts to normalize repeated occurrences of strings to use
*the same shared object, if possible, by using a small hash
*/
class StringShare
{
struct Data;
public:
static QString tryShare(const QString& in);
static QByteArray tryShare(const QByteArray& in);
static QString tryShare(const QString& in);
private:
static Data* data();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment