From 383fe50c7f8371f4c1ed7c6fceef45ebbd61f89a Mon Sep 17 00:00:00 2001 From: ggurdin <46800240+ggurdin@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:13:12 -0500 Subject: [PATCH] fix: cache boolean for whether or not meaning distractors are available (#1509) --- .../lemma_meaning_activity_generator.dart | 49 ++++++++++++++----- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/lib/pangea/toolbar/repo/lemma_meaning_activity_generator.dart b/lib/pangea/toolbar/repo/lemma_meaning_activity_generator.dart index d289c522c..b29c163c7 100644 --- a/lib/pangea/toolbar/repo/lemma_meaning_activity_generator.dart +++ b/lib/pangea/toolbar/repo/lemma_meaning_activity_generator.dart @@ -1,7 +1,9 @@ +import 'dart:async'; + import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:fluffychat/pangea/analytics/enums/construct_type_enum.dart'; -import 'package:fluffychat/pangea/analytics/models/constructs_model.dart'; +import 'package:fluffychat/pangea/analytics/models/construct_use_model.dart'; import 'package:fluffychat/pangea/analytics/repo/lemma_info_repo.dart'; import 'package:fluffychat/pangea/analytics/repo/lemma_info_request.dart'; import 'package:fluffychat/pangea/analytics/repo/lemma_info_response.dart'; @@ -12,6 +14,10 @@ import 'package:fluffychat/pangea/toolbar/models/practice_activity_model.dart'; import 'package:fluffychat/widgets/matrix.dart'; class LemmaMeaningActivityGenerator { + /// Cache whether a lemma has distractors for a given part of speech + static final Map _hasDistractorsCache = {}; + static Timer? _cacheClearTimer; + Future get( MessageActivityRequest req, ) async { @@ -57,15 +63,25 @@ class LemmaMeaningActivityGenerator { ); } - static List eligibleDistractors(String lemma, String pos) { - return MatrixState.pangeaController.getAnalytics.constructListModel.uses - .where( - (c) => - c.lemma.toLowerCase() != lemma.toLowerCase() && - c.category.toLowerCase() == pos.toLowerCase() && - c.constructType == ConstructTypeEnum.vocab, - ) - .toList(); + static List eligibleDistractors(String lemma, String pos) { + final distractors = + MatrixState.pangeaController.getAnalytics.constructListModel + .constructList(type: ConstructTypeEnum.vocab) + .where( + (c) => + c.lemma.toLowerCase() != lemma.toLowerCase() && + c.category.toLowerCase() == pos.toLowerCase(), + ) + .toList(); + + _hasDistractorsCache['${lemma.toLowerCase()}-${pos.toLowerCase()}'] = + distractors.isNotEmpty; + + _cacheClearTimer ??= Timer.periodic(const Duration(minutes: 2), (Timer t) { + _hasDistractorsCache.clear(); + }); + + return distractors; } /// From the cache, get a random set of cached definitions that are not for a specific lemma @@ -76,7 +92,7 @@ class LemmaMeaningActivityGenerator { final eligible = eligibleDistractors(req.lemma, req.partOfSpeech); eligible.shuffle(); - final List distractorConstructUses = + final List distractorConstructUses = eligible.take(count).toList(); final List> futureDefs = []; @@ -101,6 +117,13 @@ class LemmaMeaningActivityGenerator { return distractorDefs.toList(); } - static bool canGenerateDistractors(String lemma, String pos) => - eligibleDistractors(lemma, pos).isNotEmpty; + static bool canGenerateDistractors(String lemma, String pos) { + final cacheKey = '${lemma.toLowerCase()}-${pos.toLowerCase()}'; + if (_hasDistractorsCache.containsKey(cacheKey)) { + return _hasDistractorsCache[cacheKey]!; + } + + final distractors = eligibleDistractors(lemma, pos); + return distractors.isNotEmpty; + } }