Преглед на файлове

Увеличена dbVersion

Book Pauk преди 2 години
родител
ревизия
04f0b17d32
променени са 2 файла, в които са добавени 102 реда и са изтрити 4 реда
  1. 1 1
      server/config/base.js
  2. 101 3
      server/core/DbCreator.js

+ 1 - 1
server/config/base.js

@@ -17,7 +17,7 @@ module.exports = {
 
     //поправить в случае, если были критические изменения в DbCreator
     //иначе будет рассинхронизация между сервером и клиентом на уровне БД
-    dbVersion: '3',
+    dbVersion: '4',
     dbCacheSize: 5,
 
     maxPayloadSize: 500,//in MB

+ 101 - 3
server/core/DbCreator.js

@@ -357,7 +357,7 @@ class DbCreator {
             parseField(rec.series, seriesMap, seriesArr, authorIds, rec.id);
 
             //названия
-            parseField(rec.title, titleMap, titleArr, authorIds);
+            parseField(rec.title, titleMap, titleArr, authorIds, rec.id);
 
             //жанры
             let genre = rec.genre || emptyFieldValue;
@@ -533,7 +533,7 @@ class DbCreator {
 
         //title
         callback({job: 'title save', jobMessage: 'Сохранение индекса названий', jobStep: 8, progress: 0});
-        await saveTable('title', titleArr, () => {titleArr = null}, true);
+        await saveTable('title', titleArr, () => {titleArr = null}, true, true);
 
         //genre
         callback({job: 'genre save', jobMessage: 'Сохранение индекса жанров', jobStep: 9, progress: 0});
@@ -557,7 +557,16 @@ class DbCreator {
         });
 
         callback({job: 'optimization', jobMessage: 'Оптимизация', jobStep: 11, progress: 0});
-        await this.optimizeSeries(db, callback);
+        await this.optimizeSeries(db, (p) => {
+            if (p.progress)
+                p.progress = 0.5*p.progress;
+            callback(p);
+        });
+        await this.optimizeTitle(db, (p) => {
+            if (p.progress)
+                p.progress = 0.5*(1 + p.progress);
+            callback(p);
+        });
 
         callback({job: 'stats count', jobMessage: 'Подсчет статистики', jobStep: 12, progress: 0});
         await this.countStats(db, callback, stats);
@@ -672,6 +681,95 @@ class DbCreator {
         await db.close({table: 'series'});
     }
 
+    async optimizeTitle(db, callback) {
+        //оптимизация title, превращаем массив bookId в books, кладем все в title_book
+        await db.open({table: 'title'});
+
+        await db.create({
+            table: 'title_book',
+            flag: {name: 'toDel', check: 'r => r.toDel'},
+        });
+
+        const saveTitleChunk = async(titleChunk) => {
+            const ids = [];
+            for (const s of titleChunk) {
+                for (const id of s.bookId) {
+                    ids.push(id);
+                }
+            }
+
+            ids.sort((a, b) => a - b);// обязательно, иначе будет тормозить - особенности JembaDb
+
+            const rows = await db.select({table: 'book', where: `@@id(${db.esc(ids)})`});
+
+            const bookArr = new Map();
+            for (const row of rows)
+                bookArr.set(row.id, row);
+
+            for (const s of titleChunk) {
+                s.books = [];
+                s.bookCount = 0;
+                s.bookDelCount = 0;
+                for (const id of s.bookId) {
+                    const rec = bookArr.get(id);
+                    if (rec) {//на всякий случай
+                        s.books.push(rec);
+                        if (!rec.del)
+                            s.bookCount++;
+                        else
+                            s.bookDelCount++;
+                    }
+                }
+
+                if (s.books.length) {
+                    s.series = s.books[0].series;
+                } else {
+                    s.toDel = 1;
+                }
+
+                delete s.authorId;
+                delete s.bookId;
+            }
+
+            await db.insert({
+                table: 'title_book',
+                rows: titleChunk,
+            });
+        };
+
+        const rows = await db.select({table: 'title'});
+
+        let idsLen = 0;
+        let chunk = [];
+        let processed = 0;
+        for (const row of rows) {// eslint-disable-line
+            chunk.push(row);
+            idsLen += row.bookId.length;
+            processed++;
+
+            if (idsLen > 20000) {//константа выяснена эмпирическим путем "память/скорость"
+                await saveTitleChunk(chunk);
+
+                idsLen = 0;
+                chunk = [];
+
+                callback({progress: processed/rows.length});
+
+                await utils.sleep(100);
+                utils.freeMemory();
+                await db.freeMemory();
+            }
+        }
+        if (chunk.length) {
+            await saveTitleChunk(chunk);
+            chunk = null;
+        }
+
+        await db.delete({table: 'title_book', where: `@@flag('toDel')`});
+        await db.close({table: 'title_book'});
+        await db.close({table: 'title'});
+    }
+
     async countStats(db, callback, stats) {
         //статистика по количеству файлов