Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
compress.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3// Qt-Security score:insignificant reason:build-tool
4
5#include "compress.h"
6
7#include <QtCore/qdebug.h>
8#include <QtCore/qlist.h>
9
10#include <algorithm>
11#include <iterator>
12#include <iostream>
13
14#define QLALR_NO_CHECK_SORTED_TABLE
15
16struct _Fit
17{
18 inline bool operator () (int a, int b) const
19 {
20 return a == 0 || b == 0 || a == b;
21 }
22};
23
25{
26 inline bool operator () (int a, int b) const
27 { return a == b; }
28};
29
31{
34
35 _GenerateCheck(QList<int>::const_iterator it, int i) : iterator(it), initial(i) { }
36
37 inline int operator()()
38 {
39 int check = initial++;
40 return *iterator++ ? check : -1;
41 }
42};
43
45{
46public:
47 typedef const int *const_iterator;
48 typedef const int *iterator;
49
50public:
51 inline UncompressedRow ():
52 _M_index (0),
53 _M_begin (nullptr),
54 _M_end (nullptr),
55 _M_beginNonZeros (nullptr),
56 _M_endNonZeros (nullptr) {}
57
58 inline UncompressedRow (int index, const_iterator begin, const_iterator end)
59 { assign (index, begin, end); }
60
61 inline int index () const { return _M_index; }
62 inline const_iterator begin () const { return _M_begin; }
63 inline const_iterator end () const { return _M_end; }
64
65 inline void assign (int index, const_iterator begin, const_iterator end)
66 {
67 _M_index = index;
68 _M_begin = begin;
69 _M_end = end;
70
71 _M_beginNonZeros = _M_begin;
72 _M_endNonZeros = _M_end;
73
74 for (_M_beginNonZeros = _M_begin; _M_beginNonZeros != _M_end && ! _M_beginNonZeros [0]; ++_M_beginNonZeros)
75 /*continue*/ ;
76
77#if 0
78 for (_M_endNonZeros = _M_end; _M_endNonZeros != _M_beginNonZeros && ! _M_endNonZeros [-1]; --_M_endNonZeros)
79 /*continue*/ ;
80#endif
81 }
82
83 inline int at (int index) const
84 { return _M_begin [index]; }
85
86 inline bool isEmpty () const
87 { return _M_begin == _M_end; }
88
89 inline int size () const
90 { return _M_end - _M_begin; }
91
92 inline int nonZeroElements () const
93 { return _M_endNonZeros - _M_beginNonZeros; }
94
95 inline int count (int value) const
96 { return std::count (begin (), end (), value); }
97
99 { return _M_beginNonZeros; }
100
102 { return _M_endNonZeros; }
103
104private:
105 int _M_index;
106 const_iterator _M_begin;
107 const_iterator _M_end;
108 const_iterator _M_beginNonZeros;
109 const_iterator _M_endNonZeros;
110};
111
113{
114 inline bool operator () (const UncompressedRow &a, const UncompressedRow &b) const
115 { return a.count (0) > b.count (0); }
116};
117
119{
120}
121
122void Compress::operator () (int *table, int row_count, int column_count)
123{
124 index.clear ();
125 info.clear ();
126 check.clear ();
127
128 QList<UncompressedRow> sortedTable(row_count);
129
130 for (int i = 0; i < row_count; ++i)
131 {
132 int *begin = &table [i * column_count];
133 int *end = begin + column_count;
134
135 sortedTable [i].assign (i, begin, end);
136 }
137
138 std::sort (sortedTable.begin (), sortedTable.end (), _SortUncompressedRow ());
139
141 int previous_zeros = INT_MAX;
142
143 for (const UncompressedRow &row : std::as_const(sortedTable))
144 {
145 int zeros = row.count (0);
146
147 Q_ASSERT (zeros <= previous_zeros);
148 zeros = previous_zeros;
149 qDebug () << "OK!";
150 }
151#endif
152
153 index.fill (-999999, row_count);
154
155 for (const UncompressedRow &row : std::as_const(sortedTable))
156 {
157 int first_token = std::distance (row.begin (), row.beginNonZeros ());
158 QList<int>::iterator pos = info.begin();
159
160 while (pos != info.end ())
161 {
162 if (pos == info.begin ())
163 {
164 // try to find a perfect match
165 QList<int>::iterator pm = std::search(pos, info.end(), row.beginNonZeros(),
166 row.endNonZeros(), _PerfectMatch());
167
168 if (pm != info.end ())
169 {
170 pos = pm;
171 break;
172 }
173 }
174
175 pos = std::search (pos, info.end (), row.beginNonZeros (), row.endNonZeros (), _Fit ());
176
177 if (pos == info.end ())
178 break;
179
180 int idx = std::distance (info.begin (), pos) - first_token;
181 bool conflict = false;
182
183 for (int j = 0; ! conflict && j < row.size (); ++j)
184 {
185 if (row.at (j) == 0)
186 conflict |= idx + j >= 0 && check [idx + j] == j;
187
188 else
189 conflict |= check [idx + j] == j;
190 }
191
192 if (! conflict)
193 break;
194
195 ++pos;
196 }
197
198 if (pos == info.end ())
199 {
200 int size = info.size ();
201
202 info.resize (info.size () + row.nonZeroElements ());
203 check.resize (info.size ());
204
205 std::fill (check.begin () + size, check.end (), -1);
206 pos = info.begin () + size;
207 }
208
209 int offset = std::distance (info.begin (), pos);
210 index [row.index ()] = offset - first_token;
211
212 for (const int *it = row.beginNonZeros (); it != row.endNonZeros (); ++it, ++pos)
213 {
214 if (*it)
215 *pos = *it;
216 }
217
218 int i = row.index ();
219
220 for (int j = 0; j < row.size (); ++j)
221 {
222 if (row.at (j) == 0)
223 continue;
224
225 check [index [i] + j] = j;
226 }
227 }
228
229#if 0
230 for (const UncompressedRow &row : std::as_const(sortedTable))
231 {
232 int i = row.index ();
233 Q_ASSERT (i < sortedTable.size ());
234
235 for (int j = 0; j < row.size (); ++j)
236 {
237 if (row.at (j) == 0)
238 {
239 Q_ASSERT (index [i] + j < 0 || check [index [i] + j] != j);
240 continue;
241 }
242
243 Q_ASSERT ( info [index [i] + j] == row.at (j));
244 Q_ASSERT (check [index [i] + j] == j);
245 }
246 }
247#endif
248}
void operator()(int *table, int row_count, int column_count)
Definition compress.cpp:122
const_iterator beginNonZeros() const
Definition compress.cpp:98
const_iterator endNonZeros() const
Definition compress.cpp:101
UncompressedRow(int index, const_iterator begin, const_iterator end)
Definition compress.cpp:58
const int * iterator
Definition compress.cpp:48
int nonZeroElements() const
Definition compress.cpp:92
int at(int index) const
Definition compress.cpp:83
const_iterator end() const
Definition compress.cpp:63
bool isEmpty() const
Definition compress.cpp:86
int index() const
Definition compress.cpp:61
void assign(int index, const_iterator begin, const_iterator end)
Definition compress.cpp:65
int count(int value) const
Definition compress.cpp:95
const_iterator begin() const
Definition compress.cpp:62
int size() const
Definition compress.cpp:89
const int * const_iterator
Definition compress.cpp:47
#define QLALR_NO_CHECK_SORTED_TABLE
Definition compress.cpp:14
bool operator()(int a, int b) const
Definition compress.cpp:18
_GenerateCheck(QList< int >::const_iterator it, int i)
Definition compress.cpp:35
QList< int >::const_iterator iterator
Definition compress.cpp:32
bool operator()(int a, int b) const
Definition compress.cpp:26
bool operator()(const UncompressedRow &a, const UncompressedRow &b) const
Definition compress.cpp:114