Skip to content

Commit

Permalink
fix: isolate for findbook
Browse files Browse the repository at this point in the history
  • Loading branch information
Sivan22 committed Nov 21, 2024
1 parent bae3196 commit e55821c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 35 deletions.
3 changes: 2 additions & 1 deletion lib/data/repository/data_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class DataRepository {
return _isarDataProvider.getNumberOfBooksWithRefs();
}

addAllTextsToMimir(Library library, {int start = 0, int end = 100000}) async {
addAllTextsToTantivy(Library library,
{int start = 0, int end = 100000}) async {
_mimirDataProvider.addAllTBooksToTantivy(library, start: start, end: end);
}
}
76 changes: 43 additions & 33 deletions lib/models/app_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -439,57 +439,54 @@ class AppModel with ChangeNotifier {
Future<List<Book>> findBooks(String query, Category? category,
{List<String>? topics}) async {
final queryWords = query.split(RegExp(r'\s+'));
var books = category?.getAllBooks() ?? (await library).getAllBooks();
var allBooks = category?.getAllBooks() ?? (await library).getAllBooks();
if (showOtzarHachochma.value) {
books += await otzarBooks;
allBooks += await otzarBooks;
}
if (showHebrewBooks.value) {
books += await hebrewBooks;
allBooks += await hebrewBooks;
}

// First filter the books
var filteredBooks = books.where((book) {
// First, filter books outside of isolate to get the working set
var filteredBooks = allBooks.where((book) {
final title = book.title.toLowerCase();
return queryWords.every((word) => title.contains(word));
final bookTopics = book.topics.split(', ');

bool matchesQuery = queryWords.every((word) => title.contains(word));
bool matchesTopics = topics == null ||
topics.isEmpty ||
topics.every((t) => bookTopics.contains(t));

return matchesQuery && matchesTopics;
}).toList();

if (topics != null && topics.isNotEmpty) {
filteredBooks = filteredBooks
.where((book) =>
topics.every((t) => book.topics.split(', ').contains(t)))
.toList();
if (filteredBooks.isEmpty) {
return [];
}

// Create a simple data structure that can be sent to isolate
final searchData =
filteredBooks.asMap().map((index, book) => MapEntry(index, {
'index': index,
// Prepare data for isolate - only send what's needed for sorting
final List<Map<String, dynamic>> sortData = filteredBooks
.asMap()
.map((i, book) => MapEntry(i, {
'index': i,
'title': book.title,
}));

// Sort using isolate with the simplified data
final sortedIndices = await Isolate.run(() {
final entries = searchData.entries.toList();
entries.sort((a, b) {
final scoreA = ratio(query, a.value['title'] as String);
final scoreB = ratio(query, b.value['title'] as String);
return scoreB.compareTo(scoreA);
});
return entries.map((e) => e.value['index'] as int).toList();
});
}))
.values
.toList();

// Reorder the original filtered books based on the sorted indices
final sortedBooks =
sortedIndices.map((index) => filteredBooks[index]).toList();
return sortedBooks;
// Sort indices in isolate
final sortedIndices = getSortedIndices(sortData, query);

// Map sorted indices back to books
return (await sortedIndices).map((index) => filteredBooks[index]).toList();
}

Future<void> createRefsFromLibrary(int startIndex) async {
data.createRefsFromLibrary(await library, startIndex);
}

addAllTextsToMimir({int start = 0, int end = 100000}) async {
data.addAllTextsToMimir(await library, start: start, end: end);
addAllTextsToTantivy({int start = 0, int end = 100000}) async {
data.addAllTextsToTantivy(await library, start: start, end: end);
}

Future<void> refreshLibrary() async {
Expand All @@ -501,3 +498,16 @@ class AppModel with ChangeNotifier {

/// An enum that represents the different screens in the application.
enum Screens { library, find, reading, search, favorites, settings }

Future<List<int>> getSortedIndices(
List<Map<String, dynamic>> data, String query) async {
return await Isolate.run(() {
List<int> indices = List<int>.generate(data.length, (i) => i);
indices.sort((a, b) {
final scoreA = ratio(query, data[a]['title'] as String);
final scoreB = ratio(query, data[b]['title'] as String);
return scoreB.compareTo(scoreA);
});
return indices;
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class FullTextSettingsScreen extends StatelessWidget {
],
));
if (await result == true) {
context.read<AppModel>().addAllTextsToMimir();
context.read<AppModel>().addAllTextsToTantivy();
}
},
child: const Text(
Expand Down

0 comments on commit e55821c

Please sign in to comment.