Cache filters and create an index for objectclass to improve service lookup performance.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@647612 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
index d4457ca..6086e80 100644
--- a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
@@ -35,6 +35,7 @@
**/
public class FilterImpl implements Filter
{
+ private static final WeakHashMap m_programCache = new WeakHashMap();
private final ThreadLocal m_cache = new ThreadLocal();
private final Logger m_logger;
private final Object[] m_program;
@@ -57,29 +58,44 @@
{
throw new InvalidSyntaxException("Filter cannot be null", null);
}
-
- CharArrayReader car = new CharArrayReader(expr.toCharArray());
- LdapLexer lexer = new LdapLexer(car);
- Parser parser = new Parser(lexer);
- try
+ Object[] program = null;
+ synchronized (m_programCache)
{
- if (!parser.start())
+ program = (Object[]) m_programCache.get(expr);
+ }
+ if (program == null)
+ {
+ CharArrayReader car = new CharArrayReader(expr.toCharArray());
+ LdapLexer lexer = new LdapLexer(car);
+ Parser parser = new Parser(lexer);
+ try
+ {
+ if (!parser.start())
+ {
+ throw new InvalidSyntaxException(
+ "Failed to parse LDAP query.", expr);
+ }
+ }
+ catch (ParseException ex)
{
throw new InvalidSyntaxException(
- "Failed to parse LDAP query.", expr);
+ ex.getMessage(), expr);
+ }
+ catch (IOException ex)
+ {
+ throw new InvalidSyntaxException(
+ ex.getMessage(), expr);
+ }
+ program = parser.getProgram();
+ synchronized (m_programCache)
+ {
+ if (!m_programCache.containsKey(expr))
+ {
+ m_programCache.put(expr, program);
+ }
}
}
- catch (ParseException ex)
- {
- throw new InvalidSyntaxException(
- ex.getMessage(), expr);
- }
- catch (IOException ex)
- {
- throw new InvalidSyntaxException(
- ex.getMessage(), expr);
- }
- m_program = parser.getProgram();
+ m_program = program;
}
/**
@@ -254,7 +270,7 @@
public void setSource(Dictionary dict, boolean caseSensitive)
{
// Create a map if we don't have one.
-
+
if (m_map == null)
{
m_map = new StringMap();
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/Parser.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/Parser.java
index 46ff157..1bdc7c1 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/Parser.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/ldap/Parser.java
@@ -257,6 +257,11 @@
switch (kind)
{
case SIMPLE :
+ if ("objectClass".equals(attr.toString()) && (op == '='))
+ {
+ program.add(new ObjectClassOperator((String) pieces.get(0)));
+ return true;
+ }
// Code: Push(attr); Constant(pieces.get(0)); <operator>();
program.add(new PushOperator(attr.toString()));
program.add(new ConstOperator(pieces.get(0)));
@@ -534,8 +539,7 @@
}
// Exclusive inner classes
-
- private static class AndOperator extends Operator
+ private static final class AndOperator extends Operator
{
private int operandCount;
@@ -600,7 +604,7 @@
}
}
- private static class OrOperator extends Operator
+ private static final class OrOperator extends Operator
{
private int operandCount;
@@ -665,7 +669,7 @@
}
}
- private static class NotOperator extends Operator
+ private static final class NotOperator extends Operator
{
public NotOperator()
{
@@ -706,7 +710,50 @@
}
}
- private static class EqualOperator extends Operator
+ private static final class ObjectClassOperator extends Operator
+ {
+ public final String m_target;
+
+ public ObjectClassOperator(String target)
+ {
+ m_target = target;
+ }
+
+ public void buildTree(Stack operands)
+ {
+ operands.push(this);
+ }
+
+ public void execute(Stack operands, Mapper mapper)
+ throws EvaluationException
+ {
+ String[] objectClass = (String[]) mapper.lookup("objectClass");
+ if (objectClass != null)
+ {
+ for (int i = 0; i < objectClass.length; i++)
+ {
+ if (m_target.equals(objectClass[i]))
+ {
+ operands.push(Boolean.TRUE);
+ return;
+ }
+ }
+ }
+ operands.push(Boolean.FALSE);
+ }
+
+ public String toString()
+ {
+ return "=()";
+ }
+
+ public void toStringInfix(StringBuffer b)
+ {
+ b.append('(').append("objectClass=").append(m_target).append(')');
+ }
+ }
+
+ private static final class EqualOperator extends Operator
{
public EqualOperator()
{
@@ -766,7 +813,7 @@
}
}
- private static class GreaterEqualOperator extends Operator
+ private static final class GreaterEqualOperator extends Operator
{
public GreaterEqualOperator()
{
@@ -823,7 +870,7 @@
}
}
- private static class LessEqualOperator extends Operator
+ private static final class LessEqualOperator extends Operator
{
public LessEqualOperator()
{
@@ -879,7 +926,7 @@
}
}
- private static class ApproxOperator extends Operator
+ private static final class ApproxOperator extends Operator
{
public ApproxOperator()
{
@@ -935,7 +982,7 @@
}
}
- private static class PresentOperator extends Operator
+ private static final class PresentOperator extends Operator
{
String attribute;
@@ -969,7 +1016,7 @@
}
}
- private static class PushOperator extends Operator
+ private static final class PushOperator extends Operator
{
String attribute;
@@ -1012,7 +1059,7 @@
}
}
- private static class ConstOperator extends Operator
+ private static final class ConstOperator extends Operator
{
Object val;
@@ -1048,7 +1095,7 @@
}
}
- private static class SubStringOperator extends Operator
+ private static final class SubStringOperator extends Operator
implements OperatorConstants
{
String[] pieces;