stringshare.cpp 2.05 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/**
 * Copyright (C) 2003 Maksim Orlovich <maksim.orlovich@kdemail.net>
 *
 * 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 the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */
16
#include "stringshare.h"
17

18 19
#include <QHash>

20 21 22 23 24
const int SIZE = 5003;

StringShare::Data* StringShare::s_data = 0;

/**
25
 * We store the strings in a simple direct-mapped (i.e. no collision handling,
26 27 28
 * just replace) hash, 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.
29 30
 *
 * The end result is that many strings end up pointing to the same underlying data
31
 * object, instead of each one having its own little copy.
32 33 34 35 36 37
 *
 * More importantly, the way the tryShare function is coded ensures that
 * most-recently inserted text stays in the cache, which gives a better chance
 * of continuing to share data. (Even if something old ("foo") that was shared
 * gets kicked out, all the other "foo"s will still be sharing each other's
 * data.
38
 */
39 40 41

struct StringShare::Data
{
42
    QString  qstringHash [SIZE];
43 44 45 46 47 48
};

StringShare::Data* StringShare::data()
{
    if (!s_data)
        s_data = new Data;
49
    return s_data;
50 51 52 53
}

QString StringShare::tryShare(const QString& in)
{
54
    uint index = qHash(in) % SIZE;
55

56 57 58 59 60 61 62 63 64
    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;
    }
65
}
66 67

// vim: set et sw=4 tw=0 sta: