1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-06 09:16:02 +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.
Collection<Option> ourOpts = getOptionCollection(); /**
if (options != null) { * This method returns an intermediate object, ultimately used by {@link #getOptions()}.
for (Option ourOpt : ourOpts) { *
int j = options.length; * NOTE: The keys in the returned map are only used to efficiently override the values as this method
if (ourOpt.getSuperClass() != null) { * is invoked recursively. Once the recursion unwinds, the keys in the resulting map are a mixture of
String matchId = ourOpt.getSuperClass().getId(); * actual option IDs and option superClass IDs. So the keys of the resulting map should not be relied
search: * upon - only the values hold significance at this point.
for (j = 0; j < options.length; j++) { */
IOption superHolderOption = options[j]; private Map<String,IOption> doGetOptions() {
if (((Option)superHolderOption).wasOptRef()) { Map<String,IOption> map = null;
superHolderOption = superHolderOption.getSuperClass();
} if(this.superClass == null) {
while (superHolderOption != null) { map = new LinkedHashMap<String,IOption>(); // LinkedHashMap ensures we maintain option ordering
if (matchId.equals(superHolderOption.getId())) {
options[j] = ourOpt; for(Option ourOpt : getOptionCollection()) {
break search; if(ourOpt.isValid()) {
} map.put(ourOpt.getId(), ourOpt);
superHolderOption = superHolderOption.getSuperClass();
} }
} }
} }
// No Match? Add it. else {
if (j == options.length) {
IOption[] newOptions = new IOption[options.length + 1]; // 1. Get the option-map from superClass.
for (int k = 0; k < options.length; k++) { map = ((HoldsOptions)this.superClass).doGetOptions();
newOptions[k] = options[k];
} // 2. Override the superClass' options with ours, maintaining the option ordering
newOptions[j] = ourOpt; for(Option ourOpt : getOptionCollection()) {
options = newOptions; String key = ourOpt.getId();
for(IOption superOpt = ourOpt.getSuperClass(); superOpt != null; superOpt = superOpt.getSuperClass()) {
if(map.containsKey(superOpt.getId())) {
key = superOpt.getId();
break;
} }
} }
} else {
options = ourOpts.toArray(new IOption[ourOpts.size()]); if(ourOpt.isValid()) {
map.put(key, ourOpt);
} }
// Check for any invalid options. else {
int numInvalidOptions = 0; map.remove(key);
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 map;
}
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;
} }
option = option.getSuperClass();
} while (option != 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;
}
}
}
// 3. If not found in step 2, recurse into superClass.
if(this.superClass != null) {
return this.superClass.getOptionBySuperClassId(optionId);
} }
return null; return null;