summaryrefslogtreecommitdiff
path: root/library/qdawg.cpp
Unidiff
Diffstat (limited to 'library/qdawg.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/qdawg.cpp2
1 files changed, 0 insertions, 2 deletions
diff --git a/library/qdawg.cpp b/library/qdawg.cpp
index af5dc82..2ea5734 100644
--- a/library/qdawg.cpp
+++ b/library/qdawg.cpp
@@ -1,215 +1,213 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#include "qdawg.h" 20#include "qdawg.h"
21#include <qintdict.h> 21#include <qintdict.h>
22#include <qvaluelist.h>
23#include <qtextstream.h>
24#include <qfile.h> 22#include <qfile.h>
25#include <qtl.h> 23#include <qtl.h>
26 24
27#include <limits.h> 25#include <limits.h>
28#include <stdio.h> 26#include <stdio.h>
29 27
30// for mmap 28// for mmap
31#include <sys/types.h> 29#include <sys/types.h>
32#include <sys/stat.h> 30#include <sys/stat.h>
33#include <sys/mman.h> 31#include <sys/mman.h>
34#include <fcntl.h> 32#include <fcntl.h>
35#include <errno.h> 33#include <errno.h>
36#include <unistd.h> 34#include <unistd.h>
37 35
38class QDawgPrivate; 36class QDawgPrivate;
39class QTrie; 37class QTrie;
40 38
41typedef QValueList<QTrie*> TrieClub; 39typedef QValueList<QTrie*> TrieClub;
42typedef QIntDict<TrieClub> TrieClubDirectory; 40typedef QIntDict<TrieClub> TrieClubDirectory;
43 41
44class TriePtr { 42class TriePtr {
45public: 43public:
46 QChar letter; 44 QChar letter;
47 QTrie* p; 45 QTrie* p;
48 int operator <(const TriePtr& o) const; 46 int operator <(const TriePtr& o) const;
49 int operator >(const TriePtr& o) const; 47 int operator >(const TriePtr& o) const;
50 int operator <=(const TriePtr& o) const; 48 int operator <=(const TriePtr& o) const;
51}; 49};
52 50
53class TrieList : public QValueList<TriePtr> { 51class TrieList : public QValueList<TriePtr> {
54 bool sorted; 52 bool sorted;
55public: 53public:
56 TrieList() 54 TrieList()
57 { 55 {
58 sorted=TRUE; 56 sorted=TRUE;
59 } 57 }
60 58
61 QTrie* findAdd(QChar c); 59 QTrie* findAdd(QChar c);
62 bool equal(TrieList& l); 60 bool equal(TrieList& l);
63 61
64 void sort() 62 void sort()
65 { 63 {
66 if ( !sorted ) { 64 if ( !sorted ) {
67 qHeapSort(*this); 65 qHeapSort(*this);
68 sorted = TRUE; 66 sorted = TRUE;
69 } 67 }
70 } 68 }
71}; 69};
72 70
73// A fast but memory-wasting temporary class. The Dawg is the goal. 71// A fast but memory-wasting temporary class. The Dawg is the goal.
74class QTrie { 72class QTrie {
75public: 73public:
76 QTrie(); 74 QTrie();
77 ~QTrie(); 75 ~QTrie();
78 76
79 void insertWord(const QString& s, uint index=0); 77 void insertWord(const QString& s, uint index=0);
80 bool equal(QTrie* o); 78 bool equal(QTrie* o);
81 void dump(int indent=0); 79 void dump(int indent=0);
82 80
83private: 81private:
84 TrieList children; 82 TrieList children;
85 bool isword; 83 bool isword;
86 84
87 friend class QDawgPrivate; 85 friend class QDawgPrivate;
88 int maxdepth; 86 int maxdepth;
89 int decendants; 87 int decendants;
90 int key; 88 int key;
91 void distributeKeys(TrieClubDirectory& directory); 89 void distributeKeys(TrieClubDirectory& directory);
92 QTrie* clubLeader(TrieClubDirectory& directory); 90 QTrie* clubLeader(TrieClubDirectory& directory);
93 int collectKeys(); 91 int collectKeys();
94 friend class TriePtr; 92 friend class TriePtr;
95 friend class TrieList; 93 friend class TrieList;
96}; 94};
97 95
98QTrie::QTrie() 96QTrie::QTrie()
99{ 97{
100 key = 0; 98 key = 0;
101 isword = FALSE; 99 isword = FALSE;
102} 100}
103 101
104QTrie::~QTrie() 102QTrie::~QTrie()
105{ 103{
106 // NOTE: we do not delete the children - after conversion to DAWG 104 // NOTE: we do not delete the children - after conversion to DAWG
107 // it's too difficult. The QTrie's are deleted via the directory. 105 // it's too difficult. The QTrie's are deleted via the directory.
108} 106}
109 107
110void QTrie::insertWord(const QString& s, uint index) 108void QTrie::insertWord(const QString& s, uint index)
111{ 109{
112 if ( index == s.length() ) { 110 if ( index == s.length() ) {
113 isword = TRUE; 111 isword = TRUE;
114 } else { 112 } else {
115 QTrie* t = children.findAdd(s[index]); 113 QTrie* t = children.findAdd(s[index]);
116 t->insertWord(s,index+1); 114 t->insertWord(s,index+1);
117 } 115 }
118} 116}
119 117
120bool QTrie::equal(QTrie* o) 118bool QTrie::equal(QTrie* o)
121{ 119{
122 if ( o == this ) return TRUE; 120 if ( o == this ) return TRUE;
123 if ( isword != o->isword ) 121 if ( isword != o->isword )
124 return FALSE; 122 return FALSE;
125 return children.equal(o->children); 123 return children.equal(o->children);
126} 124}
127 125
128void QTrie::dump(int indent) 126void QTrie::dump(int indent)
129{ 127{
130 for (TrieList::Iterator it=children.begin(); it!=children.end(); ++it) { 128 for (TrieList::Iterator it=children.begin(); it!=children.end(); ++it) {
131 QTrie* s = (*it).p; 129 QTrie* s = (*it).p;
132 for (int in=0; in<indent; in++) 130 for (int in=0; in<indent; in++)
133 fputc(' ',stderr); 131 fputc(' ',stderr);
134 fprintf(stderr," %c %d %s %p\n",(*it).letter.unicode(), 132 fprintf(stderr," %c %d %s %p\n",(*it).letter.unicode(),
135 s->key,s->isword?"word":"",s); 133 s->key,s->isword?"word":"",s);
136 s->dump(indent+2); 134 s->dump(indent+2);
137 } 135 }
138} 136}
139 137
140void QTrie::distributeKeys(TrieClubDirectory& directory) 138void QTrie::distributeKeys(TrieClubDirectory& directory)
141{ 139{
142 maxdepth = INT_MIN; 140 maxdepth = INT_MIN;
143 decendants = children.count(); 141 decendants = children.count();
144 key = 0; 142 key = 0;
145 for (TrieList::Iterator it=children.begin(); it!=children.end(); ++it) { 143 for (TrieList::Iterator it=children.begin(); it!=children.end(); ++it) {
146 QTrie* s = (*it).p; 144 QTrie* s = (*it).p;
147 QChar l = (*it).letter; 145 QChar l = (*it).letter;
148 s->distributeKeys(directory); 146 s->distributeKeys(directory);
149 key = key*64+l.unicode()+s->key*5; 147 key = key*64+l.unicode()+s->key*5;
150 decendants += s->decendants; 148 decendants += s->decendants;
151 if ( s->maxdepth+1 > maxdepth ) 149 if ( s->maxdepth+1 > maxdepth )
152 maxdepth = s->maxdepth+1; 150 maxdepth = s->maxdepth+1;
153 } 151 }
154 if ( decendants ) { 152 if ( decendants ) {
155 key += decendants + maxdepth*256 + children.count() * 65536; 153 key += decendants + maxdepth*256 + children.count() * 65536;
156 if ( !key ) key++; // unlikely 154 if ( !key ) key++; // unlikely
157 } 155 }
158 TrieClub* c = directory[key]; 156 TrieClub* c = directory[key];
159 if ( !c ) directory.insert(key, (c = new TrieClub) ); 157 if ( !c ) directory.insert(key, (c = new TrieClub) );
160 c->prepend(this); 158 c->prepend(this);
161} 159}
162 160
163QTrie* QTrie::clubLeader(TrieClubDirectory& directory) 161QTrie* QTrie::clubLeader(TrieClubDirectory& directory)
164{ 162{
165 if ( !key ) return directory[0]->first(); 163 if ( !key ) return directory[0]->first();
166 for (TrieList::Iterator it=children.begin(); it!=children.end(); ++it) { 164 for (TrieList::Iterator it=children.begin(); it!=children.end(); ++it) {
167 QTrie* t= (*it).p->clubLeader(directory); 165 QTrie* t= (*it).p->clubLeader(directory);
168 (*it).p = t; 166 (*it).p = t;
169 } 167 }
170 TrieClub *club = directory[key]; 168 TrieClub *club = directory[key];
171 for (TrieClub::Iterator it = club->begin(); it != club->end(); ++it) { 169 for (TrieClub::Iterator it = club->begin(); it != club->end(); ++it) {
172 QTrie* o = *it; 170 QTrie* o = *it;
173 if ( o->equal(this) ) 171 if ( o->equal(this) )
174 return o; 172 return o;
175 } 173 }
176 return this; 174 return this;
177} 175}
178 176
179int QTrie::collectKeys() 177int QTrie::collectKeys()
180{ 178{
181 int n=0; 179 int n=0;
182 if ( key ) key=0,n+=children.count(); 180 if ( key ) key=0,n+=children.count();
183 for (TrieList::Iterator it=children.begin(); it!=children.end(); ++it) 181 for (TrieList::Iterator it=children.begin(); it!=children.end(); ++it)
184 n += (*it).p->collectKeys(); 182 n += (*it).p->collectKeys();
185 return n; 183 return n;
186} 184}
187 185
188int TriePtr::operator <(const TriePtr& o) const 186int TriePtr::operator <(const TriePtr& o) const
189 { return letter < o.letter; } 187 { return letter < o.letter; }
190int TriePtr::operator >(const TriePtr& o) const 188int TriePtr::operator >(const TriePtr& o) const
191 { return letter > o.letter; } 189 { return letter > o.letter; }
192int TriePtr::operator <=(const TriePtr& o) const 190int TriePtr::operator <=(const TriePtr& o) const
193 { return letter <= o.letter; } 191 { return letter <= o.letter; }
194 192
195bool TrieList::equal(TrieList& l) 193bool TrieList::equal(TrieList& l)
196{ 194{
197 if ( count() != l.count() ) 195 if ( count() != l.count() )
198 return FALSE; 196 return FALSE;
199 sort(); l.sort(); 197 sort(); l.sort();
200 ConstIterator it2 = begin(); 198 ConstIterator it2 = begin();
201 ConstIterator it = l.begin(); 199 ConstIterator it = l.begin();
202 for( ; it != l.end(); ++it, ++it2 ) 200 for( ; it != l.end(); ++it, ++it2 )
203 if ( (*it).letter != (*it2).letter || ! (*it).p->equal((*it2).p) ) 201 if ( (*it).letter != (*it2).letter || ! (*it).p->equal((*it2).p) )
204 return FALSE; 202 return FALSE;
205 return TRUE; 203 return TRUE;
206} 204}
207QTrie* TrieList::findAdd(QChar c) 205QTrie* TrieList::findAdd(QChar c)
208{ 206{
209 for (Iterator it=begin(); it!=end(); ++it) { 207 for (Iterator it=begin(); it!=end(); ++it) {
210 if ( (*it).letter == c ) 208 if ( (*it).letter == c )
211 return (*it).p; 209 return (*it).p;
212 } 210 }
213 TriePtr p; 211 TriePtr p;
214 p.p = new QTrie; 212 p.p = new QTrie;
215 p.letter = c; 213 p.letter = c;