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 ®ion, 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