diff options
author | Thomas Hallgren | 2010-03-11 07:13:52 +0000 |
---|---|---|
committer | Thomas Hallgren | 2010-03-11 07:13:52 +0000 |
commit | 02fc7705e3fdbdf55bccae8cf6026be44caa7c71 (patch) | |
tree | 6317dbc8bd8ef49a8e7035d4f2cb1ac5fda26eaa /bundles/org.eclipse.equinox.p2.metadata/src | |
parent | 3626278870d76d9f46feebcf478c2a5e318fe284 (diff) | |
download | rt.equinox.p2-02fc7705e3fdbdf55bccae8cf6026be44caa7c71.tar.gz rt.equinox.p2-02fc7705e3fdbdf55bccae8cf6026be44caa7c71.tar.xz rt.equinox.p2-02fc7705e3fdbdf55bccae8cf6026be44caa7c71.zip |
*** empty log message ***
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.metadata/src')
2 files changed, 90 insertions, 34 deletions
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/QueryResult.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/QueryResult.java index 440f742af..1379e6359 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/QueryResult.java +++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/QueryResult.java @@ -21,10 +21,24 @@ import org.eclipse.equinox.p2.query.*; */ public class QueryResult<T> implements IQueryResult<T> { - private final IRepeatableIterator<T> iterator; + private Iterator<T> iterator; + private boolean firstUsed = false; public QueryResult(Iterator<T> iterator) { - this.iterator = RepeatableIterator.create(iterator); + this.iterator = (iterator instanceof IRepeatableIterator<?>) ? iterator : RepeatableIterator.create(iterator); + } + + /** + * Create an QueryResult based on the given iterator. The <code>oneShot</code> parameter + * can be set to <code>true</code> if the returned instance is expected to be perused + * only once. This will allow some optimizations since the result of the iteration doesn't + * need to be copied in preparation for a second iteration. + * + * @param iterator The iterator to use as the result iterator. + * @param oneShot True if the created instance is perused only once. + */ + public QueryResult(Iterator<T> iterator, boolean oneShot) { + this.iterator = oneShot ? iterator : ((iterator instanceof IRepeatableIterator<?>) ? iterator : RepeatableIterator.create(iterator)); } public QueryResult(Collection<T> collection) { @@ -36,38 +50,69 @@ public class QueryResult<T> implements IQueryResult<T> { } public Iterator<T> iterator() { - return iterator.getCopy(); + if (firstUsed) { + if (iterator instanceof RepeatableIterator<?>) + return ((RepeatableIterator<T>) iterator).getCopy(); + throw new IllegalStateException("The one shot iterator has been used"); //$NON-NLS-1$ + } + firstUsed = true; + return iterator; } @SuppressWarnings("unchecked") public T[] toArray(Class<T> clazz) { - Object provider = iterator.getIteratorProvider(); - if (provider.getClass().isArray()) - return (T[]) provider; + if (iterator instanceof IRepeatableIterator<?>) { + Object provider = ((RepeatableIterator<T>) iterator).getIteratorProvider(); + if (provider.getClass().isArray()) + return (T[]) provider; - if (provider instanceof Collector<?>) - return ((Collector<T>) provider).toArray(clazz); + if (provider instanceof Collector<?>) + return ((Collector<T>) provider).toArray(clazz); - Collection<T> c = (Collection<T>) provider; + Collection<T> c = (Collection<T>) provider; + return c.toArray((T[]) Array.newInstance(clazz, c.size())); + } + + // Build a collection from the current iterator and then use + // that as the provider, should an iterator be queried after + // this call. + Iterator<T> iter = iterator(); + ArrayList<T> c = new ArrayList<T>(); + while (iter.hasNext()) + c.add(iter.next()); + iterator = RepeatableIterator.create(c); + firstUsed = false; return c.toArray((T[]) Array.newInstance(clazz, c.size())); } @SuppressWarnings("unchecked") public Set<T> toSet() { - Object provider = iterator.getIteratorProvider(); - if (provider.getClass().isArray()) { - T[] elems = (T[]) provider; - int idx = elems.length; - HashSet<T> copy = new HashSet<T>(idx); - while (--idx >= 0) - copy.add(elems[idx]); - return copy; + if (iterator instanceof IRepeatableIterator<?>) { + Object provider = ((RepeatableIterator<T>) iterator).getIteratorProvider(); + if (provider.getClass().isArray()) { + T[] elems = (T[]) provider; + int idx = elems.length; + HashSet<T> copy = new HashSet<T>(idx); + while (--idx >= 0) + copy.add(elems[idx]); + return copy; + } + if (provider instanceof Collector<?>) + return ((Collector<T>) provider).toSet(); + if (provider instanceof Map<?, ?>) + return new HashSet<T>((Set<T>) ((Map<?, ?>) provider).entrySet()); + return new HashSet<T>((Collection<T>) provider); } - if (provider instanceof Collector<?>) - return ((Collector<T>) provider).toSet(); - if (provider instanceof Map<?, ?>) - return new HashSet<T>((Set<T>) ((Map<?, ?>) provider).entrySet()); - return new HashSet<T>((Collection<T>) provider); + // Build a collection from the current iterator and then use + // that as the provider, should an iterator be queried after + // this call. + Iterator<T> iter = iterator(); + HashSet<T> c = new HashSet<T>(); + while (iter.hasNext()) + c.add(iter.next()); + iterator = RepeatableIterator.create(c); + firstUsed = false; + return c; } public IQueryResult<T> query(IQuery<T> query, IProgressMonitor monitor) { @@ -76,16 +121,17 @@ public class QueryResult<T> implements IQueryResult<T> { @SuppressWarnings("unchecked") public Set<T> toUnmodifiableSet() { - Object provider = iterator.getIteratorProvider(); - if (provider instanceof Collector<?>) - return ((Collector<T>) provider).toUnmodifiableSet(); - - if (provider instanceof Set<?>) - return Collections.unmodifiableSet((Set<T>) provider); + if (iterator instanceof IRepeatableIterator<?>) { + Object provider = ((RepeatableIterator<T>) iterator).getIteratorProvider(); + if (provider instanceof Collector<?>) + return ((Collector<T>) provider).toUnmodifiableSet(); - if (provider instanceof Map<?, ?>) - return Collections.unmodifiableSet((Set<T>) ((Map<?, ?>) provider).entrySet()); + if (provider instanceof Set<?>) + return Collections.unmodifiableSet((Set<T>) provider); + if (provider instanceof Map<?, ?>) + return Collections.unmodifiableSet((Set<T>) ((Map<?, ?>) provider).entrySet()); + } return toSet(); } } diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/ExpressionMatchQuery.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/ExpressionMatchQuery.java index 1b0284165..dc9fa299d 100644 --- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/ExpressionMatchQuery.java +++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/p2/query/ExpressionMatchQuery.java @@ -11,8 +11,7 @@ package org.eclipse.equinox.p2.query; import java.util.*; -import org.eclipse.equinox.internal.p2.metadata.expression.Expression; -import org.eclipse.equinox.internal.p2.metadata.expression.ExpressionFactory; +import org.eclipse.equinox.internal.p2.metadata.expression.*; import org.eclipse.equinox.p2.metadata.expression.*; import org.eclipse.equinox.p2.metadata.index.*; @@ -28,8 +27,13 @@ public class ExpressionMatchQuery<T> implements IMatchQuery<T>, IQueryWithIndex< public ExpressionMatchQuery(Class<? extends T> matchingClass, IExpression expression, Object... parameters) { this.matchingClass = matchingClass; - this.expression = ExpressionUtil.getFactory().<T> matchExpression(expression, parameters); - this.context = this.expression.createContext(); + if (expression == ExpressionUtil.TRUE_EXPRESSION) { + this.expression = null; + this.context = null; + } else { + this.expression = ExpressionUtil.getFactory().<T> matchExpression(expression, parameters); + this.context = this.expression.createContext(); + } this.indexedMembers = Expression.getIndexCandidateMembers(matchingClass, ExpressionFactory.THIS, (Expression) expression); } @@ -46,6 +50,9 @@ public class ExpressionMatchQuery<T> implements IMatchQuery<T>, IQueryWithIndex< } public IQueryResult<T> perform(IIndexProvider<T> indexProvider) { + if (expression == null) + return new QueryResult<T>(indexProvider.everything()); + Iterator<T> iterator = null; int top = indexedMembers.size(); for (int idx = 0; idx < top; ++idx) { @@ -63,6 +70,9 @@ public class ExpressionMatchQuery<T> implements IMatchQuery<T>, IQueryWithIndex< } public IQueryResult<T> perform(Iterator<T> iterator) { + if (expression == null) + return new QueryResult<T>(iterator); + HashSet<T> result = null; while (iterator.hasNext()) { T value = iterator.next(); |