From 8975bfdb999983c1554d8db65b68d291946a53e1 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Sat, 9 Sep 2017 16:11:05 -0700 Subject: [PATCH 1/3] Precompute Pi, and do not store documentation on access. --- .../org/nwapw/abacus/plugin/PluginManager.java | 14 ++------------ .../java/org/nwapw/abacus/fx/AbacusController.java | 7 ++++++- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/org/nwapw/abacus/plugin/PluginManager.java b/core/src/main/java/org/nwapw/abacus/plugin/PluginManager.java index 3d4f384..27404d4 100644 --- a/core/src/main/java/org/nwapw/abacus/plugin/PluginManager.java +++ b/core/src/main/java/org/nwapw/abacus/plugin/PluginManager.java @@ -141,6 +141,7 @@ public class PluginManager { registeredNumberImplementations.put(name, implementation); interfaceImplementationNames.put(implementation.getImplementation(), name); interfaceImplementations.put(implementation.getImplementation(), implementation); + cachedPi.put(implementation.getImplementation(), implementation.instanceForPi()); } /** @@ -218,10 +219,6 @@ public class PluginManager { break; } } - if (toReturn == null) { - toReturn = new Documentation(name, "", "", "", type); - registerDocumentation(toReturn); - } return toReturn; } @@ -252,14 +249,7 @@ public class PluginManager { * @return pi */ public NumberInterface piFor(Class forClass) { - if (cachedPi.containsKey(forClass)) return cachedPi.get(forClass); - NumberImplementation implementation = interfaceImplementationFor(forClass); - NumberInterface generatedPi = null; - if (implementation != null) { - generatedPi = implementation.instanceForPi(); - } - cachedPi.put(forClass, generatedPi); - return generatedPi; + return cachedPi.get(forClass); } /** diff --git a/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java b/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java index 5f23a9a..15c75b8 100644 --- a/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java +++ b/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -363,7 +363,12 @@ public class AbacusController implements PluginListener { enabledPlugins.add(plugin); } PluginManager pluginManager = abacus.getPluginManager(); - functionList.addAll(manager.getAllFunctions().stream().map(name -> pluginManager.documentationFor(name, DocumentationType.FUNCTION)) + functionList.addAll(manager.getAllFunctions().stream().map(name -> { + Documentation documentationInstance = pluginManager.documentationFor(name, DocumentationType.FUNCTION); + if(documentationInstance == null) + documentationInstance = new Documentation(name, "", "", "", DocumentationType.FUNCTION); + return documentationInstance; + }) .collect(Collectors.toCollection(ArrayList::new))); functionList.addAll(manager.getAllTreeValueFunctions().stream().map(name -> pluginManager.documentationFor(name, DocumentationType.TREE_VALUE_FUNCTION)) .collect(Collectors.toCollection(ArrayList::new))); From 7cd117dac1f440f04767a1502b5db2ce5232a45f Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Sun, 10 Sep 2017 20:17:49 -0700 Subject: [PATCH 2/3] Add synchronization to the Standard plugin. --- core/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java b/core/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java index e144bbc..b3b16f0 100755 --- a/core/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java +++ b/core/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java @@ -696,8 +696,7 @@ public class StandardPlugin extends Plugin { * @param n non-negative integer. * @return a number of numClass with value n factorial. */ - public static NumberInterface factorial(NumberImplementation implementation, int n) { - + synchronized public static NumberInterface factorial(NumberImplementation implementation, int n) { if (!FACTORIAL_LISTS.containsKey(implementation)) { FACTORIAL_LISTS.put(implementation, new ArrayList<>()); FACTORIAL_LISTS.get(implementation).add(implementation.instanceForString("1")); From 87529da15f6039bdf179fe9f95b2a0629c0834bb Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Mon, 11 Sep 2017 18:55:59 -0700 Subject: [PATCH 3/3] Precompute all the transitions ahead of time. --- .../nwapw/abacus/number/PromotionManager.kt | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/core/src/main/kotlin/org/nwapw/abacus/number/PromotionManager.kt b/core/src/main/kotlin/org/nwapw/abacus/number/PromotionManager.kt index 421d642..a49a61c 100644 --- a/core/src/main/kotlin/org/nwapw/abacus/number/PromotionManager.kt +++ b/core/src/main/kotlin/org/nwapw/abacus/number/PromotionManager.kt @@ -37,21 +37,6 @@ class PromotionManager(val abacus: Abacus) : PluginListener { return null } - /** - * If a path between the given implementations has already been computed, uses - * the already calculated path. Otherwise, calls [computePathBetween] to compute a new - * path. - * - * @param from the implementation to start from. - * @param to the implementation to get to. - * @return the resulting promotion path, or null if it is not found - */ - fun getPathBetween(from: NumberImplementation, to: NumberImplementation): PromotionPath? { - return computePaths.computeIfAbsent(from to to, { - computePathBetween(it.first, it.second) - }) - } - /** * Promote all the numbers in the list to the same number implementation, to ensure * they can be used with each other. Finds the highest priority implementation @@ -66,16 +51,26 @@ class PromotionManager(val abacus: Abacus) : PluginListener { val highestPriority = implementations.sortedBy { it.priority }.last() return PromotionResult(items = numbers.map { if(it.javaClass == highestPriority.implementation) it - else getPathBetween(pluginManager.interfaceImplementationFor(it.javaClass), highestPriority) + else computePaths[pluginManager.interfaceImplementationFor(it.javaClass) to highestPriority] ?.promote(it) ?: return null }.toTypedArray(), promotedTo = highestPriority) } - override fun onLoad(manager: PluginManager?) { + override fun onLoad(manager: PluginManager) { + val implementations = manager.allNumberImplementations.map { manager.numberImplementationFor(it) } + for((index, value) in implementations.withIndex()){ + for(i in index until implementations.size){ + val other = implementations[i] + val promoteFrom = if(other.priority > value.priority) value else other + val promoteTo = if(other.priority > value.priority) other else value + val path = computePathBetween(promoteFrom, promoteTo) + computePaths.put(promoteFrom to promoteTo, path) + } + } } - override fun onUnload(manager: PluginManager?) { + override fun onUnload(manager: PluginManager) { computePaths.clear() }