1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #ifndef _U2_SQLITE_ASSEMBLY_MULTI_TABLE_DBI_H_
23 #define _U2_SQLITE_ASSEMBLY_MULTI_TABLE_DBI_H_
24 
25 #include <QReadWriteLock>
26 
27 #include <U2Core/U2SqlHelpers.h>
28 
29 #include "SingleTableAssemblyAdapter.h"
30 #include "util/AssemblyPackAlgorithm.h"
31 
32 namespace U2 {
33 
34 class MTASingleTableAdapter {
35 public:
36     /** Wrapper over 1 table in database. If singleTableAdapter == NULL the table was not created yet */
MTASingleTableAdapter(SingleTableAssemblyAdapter * a,int _rowPos,int _elenPos,const QByteArray & extra)37     MTASingleTableAdapter(SingleTableAssemblyAdapter *a, int _rowPos, int _elenPos, const QByteArray &extra)
38         : singleTableAdapter(a), rowPos(_rowPos), elenPos(_elenPos), idExtra(extra) {
39     }
40 
41     SingleTableAssemblyAdapter *singleTableAdapter;
42     int rowPos;
43     int elenPos;
44     QByteArray idExtra;
45 };
46 
47 class MultiTableAssemblyAdapter : public SQLiteAssemblyAdapter {
48 public:
49     MultiTableAssemblyAdapter(SQLiteDbi *dbi, const U2DataId &assemblyId, const AssemblyCompressor *compressor, DbRef *ref, U2OpStatus &os);
50 
51     ~MultiTableAssemblyAdapter();
52 
53     virtual qint64 countReads(const U2Region &r, U2OpStatus &os);
54 
55     virtual qint64 getMaxPackedRow(const U2Region &r, U2OpStatus &os);
56     virtual qint64 getMaxEndPos(U2OpStatus &os);
57 
58     virtual U2DbiIterator<U2AssemblyRead> *getReads(const U2Region &r, U2OpStatus &os, bool sortedHint = false);
59     virtual U2DbiIterator<U2AssemblyRead> *getReadsByRow(const U2Region &r, qint64 minRow, qint64 maxRow, U2OpStatus &os);
60     virtual U2DbiIterator<U2AssemblyRead> *getReadsByName(const QByteArray &name, U2OpStatus &os);
61 
62     virtual void addReads(U2DbiIterator<U2AssemblyRead> *it, U2AssemblyReadsImportInfo &ii, U2OpStatus &os);
63     virtual void removeReads(const QList<U2DataId> &readIds, U2OpStatus &os);
64     virtual void dropReadsTables(U2OpStatus &os);
65 
66     virtual void pack(U2AssemblyPackStat &stat, U2OpStatus &os);
67     virtual void calculateCoverage(const U2Region &region, U2AssemblyCoverageStat &coverage, U2OpStatus &os);
68 
69     virtual void createReadsIndexes(U2OpStatus &os);
70 
71     int getElenRangePosByLength(qint64 readLength) const;
72     int getElenRangePosById(const U2DataId &id) const;
getNumberOfElenRanges()73     int getNumberOfElenRanges() const {
74         return elenRanges.size();
75     }
76 
77     int getRowRangePosByRow(quint64 row) const;
78     int getRowRangePosById(const U2DataId &id) const;
getRowsPerRange()79     int getRowsPerRange() const {
80         return rowsPerRange;
81     }
82 
getAdapters()83     const QVector<MTASingleTableAdapter *> &getAdapters() const {
84         return adapters;
85     }
getIdExtrasPerRange()86     const QVector<QByteArray> &getIdExtrasPerRange() const {
87         return idExtras;
88     }
89 
getDbRef()90     DbRef *getDbRef() const {
91         return dbi->getDbRef();
92     }
93 
94     MTASingleTableAdapter *getAdapterByRowAndElenRange(int rowRange, int elenRange, bool createIfNotExits, U2OpStatus &os);
95 
96 protected:
97     QString getTableSuffix(int rowRange, int elenRange);
98     static QByteArray getIdExtra(int rowRange, int elenRange);
99 
100     void addTableAdapter(int minLen, int maxLen, const U2DataId &assemblyId, const AssemblyCompressor *compressor, bool last, U2OpStatus &os);
101 
102     /** Checks if table info must be re-read from DB and calls re-read if needed */
103     void syncTables(U2OpStatus &os);
104 
105     /** For a new and empty assembly analyzes reads data and calculate ranges */
106     void initTables(const QList<U2AssemblyRead> &reads, U2OpStatus &os);
107 
108     /** Re-reads table info from DB */
109     void rereadTables(const QByteArray &idata, U2OpStatus &os);
110 
111     /** Flushes tables info into database */
112     void flushTables(U2OpStatus &os);
113 
114     void clearTableAdaptersInfo();
115 
116     MTASingleTableAdapter *createAdapter(int rowRange, int elenRange, U2OpStatus &os);
117 
118     void initAdaptersGrid(int nRows, int nRanges);
119 
120     SQLiteDbi *dbi;
121 
122     /** All non-NUL adapters */
123     QVector<MTASingleTableAdapter *> adapters;
124 
125     /** outer dim -> prow, inner dim -> elen */
126     QVector<QVector<MTASingleTableAdapter *>> adaptersGrid;
127 
128     /** id extras for every table, same hierarchy with tableAdapters */
129     QVector<QByteArray> idExtras;
130 
131     /** assembly object version adapters are used for */
132     qint32 version;
133 
134     /** effective length ranges */
135     QVector<U2Region> elenRanges;
136 
137     /** prow range per table */
138     qint32 rowsPerRange;
139 
140     // TODO: add read-locks into all methods
141     QReadWriteLock tablesSyncLock;
142 };
143 
144 class SQLiteReadTableMigrationData {
145 public:
SQLiteReadTableMigrationData()146     SQLiteReadTableMigrationData()
147         : readId(-1), oldTable(nullptr), newProw(-1) {
148     }
SQLiteReadTableMigrationData(qint64 oldId,MTASingleTableAdapter * oldT,int newP)149     SQLiteReadTableMigrationData(qint64 oldId, MTASingleTableAdapter *oldT, int newP)
150         : readId(oldId), oldTable(oldT), newProw(newP) {
151     }
152 
153     qint64 readId;
154     MTASingleTableAdapter *oldTable;
155     int newProw;
156 };
157 
158 class MultiTablePackAlgorithmAdapter : public PackAlgorithmAdapter {
159 public:
160     MultiTablePackAlgorithmAdapter(MultiTableAssemblyAdapter *a);
161     ~MultiTablePackAlgorithmAdapter();
162 
163     virtual U2DbiIterator<PackAlgorithmData> *selectAllReads(U2OpStatus &os);
164     virtual void assignProw(const U2DataId &readId, qint64 prow, U2OpStatus &os);
165 
166     void releaseDbResources();
167     void migrateAll(U2OpStatus &os);
168 
169 private:
170     void ensureGridSize(int nRows);
171     void migrate(MTASingleTableAdapter *newA, const QVector<SQLiteReadTableMigrationData> &data, qint64 migratedBefore, qint64 totalMigrationCount, U2OpStatus &os);
172 
173     MultiTableAssemblyAdapter *multiTableAdapter;
174     QVector<SingleTablePackAlgorithmAdapter *> packAdapters;
175     QVector<QVector<SingleTablePackAlgorithmAdapter *>> packAdaptersGrid;
176     QHash<MTASingleTableAdapter *, QVector<SQLiteReadTableMigrationData>> migrations;
177 };
178 
179 // Class that multiplexes multiple read iterators into 1
180 class MTAReadsIterator : public U2DbiIterator<U2AssemblyRead> {
181 public:
182     MTAReadsIterator(QVector<U2DbiIterator<U2AssemblyRead> *> &iterators, const QVector<QByteArray> &idExtras, bool sortedHint);
183 
184     virtual ~MTAReadsIterator();
185 
186     virtual bool hasNext();
187 
188     virtual U2AssemblyRead next();
189 
190     virtual U2AssemblyRead peek();
191 
192 private:
193     QVector<U2DbiIterator<U2AssemblyRead> *> iterators;
194     int currentRange;
195     QVector<QByteArray> idExtras;
196     bool sortedHint;
197 };
198 
199 // Class that multiplexes multiple read packed data iterators into 1 and supports ordering
200 class MTAPackAlgorithmDataIterator : public U2DbiIterator<PackAlgorithmData> {
201 public:
202     MTAPackAlgorithmDataIterator(QVector<U2DbiIterator<PackAlgorithmData> *> &iterators, const QVector<QByteArray> &idExtras);
203 
204     virtual ~MTAPackAlgorithmDataIterator();
205 
206     virtual bool hasNext();
207 
208     virtual PackAlgorithmData next();
209 
210     virtual PackAlgorithmData peek();
211 
212 private:
213     void fetchNextData();
214 
215     QVector<U2DbiIterator<PackAlgorithmData> *> iterators;
216     PackAlgorithmData nextData;
217     QVector<QByteArray> idExtras;
218 };
219 
220 }  // namespace U2
221 
222 #endif
223