1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 01:36:01 +02:00

Bug 405643 - [performance] HoldsOptions performance improvements

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>
This commit is contained in:
bbelyavsky 2013-04-16 10:00:46 -04:00 committed by Andrew Gvozdev
parent 81627b721e
commit 329251bdc0

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Symbian Ltd - Initial API and implementation * Symbian Ltd - Initial API and implementation
* Baltasar Belyavsky (Texas Instruments) - [405643] HoldsOptions performance improvements
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.managedbuilder.internal.core; package org.eclipse.cdt.managedbuilder.internal.core;
@ -260,67 +261,56 @@ public abstract class HoldsOptions extends BuildObject implements IHoldsOptions,
*/ */
@Override @Override
public IOption[] getOptions() { public IOption[] getOptions() {
IOption[] options = null; Collection<IOption> opts = doGetOptions().values();
// Merge our options with our superclass' options. return opts.toArray(new IOption[opts.size()]);
if (superClass != null) { }
options = superClass.getOptions();
} /**
// Our options take precedence. * This method returns an intermediate object, ultimately used by {@link #getOptions()}.
Collection<Option> ourOpts = getOptionCollection(); *
if (options != null) { * NOTE: The keys in the returned map are only used to efficiently override the values as this method
for (Option ourOpt : ourOpts) { * is invoked recursively. Once the recursion unwinds, the keys in the resulting map are a mixture of
int j = options.length; * actual option IDs and option superClass IDs. So the keys of the resulting map should not be relied
if (ourOpt.getSuperClass() != null) { * upon - only the values hold significance at this point.
String matchId = ourOpt.getSuperClass().getId(); */
search: private Map<String,IOption> doGetOptions() {
for (j = 0; j < options.length; j++) { Map<String,IOption> map = null;
IOption superHolderOption = options[j];
if (((Option)superHolderOption).wasOptRef()) { if(this.superClass == null) {
superHolderOption = superHolderOption.getSuperClass(); map = new LinkedHashMap<String,IOption>(); // LinkedHashMap ensures we maintain option ordering
}
while (superHolderOption != null) { for(Option ourOpt : getOptionCollection()) {
if (matchId.equals(superHolderOption.getId())) { if(ourOpt.isValid()) {
options[j] = ourOpt; map.put(ourOpt.getId(), ourOpt);
break search;
}
superHolderOption = superHolderOption.getSuperClass();
}
}
} }
// No Match? Add it. }
if (j == options.length) { }
IOption[] newOptions = new IOption[options.length + 1]; else {
for (int k = 0; k < options.length; k++) {
newOptions[k] = options[k]; // 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;
} }
newOptions[j] = ourOpt; }
options = newOptions;
if(ourOpt.isValid()) {
map.put(key, ourOpt);
}
else {
map.remove(key);
} }
} }
} else {
options = ourOpts.toArray(new IOption[ourOpts.size()]);
} }
// Check for any invalid options.
int numInvalidOptions = 0; return map;
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++;
}
}
options = newOptions;
}
return options;
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -353,16 +343,25 @@ public abstract class HoldsOptions extends BuildObject implements IHoldsOptions,
public IOption getOptionBySuperClassId(String optionId) { public IOption getOptionBySuperClassId(String optionId) {
if (optionId == null) return null; if (optionId == null) return null;
// Look for an option with this ID, or an option with a superclass with this id // 1. Try a quick look-up - at first iteration in the recursion, this will yield nothing, but once
IOption[] options = getOptions(); // we go into recursion (step 3), this look-up would efficiently find non-overridden options.
for (IOption targetOption : options) { IOption option = getOptionMap().get(optionId);
IOption option = targetOption; if(option != null) {
do { return option;
if (optionId.equals(option.getId())) { }
return targetOption.isValid() ? targetOption : null;
// 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;
} }
option = option.getSuperClass(); }
} while (option != null); }
// 3. If not found in step 2, recurse into superClass.
if(this.superClass != null) {
return this.superClass.getOptionBySuperClassId(optionId);
} }
return null; return null;