summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbbelyavsky2013-04-16 10:00:46 (EDT)
committerAndrew Gvozdev2013-05-17 14:21:03 (EDT)
commit329251bdc0d6b42c3e87bc866fb1d8a15d026ff7 (patch)
treedac94f04fc7b544a277034b63ecf6b06d3f7d646
parent81627b721e74f71dd23606c7392232922756ffe1 (diff)
downloadorg.eclipse.cdt-329251bdc0d6b42c3e87bc866fb1d8a15d026ff7.zip
org.eclipse.cdt-329251bdc0d6b42c3e87bc866fb1d8a15d026ff7.tar.gz
org.eclipse.cdt-329251bdc0d6b42c3e87bc866fb1d8a15d026ff7.tar.bz2
Bug 405643 - [performance] HoldsOptions performance improvementsrefs/changes/36/11936/4
Change-Id: I10bc345821ad5d44a035a7dd46ac5837a0e5bbdb Reviewed-on: https://git.eclipse.org/r/11936 Reviewed-by: Andrew Gvozdev <angvoz.dev@gmail.com> IP-Clean: Andrew Gvozdev <angvoz.dev@gmail.com> Tested-by: Andrew Gvozdev <angvoz.dev@gmail.com>
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HoldsOptions.java133
1 files changed, 66 insertions, 67 deletions
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HoldsOptions.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HoldsOptions.java
index c7bd60b..283d54e 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HoldsOptions.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HoldsOptions.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Symbian Ltd - Initial API and implementation
+ * Baltasar Belyavsky (Texas Instruments) - [405643] HoldsOptions performance improvements
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.internal.core;
@@ -260,69 +261,58 @@ public abstract class HoldsOptions extends BuildObject implements IHoldsOptions,
*/
@Override
public IOption[] getOptions() {
- IOption[] options = null;
- // Merge our options with our superclass' options.
- if (superClass != null) {
- options = superClass.getOptions();
- }
- // Our options take precedence.
- Collection<Option> ourOpts = getOptionCollection();
- if (options != null) {
- for (Option ourOpt : ourOpts) {
- int j = options.length;
- if (ourOpt.getSuperClass() != null) {
- String matchId = ourOpt.getSuperClass().getId();
- search:
- for (j = 0; j < options.length; j++) {
- IOption superHolderOption = options[j];
- if (((Option)superHolderOption).wasOptRef()) {
- superHolderOption = superHolderOption.getSuperClass();
- }
- while (superHolderOption != null) {
- if (matchId.equals(superHolderOption.getId())) {
- options[j] = ourOpt;
- break search;
- }
- superHolderOption = superHolderOption.getSuperClass();
- }
- }
- }
- // No Match? Add it.
- if (j == options.length) {
- IOption[] newOptions = new IOption[options.length + 1];
- for (int k = 0; k < options.length; k++) {
- newOptions[k] = options[k];
- }
- newOptions[j] = ourOpt;
- options = newOptions;
+ Collection<IOption> opts = doGetOptions().values();
+ return opts.toArray(new IOption[opts.size()]);
+ }
+
+ /**
+ * This method returns an intermediate object, ultimately used by {@link #getOptions()}.
+ *
+ * NOTE: The keys in the returned map are only used to efficiently override the values as this method
+ * is invoked recursively. Once the recursion unwinds, the keys in the resulting map are a mixture of
+ * actual option IDs and option superClass IDs. So the keys of the resulting map should not be relied
+ * upon - only the values hold significance at this point.
+ */
+ private Map<String,IOption> doGetOptions() {
+ Map<String,IOption> map = null;
+
+ if(this.superClass == null) {
+ map = new LinkedHashMap<String,IOption>(); // LinkedHashMap ensures we maintain option ordering
+
+ for(Option ourOpt : getOptionCollection()) {
+ if(ourOpt.isValid()) {
+ map.put(ourOpt.getId(), ourOpt);
}
}
- } else {
- options = ourOpts.toArray(new IOption[ourOpts.size()]);
- }
- // Check for any invalid options.
- int numInvalidOptions = 0;
- int i;
- for (i=0; i < options.length; i++) {
- if (options[i].isValid() == false) {
- numInvalidOptions++;
- }
}
- // Take invalid options out of the array, if there are any
- if (numInvalidOptions > 0) {
- int j = 0;
- IOption[] newOptions = new IOption[options.length - numInvalidOptions];
- for (i=0; i < options.length; i++) {
- if (options[i].isValid() == true) {
- newOptions[j] = options[i];
- j++;
+ else {
+
+ // 1. Get the option-map from superClass.
+ map = ((HoldsOptions)this.superClass).doGetOptions();
+
+ // 2. Override the superClass' options with ours, maintaining the option ordering
+ for(Option ourOpt : getOptionCollection()) {
+ String key = ourOpt.getId();
+
+ for(IOption superOpt = ourOpt.getSuperClass(); superOpt != null; superOpt = superOpt.getSuperClass()) {
+ if(map.containsKey(superOpt.getId())) {
+ key = superOpt.getId();
+ break;
+ }
+ }
+
+ if(ourOpt.isValid()) {
+ map.put(key, ourOpt);
+ }
+ else {
+ map.remove(key);
}
}
- options = newOptions;
}
- return options;
+
+ return map;
}
-
+
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getOption(java.lang.String)
*/
@@ -353,21 +343,30 @@ public abstract class HoldsOptions extends BuildObject implements IHoldsOptions,
public IOption getOptionBySuperClassId(String optionId) {
if (optionId == null) return null;
- // Look for an option with this ID, or an option with a superclass with this id
- IOption[] options = getOptions();
- for (IOption targetOption : options) {
- IOption option = targetOption;
- do {
- if (optionId.equals(option.getId())) {
- return targetOption.isValid() ? targetOption : null;
- }
- option = option.getSuperClass();
- } while (option != null);
+ // 1. Try a quick look-up - at first iteration in the recursion, this will yield nothing, but once
+ // we go into recursion (step 3), this look-up would efficiently find non-overridden options.
+ IOption option = getOptionMap().get(optionId);
+ if(option != null) {
+ return option;
}
+ // 2. Try to find the option among those that we override.
+ for(Option ourOpt : getOptionCollection()) {
+ for(IOption superOpt = ourOpt.getSuperClass(); superOpt != null; superOpt = superOpt.getSuperClass()) {
+ if(optionId.equals(superOpt.getId())) {
+ return ourOpt.isValid()? ourOpt: null;
+ }
+ }
+ }
+
+ // 3. If not found in step 2, recurse into superClass.
+ if(this.superClass != null) {
+ return this.superClass.getOptionBySuperClassId(optionId);
+ }
+
return null;
}
-
+
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IHoldsOptions#getChildCategories()
*/