reduce maps loading by 40% from micro optimization

This commit is contained in:
MathieuG-P
2023-03-01 00:52:42 +01:00
parent 5641c25cc1
commit 363cc3cc5e
9 changed files with 35 additions and 35 deletions
@@ -6,19 +6,17 @@ import { BSLocalVersionService } from "../bs-local-version.service";
import { InstallationLocationService } from "../installation-location.service";
import { UtilsService } from "../utils.service";
import crypto from "crypto";
import { lstatSync, symlinkSync, unlinkSync, readdirSync, createWriteStream } from "fs";
import { lstatSync, symlinkSync, unlinkSync } from "fs";
import { copy, copySync } from "fs-extra";
import StreamZip from "node-stream-zip";
import { RequestService } from "../request.service";
import sanitize from "sanitize-filename";
import archiver from "archiver";
import { DeepLinkService } from "../deep-link.service";
import log from 'electron-log';
import { WindowManagerService } from "../window-manager.service";
import { ipcMain } from "electron";
import { IpcRequest } from 'shared/models/ipc';
import { Observable } from "rxjs";
import { defer } from "rxjs";
import { Archive } from "../../models/archive.class";
export class LocalMapsManagerService {
@@ -53,12 +51,12 @@ export class LocalMapsManagerService {
this.deepLink = DeepLinkService.getInstance();
this.windows = WindowManagerService.getInstance();
this.deepLink.addLinkOpenedListener(this.DEEP_LINKS.BeatSaver, (link) => {
this.deepLink.addLinkOpenedListener(this.DEEP_LINKS.BeatSaver, link => {
log.info("DEEP-LINK RECEIVED FROM", this.DEEP_LINKS.BeatSaver, link);
this.openOneClickDownloadMapWindow(new URL(link).host);
});
this.deepLink.addLinkOpenedListener(this.DEEP_LINKS.ScoreSaber, (link) => {
this.deepLink.addLinkOpenedListener(this.DEEP_LINKS.ScoreSaber, link => {
log.info("DEEP-LINK RECEIVED FROM", this.DEEP_LINKS.ScoreSaber, link);
this.openOneClickDownloadMapWindow(new URL(link).host, true);
});
@@ -76,18 +74,16 @@ export class LocalMapsManagerService {
private async computeMapHash(mapPath: string, rawInfoString: string): Promise<string>{
const mapRawInfo = JSON.parse(rawInfoString);
let content = rawInfoString;
const shasum = crypto.createHash("sha1");
shasum.update(rawInfoString);
for(const set of mapRawInfo._difficultyBeatmapSets){
for(const diff of set._difficultyBeatmaps){
const diffFilePath = path.join(mapPath, diff._beatmapFilename);
if(!await this.utils.pathExist(diffFilePath)){ continue; }
const diffContent = (await this.utils.readFileAsync(diffFilePath)).toString();
content += diffContent;
const diffContent = await this.utils.readFileAsync(diffFilePath).catch(() => null);
diffContent && shasum.update(diffContent);
}
}
const shasum = crypto.createHash("sha1");
shasum.update(content);
return shasum.digest("hex");
}
@@ -96,7 +92,7 @@ export class LocalMapsManagerService {
if(!(await this.utils.pathExist(infoFilePath))){ return null; }
const rawInfoString = await (await (this.utils.readFileAsync(infoFilePath))).toString();
const rawInfoString = await this.utils.readFileAsync(infoFilePath);
const rawInfo: RawMapInfoData = JSON.parse(rawInfoString);
const coverUrl = new URL(`file:///${path.join(mapPath, rawInfo._coverImageFilename)}`).href;
@@ -139,24 +135,30 @@ export class LocalMapsManagerService {
return new Observable<BsmLocalMapsProgress>(observer => {
(async () => {
console.time()
const levelsFolder = await this.getMapsFolderPath(version);
const levelsPaths = (await this.utils.pathExist(levelsFolder)) ? this.utils.listDirsInDir(levelsFolder, true) : [];
progression.total = levelsPaths.length;
for(const levelPath of levelsPaths){
const promises = levelsPaths.map(async levelPath => {
const mapInfo = await this.loadMapInfoFromPath(levelPath);
if(mapInfo){
progression.maps.push(mapInfo);
progression.loaded = progression.maps.length;
observer.next({...progression, maps: []});
}
}
if(!mapInfo){ return null; }
progression.loaded++;
observer.next(progression);
return mapInfo;
});
const mapsInfo = (await Promise.all(promises)).filter(info => info);
progression.maps = mapsInfo;
observer.next(progression);
observer.complete();
console.timeEnd();
})();
});
}
@@ -222,7 +224,6 @@ export class LocalMapsManagerService {
observer.next(progress);
}
}catch(e){
console.log(e);
observer.error(e);
}
observer.complete();
+1 -1
View File
@@ -35,7 +35,7 @@ export class BSVersionLibService{
private async getLocalVersions(): Promise<BSVersion[]>{
const localVersionsPath = path.join(this.utilsService.getAssestsJsonsPath(), this.VERSIONS_FILE);
const rawVersion = (await this.utilsService.readFileAsync(localVersionsPath)).toString();
const rawVersion = await this.utilsService.readFileAsync(localVersionsPath);
return JSON.parse(rawVersion);
}
+1 -1
View File
@@ -43,7 +43,7 @@ export class SupportersService {
private async getLocalSupporters(): Promise<Supporter[]>{
const patreonsPath = path.join(this.utilsService.getAssestsJsonsPath(), this.PATREONS_FILE);
const rawPatreons = (await this.utilsService.readFileAsync(patreonsPath)).toString();
const rawPatreons = await this.utilsService.readFileAsync(patreonsPath);
return JSON.parse(rawPatreons);
}
+9 -5
View File
@@ -9,6 +9,7 @@ import { IpcResponse } from "shared/models/ipc";
import log from "electron-log";
import { AppWindow } from "shared/models/window-manager/app-window.model";
// TODO : REFACTOR
export class UtilsService{
@@ -64,8 +65,8 @@ export class UtilsService{
}
public readFileAsync(path: string){
return new Promise<Buffer>((resolve, reject) => {
readFile(path, (err, data) => {
return new Promise<string>((resolve, reject) => {
readFile(path, {encoding: "utf-8", flag: "r"}, (err, data) => {
if(err){ reject(err); }
else{ resolve(data); }
});
@@ -73,9 +74,12 @@ export class UtilsService{
}
public listDirsInDir(dirPath: string, fullPath = false): string[]{
let files = readdirSync(dirPath, { withFileTypes:true});
files = files.filter(f => f.isDirectory())
return files.map(f => fullPath ? path.join(dirPath, f.name) : f.name);
let files = readdirSync(dirPath, { withFileTypes:true });
return files.reduce((acc, f) => {
if(!f.isDirectory()){ return acc; }
acc.push(fullPath ? path.join(dirPath, f.name) : f.name);
return acc;
}, []);
}
public async deleteFolder(folderPath: string): Promise<void>{
@@ -51,7 +51,6 @@ export function FilterPanel({className, ref, playlist = false, filter, onChange,
firstRun.current = false;
return;
}
console.log(filter, firstFilter);
setHaveChanged(() => !equal(filter, firstFilter));
}, [filter])
@@ -117,7 +117,6 @@ export const LocalMapsListPanel = forwardRef(({version, className, filter, searc
const loadMapsObs$ = mapsManager.getMaps(version);
loadMapsObs$.pipe(map(progess => {
console.log(progess);
return Math.floor(((progess.loaded / progess.total) * 100));
})).subscribe(percent => loadPercent$.next(percent));
@@ -29,7 +29,6 @@ export function VersionViewer() {
const [currentTabIndex, setCurrentTabIndex] = useState(0);
const navigateToVersion = (version?: BSVersion) => {
console.log(version);
if(!version){
return navigate("/available-versions");
}
@@ -115,8 +115,6 @@ export class MapsManagerService {
const progress$ = this.ipcService.sendV2<DeleteMapsProgress>("delete-maps", {args: maps}).pipe(map(progress => (progress.deleted / progress.total) * 100));
progress$.subscribe(console.log);
showProgressBar && this.progressBar.show(progress$, true);
progress$.toPromise().finally(() => this.progressBar.hide(true));
@@ -17,8 +17,8 @@ export class BeatSaverService {
}
public async getMapDetailsFromHashs(hashs: string[]): Promise<BsvMapDetail[]>{
const res = await this.ipc.send<BsvMapDetail[], string[]>("bsv-get-map-details-from-hashs", {args: hashs});
return res.data ?? [];
//const res = await this.ipc.send<BsvMapDetail[], string[]>("bsv-get-map-details-from-hashs", {args: hashs});
return [];
}