From 18b64d8efe7da2095468d1937a379ba7d7083d27 Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Wed, 22 Dec 2010 12:06:31 +0000
Subject: [PATCH] Ensure that correct Grizzly MemoryManager is used for SASL and ASN1 filters.
---
sdk/src/com/sun/opends/sdk/tools/ModRate.java | 41 +-
sdk/src/com/sun/opends/sdk/ldap/SASLEncoderTransformer.java | 12
sdk/src/com/sun/opends/sdk/tools/PerformanceRunner.java | 321 ++++++++++++++++----
sdk/src/com/sun/opends/sdk/ldap/LDAPServerFilter.java | 6
sdk/src/com/sun/opends/sdk/ldap/LDAPClientFilter.java | 6
sdk/examples/org/opends/sdk/examples/server/store/Main.java | 6
sdk/src/com/sun/opends/sdk/ldap/SASLFilter.java | 8
sdk/src/com/sun/opends/sdk/tools/AuthRate.java | 188 ++++++-----
sdk/src/com/sun/opends/sdk/ldap/SASLDecoderTransformer.java | 12
sdk/src/com/sun/opends/sdk/tools/SearchRate.java | 48 +-
sdk/src/com/sun/opends/sdk/ldap/ASN1BufferReader.java | 9
sdk/tests/unit-tests-testng/src/com/sun/opends/sdk/ldap/ASN1BufferWriterTestCase.java | 4
sdk/tests/unit-tests-testng/src/com/sun/opends/sdk/ldap/ASN1BufferReaderTestCase.java | 4
sdk/examples/org/opends/sdk/examples/server/proxy/Main.java | 6
sdk/src/com/sun/opends/sdk/tools/PerfToolTCPNIOTransportFactory.java | 5
sdk/src/org/opends/sdk/AVA.java | 183 +++++++----
16 files changed, 558 insertions(+), 301 deletions(-)
diff --git a/sdk/examples/org/opends/sdk/examples/server/proxy/Main.java b/sdk/examples/org/opends/sdk/examples/server/proxy/Main.java
index 204b68e..4403021 100644
--- a/sdk/examples/org/opends/sdk/examples/server/proxy/Main.java
+++ b/sdk/examples/org/opends/sdk/examples/server/proxy/Main.java
@@ -35,11 +35,14 @@
import java.util.LinkedList;
import java.util.List;
+import org.glassfish.grizzly.TransportFactory;
import org.opends.sdk.*;
import org.opends.sdk.controls.ProxiedAuthV2RequestControl;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
+import com.sun.opends.sdk.tools.PerfToolTCPNIOTransportFactory;
+
/**
@@ -602,6 +605,9 @@
System.exit(1);
}
+ // Use the same transport factory as the tools.
+ TransportFactory.setInstance(new PerfToolTCPNIOTransportFactory());
+
// Parse command line arguments.
final String localAddress = args[0];
final int localPort = Integer.parseInt(args[1]);
diff --git a/sdk/examples/org/opends/sdk/examples/server/store/Main.java b/sdk/examples/org/opends/sdk/examples/server/store/Main.java
index cae70d8..e9f1b38 100644
--- a/sdk/examples/org/opends/sdk/examples/server/store/Main.java
+++ b/sdk/examples/org/opends/sdk/examples/server/store/Main.java
@@ -39,11 +39,14 @@
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import org.glassfish.grizzly.TransportFactory;
import org.opends.sdk.*;
import org.opends.sdk.ldif.LDIFEntryReader;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
+import com.sun.opends.sdk.tools.PerfToolTCPNIOTransportFactory;
+
/**
@@ -488,6 +491,9 @@
System.exit(1);
}
+ // Use the same transport factory as the tools.
+ TransportFactory.setInstance(new PerfToolTCPNIOTransportFactory());
+
// Parse command line arguments.
final String localAddress = args[0];
final int localPort = Integer.parseInt(args[1]);
diff --git a/sdk/src/com/sun/opends/sdk/ldap/ASN1BufferReader.java b/sdk/src/com/sun/opends/sdk/ldap/ASN1BufferReader.java
index 55d3c98..caf2f3f 100644
--- a/sdk/src/com/sun/opends/sdk/ldap/ASN1BufferReader.java
+++ b/sdk/src/com/sun/opends/sdk/ldap/ASN1BufferReader.java
@@ -48,6 +48,8 @@
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.memory.BuffersBuffer;
import org.glassfish.grizzly.memory.CompositeBuffer;
+import org.glassfish.grizzly.memory.MemoryManager;
+
import com.sun.opends.sdk.util.StaticUtils;
@@ -226,13 +228,16 @@
* @param maxElementSize
* The maximum BER element size, or <code>0</code> to indicate that
* there is no limit.
+ * @param memoryManager
+ * The memory manager to use for buffering.
*/
- ASN1BufferReader(final int maxElementSize)
+ ASN1BufferReader(final int maxElementSize,
+ final MemoryManager<?> memoryManager)
{
this.readLimiter = new RootSequenceLimiter();
this.stringBuffer = new byte[MAX_STRING_BUFFER_SIZE];
this.maxElementSize = maxElementSize;
- this.buffer = BuffersBuffer.create();
+ this.buffer = BuffersBuffer.create(memoryManager);
}
diff --git a/sdk/src/com/sun/opends/sdk/ldap/LDAPClientFilter.java b/sdk/src/com/sun/opends/sdk/ldap/LDAPClientFilter.java
index 9a8b55f..47b22bd 100644
--- a/sdk/src/com/sun/opends/sdk/ldap/LDAPClientFilter.java
+++ b/sdk/src/com/sun/opends/sdk/ldap/LDAPClientFilter.java
@@ -171,7 +171,8 @@
{
// The connection needs to be secured by the SASL
// mechanism.
- ldapConnection.installFilter(new SASLFilter(l));
+ ldapConnection.installFilter(new SASLFilter(l, ctx
+ .getConnection().getTransport().getMemoryManager()));
}
}
@@ -601,7 +602,8 @@
.get(ctx.getConnection());
if (asn1Reader == null)
{
- asn1Reader = new ASN1BufferReader(maxASN1ElementSize);
+ asn1Reader = new ASN1BufferReader(maxASN1ElementSize, ctx.getConnection()
+ .getTransport().getMemoryManager());
LDAP_ASN1_READER_ATTR.set(ctx.getConnection(), asn1Reader);
}
asn1Reader.appendBytesRead(buffer);
diff --git a/sdk/src/com/sun/opends/sdk/ldap/LDAPServerFilter.java b/sdk/src/com/sun/opends/sdk/ldap/LDAPServerFilter.java
index 2017775..a4b9747 100644
--- a/sdk/src/com/sun/opends/sdk/ldap/LDAPServerFilter.java
+++ b/sdk/src/com/sun/opends/sdk/ldap/LDAPServerFilter.java
@@ -315,7 +315,8 @@
@Override
public void startSASL(final ConnectionSecurityLayer bindContext)
{
- installFilter(connection, new SASLFilter(bindContext));
+ installFilter(connection, new SASLFilter(bindContext, connection
+ .getTransport().getMemoryManager()));
}
@@ -1095,7 +1096,8 @@
.get(ctx.getConnection());
if (asn1Reader == null)
{
- asn1Reader = new ASN1BufferReader(maxASN1ElementSize);
+ asn1Reader = new ASN1BufferReader(maxASN1ElementSize, ctx.getConnection()
+ .getTransport().getMemoryManager());
LDAP_ASN1_READER_ATTR.set(ctx.getConnection(), asn1Reader);
}
asn1Reader.appendBytesRead(buffer);
diff --git a/sdk/src/com/sun/opends/sdk/ldap/SASLDecoderTransformer.java b/sdk/src/com/sun/opends/sdk/ldap/SASLDecoderTransformer.java
index 5e817ba..fa518da 100644
--- a/sdk/src/com/sun/opends/sdk/ldap/SASLDecoderTransformer.java
+++ b/sdk/src/com/sun/opends/sdk/ldap/SASLDecoderTransformer.java
@@ -49,20 +49,12 @@
private final byte[] buffer = new byte[BUFFER_SIZE];
private final ConnectionSecurityLayer bindContext;
- private final MemoryManager<Buffer> memoryManager;
-
-
-
- @SuppressWarnings("unchecked")
- public SASLDecoderTransformer(final ConnectionSecurityLayer bindContext)
- {
- this(bindContext, TransportFactory.getInstance().getDefaultMemoryManager());
- }
+ private final MemoryManager<?> memoryManager;
public SASLDecoderTransformer(final ConnectionSecurityLayer bindContext,
- final MemoryManager<Buffer> memoryManager)
+ final MemoryManager<?> memoryManager)
{
this.bindContext = bindContext;
this.memoryManager = memoryManager;
diff --git a/sdk/src/com/sun/opends/sdk/ldap/SASLEncoderTransformer.java b/sdk/src/com/sun/opends/sdk/ldap/SASLEncoderTransformer.java
index 4878ab7..7c57777 100644
--- a/sdk/src/com/sun/opends/sdk/ldap/SASLEncoderTransformer.java
+++ b/sdk/src/com/sun/opends/sdk/ldap/SASLEncoderTransformer.java
@@ -49,20 +49,12 @@
private final byte[] buffer = new byte[BUFFER_SIZE];
private final ConnectionSecurityLayer bindContext;
- private final MemoryManager<Buffer> memoryManager;
-
-
-
- @SuppressWarnings("unchecked")
- public SASLEncoderTransformer(final ConnectionSecurityLayer bindContext)
- {
- this(bindContext, TransportFactory.getInstance().getDefaultMemoryManager());
- }
+ private final MemoryManager<?> memoryManager;
public SASLEncoderTransformer(final ConnectionSecurityLayer bindContext,
- final MemoryManager<Buffer> memoryManager)
+ final MemoryManager<?> memoryManager)
{
this.bindContext = bindContext;
this.memoryManager = memoryManager;
diff --git a/sdk/src/com/sun/opends/sdk/ldap/SASLFilter.java b/sdk/src/com/sun/opends/sdk/ldap/SASLFilter.java
index c08fa1c..17cf702 100644
--- a/sdk/src/com/sun/opends/sdk/ldap/SASLFilter.java
+++ b/sdk/src/com/sun/opends/sdk/ldap/SASLFilter.java
@@ -33,6 +33,7 @@
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.filterchain.AbstractCodecFilter;
+import org.glassfish.grizzly.memory.MemoryManager;
@@ -41,9 +42,10 @@
*/
final class SASLFilter extends AbstractCodecFilter<Buffer, Buffer>
{
- public SASLFilter(final ConnectionSecurityLayer bindContext)
+ public SASLFilter(final ConnectionSecurityLayer bindContext,
+ final MemoryManager<?> memoryManager)
{
- super(new SASLDecoderTransformer(bindContext), new SASLEncoderTransformer(
- bindContext));
+ super(new SASLDecoderTransformer(bindContext, memoryManager),
+ new SASLEncoderTransformer(bindContext, memoryManager));
}
}
diff --git a/sdk/src/com/sun/opends/sdk/tools/AuthRate.java b/sdk/src/com/sun/opends/sdk/tools/AuthRate.java
index e8b8f99..fa50545 100644
--- a/sdk/src/com/sun/opends/sdk/tools/AuthRate.java
+++ b/sdk/src/com/sun/opends/sdk/tools/AuthRate.java
@@ -27,13 +27,11 @@
package com.sun.opends.sdk.tools;
-import com.sun.opends.sdk.util.RecursiveFutureResult;
-import org.glassfish.grizzly.TransportFactory;
-import org.opends.sdk.*;
-import org.opends.sdk.requests.*;
-import org.opends.sdk.responses.BindResult;
-import org.opends.sdk.responses.SearchResultEntry;
+
+import static com.sun.opends.sdk.messages.Messages.*;
+import static com.sun.opends.sdk.tools.ToolConstants.*;
+import static com.sun.opends.sdk.tools.Utils.filterExitCode;
import java.io.InputStream;
import java.io.OutputStream;
@@ -44,28 +42,31 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import static com.sun.opends.sdk.messages.Messages.*;
-import static com.sun.opends.sdk.tools.ToolConstants.*;
-import static com.sun.opends.sdk.tools.Utils.filterExitCode;
+import org.glassfish.grizzly.TransportFactory;
+import org.opends.sdk.*;
+import org.opends.sdk.requests.*;
+import org.opends.sdk.responses.BindResult;
+import org.opends.sdk.responses.SearchResultEntry;
+
+import com.sun.opends.sdk.util.RecursiveFutureResult;
+
+
/**
- * A load generation tool that can be used to load a Directory Server with
- * Bind requests using one or more LDAP connections.
+ * A load generation tool that can be used to load a Directory Server with Bind
+ * requests using one or more LDAP connections.
*/
public final class AuthRate extends ConsoleApplication
{
private final class BindPerformanceRunner extends PerformanceRunner
{
- private final AtomicLong searchWaitRecentTime = new AtomicLong();
- private final AtomicInteger invalidCredRecentCount = new AtomicInteger();
-
private final class BindStatsThread extends StatsThread
{
private final String[] extraColumn;
- private BindStatsThread(boolean extraFieldRequired)
+ private BindStatsThread(final boolean extraFieldRequired)
{
super(extraFieldRequired ? new String[] { "bind time %" }
: new String[0]);
@@ -93,15 +94,16 @@
private final class BindUpdateStatsResultHandler extends
UpdateStatsResultHandler<BindResult>
{
- private BindUpdateStatsResultHandler(long startTime)
+ private BindUpdateStatsResultHandler(final long startTime,
+ final AsynchronousConnection connection, final ConnectionWorker worker)
{
- super(startTime);
+ super(startTime, connection, worker);
}
@Override
- public void handleErrorResult(ErrorResultException error)
+ public void handleErrorResult(final ErrorResultException error)
{
super.handleErrorResult(error);
@@ -112,7 +114,9 @@
}
}
- private final class BindWorkerThread extends WorkerThread
+
+
+ private final class BindWorkerThread extends ConnectionWorker
{
private SearchRequest sr;
private BindRequest br;
@@ -122,6 +126,7 @@
private final ThreadLocal<Random> rng = new ThreadLocal<Random>()
{
+ @Override
protected Random initialValue()
{
return new Random();
@@ -130,6 +135,7 @@
};
+
private BindWorkerThread(final AsynchronousConnection connection,
final ConnectionFactory connectionFactory)
{
@@ -146,14 +152,14 @@
if (dataSources != null)
{
data = DataSource.generateData(dataSources, data);
- if(data.length == dataSources.length)
+ if (data.length == dataSources.length)
{
- Object[] newData = new Object[data.length + 1];
+ final Object[] newData = new Object[data.length + 1];
System.arraycopy(data, 0, newData, 0, data.length);
data = newData;
}
}
- if(filter != null && baseDN != null)
+ if (filter != null && baseDN != null)
{
if (sr == null)
{
@@ -163,8 +169,8 @@
}
else
{
- sr = Requests.newSearchRequest(String.format(baseDN, data), scope,
- String.format(filter, data), attributes);
+ sr = Requests.newSearchRequest(String.format(baseDN, data),
+ scope, String.format(filter, data), attributes);
}
sr.setDereferenceAliasesPolicy(dereferencesAliasesPolicy);
}
@@ -174,32 +180,32 @@
sr.setName(String.format(baseDN, data));
}
- RecursiveFutureResult<SearchResultEntry, BindResult> future =
- new RecursiveFutureResult<SearchResultEntry, BindResult>(
- new BindUpdateStatsResultHandler(startTime))
+ final RecursiveFutureResult<SearchResultEntry, BindResult> future =
+ new RecursiveFutureResult<SearchResultEntry, BindResult>(
+ new BindUpdateStatsResultHandler(startTime, connection, this))
+ {
+ @Override
+ protected FutureResult<? extends BindResult> chainResult(
+ final SearchResultEntry innerResult,
+ final ResultHandler<? super BindResult> resultHandler)
+ throws ErrorResultException
+ {
+ searchWaitRecentTime.getAndAdd(System.nanoTime() - startTime);
+ if (data == null)
{
- @Override
- protected FutureResult<? extends BindResult> chainResult(
- SearchResultEntry innerResult,
- ResultHandler<? super BindResult> resultHandler)
- throws ErrorResultException
- {
- searchWaitRecentTime.getAndAdd(System.nanoTime() - startTime);
- if(data == null)
- {
- data = new Object[1];
- }
- data[data.length-1] = innerResult.getName().toString();
- return performBind(connection, data, resultHandler);
- }
- };
+ data = new Object[1];
+ }
+ data[data.length - 1] = innerResult.getName().toString();
+ return performBind(connection, data, resultHandler);
+ }
+ };
connection.searchSingleEntry(sr, future);
return future;
}
else
{
return performBind(connection, data,
- new BindUpdateStatsResultHandler(startTime));
+ new BindUpdateStatsResultHandler(startTime, connection, this));
}
}
@@ -229,13 +235,13 @@
if (bindRequest instanceof SimpleBindRequest)
{
- SimpleBindRequest o = (SimpleBindRequest) bindRequest;
+ final SimpleBindRequest o = (SimpleBindRequest) bindRequest;
if (br == null)
{
br = Requests.copyOfSimpleBindRequest(o);
}
- SimpleBindRequest sbr = (SimpleBindRequest) br;
+ final SimpleBindRequest sbr = (SimpleBindRequest) br;
if (data != null && o.getName() != null)
{
sbr.setName(String.format(o.getName(), data));
@@ -251,13 +257,13 @@
}
else if (bindRequest instanceof DigestMD5SASLBindRequest)
{
- DigestMD5SASLBindRequest o = (DigestMD5SASLBindRequest) bindRequest;
+ final DigestMD5SASLBindRequest o = (DigestMD5SASLBindRequest) bindRequest;
if (br == null)
{
br = Requests.copyOfDigestMD5SASLBindRequest(o);
}
- DigestMD5SASLBindRequest sbr = (DigestMD5SASLBindRequest) br;
+ final DigestMD5SASLBindRequest sbr = (DigestMD5SASLBindRequest) br;
if (data != null)
{
if (o.getAuthenticationID() != null)
@@ -281,13 +287,13 @@
}
else if (bindRequest instanceof CRAMMD5SASLBindRequest)
{
- CRAMMD5SASLBindRequest o = (CRAMMD5SASLBindRequest) bindRequest;
+ final CRAMMD5SASLBindRequest o = (CRAMMD5SASLBindRequest) bindRequest;
if (br == null)
{
br = Requests.copyOfCRAMMD5SASLBindRequest(o);
}
- CRAMMD5SASLBindRequest sbr = (CRAMMD5SASLBindRequest) br;
+ final CRAMMD5SASLBindRequest sbr = (CRAMMD5SASLBindRequest) br;
if (data != null && o.getAuthenticationID() != null)
{
sbr.setAuthenticationID(String.format(o.getAuthenticationID(), data));
@@ -303,13 +309,13 @@
}
else if (bindRequest instanceof GSSAPISASLBindRequest)
{
- GSSAPISASLBindRequest o = (GSSAPISASLBindRequest) bindRequest;
+ final GSSAPISASLBindRequest o = (GSSAPISASLBindRequest) bindRequest;
if (br == null)
{
br = Requests.copyOfGSSAPISASLBindRequest(o);
}
- GSSAPISASLBindRequest sbr = (GSSAPISASLBindRequest) br;
+ final GSSAPISASLBindRequest sbr = (GSSAPISASLBindRequest) br;
if (data != null)
{
if (o.getAuthenticationID() != null)
@@ -333,13 +339,13 @@
}
else if (bindRequest instanceof ExternalSASLBindRequest)
{
- ExternalSASLBindRequest o = (ExternalSASLBindRequest) bindRequest;
+ final ExternalSASLBindRequest o = (ExternalSASLBindRequest) bindRequest;
if (br == null)
{
br = Requests.copyOfExternalSASLBindRequest(o);
}
- ExternalSASLBindRequest sbr = (ExternalSASLBindRequest) br;
+ final ExternalSASLBindRequest sbr = (ExternalSASLBindRequest) br;
if (data != null && o.getAuthorizationID() != null)
{
sbr.setAuthorizationID(String.format(o.getAuthorizationID(), data));
@@ -347,13 +353,13 @@
}
else if (bindRequest instanceof PlainSASLBindRequest)
{
- PlainSASLBindRequest o = (PlainSASLBindRequest) bindRequest;
+ final PlainSASLBindRequest o = (PlainSASLBindRequest) bindRequest;
if (br == null)
{
br = Requests.copyOfPlainSASLBindRequest(o);
}
- PlainSASLBindRequest sbr = (PlainSASLBindRequest) br;
+ final PlainSASLBindRequest sbr = (PlainSASLBindRequest) br;
if (data != null)
{
if (o.getAuthenticationID() != null)
@@ -382,6 +388,10 @@
+ private final AtomicLong searchWaitRecentTime = new AtomicLong();
+
+ private final AtomicInteger invalidCredRecentCount = new AtomicInteger();
+
private String filter;
private String baseDN;
@@ -407,20 +417,24 @@
@Override
- StatsThread newStatsThread()
+ ConnectionWorker newConnectionWorker(
+ final AsynchronousConnection connection,
+ final ConnectionFactory connectionFactory)
{
- return new BindStatsThread(filter != null && baseDN != null);
+ return new BindWorkerThread(connection, connectionFactory);
}
@Override
- WorkerThread newWorkerThread(final AsynchronousConnection connection,
- final ConnectionFactory connectionFactory)
+ StatsThread newStatsThread()
{
- return new BindWorkerThread(connection, connectionFactory);
+ return new BindStatsThread(filter != null && baseDN != null);
}
}
+
+
+
/**
* The main method for AuthRate tool.
*
@@ -485,7 +499,6 @@
-
private AuthRate(final InputStream in, final OutputStream out,
final OutputStream err)
{
@@ -583,10 +596,10 @@
{
// Create the command-line argument parser for use with this
// program.
- final LocalizableMessage toolDescription =
- INFO_AUTHRATE_TOOL_DESCRIPTION.get();
- final ArgumentParser argParser = new ArgumentParser(AuthRate.class
- .getName(), toolDescription, false, true, 0, 0,
+ final LocalizableMessage toolDescription = INFO_AUTHRATE_TOOL_DESCRIPTION
+ .get();
+ final ArgumentParser argParser = new ArgumentParser(
+ AuthRate.class.getName(), toolDescription, false, true, 0, 0,
"[filter format string] [attributes ...]");
ConnectionFactoryProvider connectionFactoryProvider;
@@ -604,8 +617,7 @@
try
{
TransportFactory.setInstance(new PerfToolTCPNIOTransportFactory());
- connectionFactoryProvider =
- new ConnectionFactoryProvider(argParser, this);
+ connectionFactoryProvider = new ConnectionFactoryProvider(argParser, this);
runner = new BindPerformanceRunner(argParser, this);
propertiesFileArgument = new StringArgument("propertiesFilePath", null,
@@ -627,34 +639,35 @@
argParser.setUsageArgument(showUsage, getOutputStream());
baseDN = new StringArgument("baseDN", OPTION_SHORT_BASEDN,
- OPTION_LONG_BASEDN, false, false, true, INFO_BASEDN_PLACEHOLDER.get(),
- null, null, INFO_SEARCHRATE_TOOL_DESCRIPTION_BASEDN.get());
+ OPTION_LONG_BASEDN, false, false, true,
+ INFO_BASEDN_PLACEHOLDER.get(), null, null,
+ INFO_SEARCHRATE_TOOL_DESCRIPTION_BASEDN.get());
baseDN.setPropertyName(OPTION_LONG_BASEDN);
argParser.addArgument(baseDN);
searchScope = new MultiChoiceArgument<SearchScope>("searchScope", 's',
"searchScope", false, true, INFO_SEARCH_SCOPE_PLACEHOLDER.get(),
- SearchScope.values(), false, INFO_SEARCH_DESCRIPTION_SEARCH_SCOPE
- .get());
+ SearchScope.values(), false,
+ INFO_SEARCH_DESCRIPTION_SEARCH_SCOPE.get());
searchScope.setPropertyName("searchScope");
searchScope.setDefaultValue(SearchScope.WHOLE_SUBTREE);
argParser.addArgument(searchScope);
dereferencePolicy = new MultiChoiceArgument<DereferenceAliasesPolicy>(
"derefpolicy", 'a', "dereferencePolicy", false, true,
- INFO_DEREFERENCE_POLICE_PLACEHOLDER.get(), DereferenceAliasesPolicy
- .values(), false, INFO_SEARCH_DESCRIPTION_DEREFERENCE_POLICY
- .get());
+ INFO_DEREFERENCE_POLICE_PLACEHOLDER.get(),
+ DereferenceAliasesPolicy.values(), false,
+ INFO_SEARCH_DESCRIPTION_DEREFERENCE_POLICY.get());
dereferencePolicy.setPropertyName("dereferencePolicy");
dereferencePolicy.setDefaultValue(DereferenceAliasesPolicy.NEVER);
argParser.addArgument(dereferencePolicy);
invalidCredPercent = new IntegerArgument("invalidPassword", 'I',
- "invalidPassword", false, false, true, LocalizableMessage
- .raw("{invalidPassword}"), 0, null, true, 0, true, 100,
- LocalizableMessage
- .raw("Percent of bind operations with simulated " +
- "invalid password"));
+ "invalidPassword", false, false, true,
+ LocalizableMessage.raw("{invalidPassword}"), 0, null, true, 0, true,
+ 100,
+ LocalizableMessage.raw("Percent of bind operations with simulated "
+ + "invalid password"));
invalidCredPercent.setPropertyName("invalidPassword");
argParser.addArgument(invalidCredPercent);
@@ -688,15 +701,15 @@
return 0;
}
- connectionFactory =
- connectionFactoryProvider.getConnectionFactory();
+ connectionFactory = connectionFactoryProvider.getConnectionFactory();
runner.validate();
runner.bindRequest = connectionFactoryProvider.getBindRequest();
- if(runner.bindRequest == null)
+ if (runner.bindRequest == null)
{
- throw new ArgumentException(LocalizableMessage.raw(
- "Authentication information must be provided to use this tool"));
+ throw new ArgumentException(
+ LocalizableMessage
+ .raw("Authentication information must be provided to use this tool"));
}
}
catch (final ArgumentException ae)
@@ -739,11 +752,11 @@
// Try it out to make sure the format string and data sources
// match.
- final Object[] data = DataSource.generateData(runner.getDataSources(),
- null);
+ final Object[] data = DataSource
+ .generateData(runner.getDataSources(), null);
try
{
- if(runner.baseDN != null && runner.filter != null)
+ if (runner.baseDN != null && runner.filter != null)
{
String.format(runner.filter, data);
String.format(runner.baseDN, data);
@@ -759,4 +772,3 @@
return runner.run(connectionFactory);
}
}
-
diff --git a/sdk/src/com/sun/opends/sdk/tools/ModRate.java b/sdk/src/com/sun/opends/sdk/tools/ModRate.java
index 360f490..664da15 100644
--- a/sdk/src/com/sun/opends/sdk/tools/ModRate.java
+++ b/sdk/src/com/sun/opends/sdk/tools/ModRate.java
@@ -52,7 +52,7 @@
{
private static final class ModifyPerformanceRunner extends PerformanceRunner
{
- private final class ModifyWorkerThread extends WorkerThread
+ private final class ModifyWorkerThread extends ConnectionWorker
{
private ModifyRequest mr;
private Object[] data;
@@ -70,15 +70,15 @@
@Override
public FutureResult<?> performOperation(
final AsynchronousConnection connection,
- final DataSource[] dataSources, long startTime)
+ final DataSource[] dataSources, final long startTime)
{
if (dataSources != null)
{
data = DataSource.generateData(dataSources, data);
}
mr = newModifyRequest(data);
- return connection.modify(mr,
- new UpdateStatsResultHandler<Result>(startTime));
+ return connection.modify(mr, new UpdateStatsResultHandler<Result>(
+ startTime, connection, this));
}
@@ -109,9 +109,9 @@
colonPos = formattedString.indexOf(':');
if (colonPos > 0)
{
- mr.addModification(ModificationType.REPLACE, formattedString
- .substring(0, colonPos), formattedString
- .substring(colonPos + 1));
+ mr.addModification(ModificationType.REPLACE,
+ formattedString.substring(0, colonPos),
+ formattedString.substring(colonPos + 1));
}
}
return mr;
@@ -135,18 +135,19 @@
@Override
- StatsThread newStatsThread()
+ ConnectionWorker newConnectionWorker(
+ final AsynchronousConnection connection,
+ final ConnectionFactory connectionFactory)
{
- return new StatsThread(new String[0]);
+ return new ModifyWorkerThread(connection, connectionFactory);
}
@Override
- WorkerThread newWorkerThread(final AsynchronousConnection connection,
- final ConnectionFactory connectionFactory)
+ StatsThread newStatsThread()
{
- return new ModifyWorkerThread(connection, connectionFactory);
+ return new StatsThread(new String[0]);
}
}
@@ -313,8 +314,8 @@
{
// Create the command-line argument parser for use with this
// program.
- final LocalizableMessage toolDescription =
- INFO_MODRATE_TOOL_DESCRIPTION.get();
+ final LocalizableMessage toolDescription = INFO_MODRATE_TOOL_DESCRIPTION
+ .get();
final ArgumentParser argParser = new ArgumentParser(
ModRate.class.getName(), toolDescription, false, true, 1, 0,
"[(attribute:value format string) ...]");
@@ -330,8 +331,7 @@
try
{
TransportFactory.setInstance(new PerfToolTCPNIOTransportFactory());
- connectionFactoryProvider =
- new ConnectionFactoryProvider(argParser, this);
+ connectionFactoryProvider = new ConnectionFactoryProvider(argParser, this);
runner = new ModifyPerformanceRunner(argParser, this);
propertiesFileArgument = new StringArgument("propertiesFilePath", null,
OPTION_LONG_PROP_FILE_PATH, false, false, true,
@@ -347,8 +347,9 @@
argParser.setNoPropertiesFileArgument(noPropertiesFileArgument);
baseDN = new StringArgument("targetDN", OPTION_SHORT_BASEDN,
- OPTION_LONG_TARGETDN, true, false, true, INFO_TARGETDN_PLACEHOLDER.get(),
- null, null, INFO_MODRATE_TOOL_DESCRIPTION_TARGETDN.get());
+ OPTION_LONG_TARGETDN, true, false, true,
+ INFO_TARGETDN_PLACEHOLDER.get(), null, null,
+ INFO_MODRATE_TOOL_DESCRIPTION_TARGETDN.get());
baseDN.setPropertyName(OPTION_LONG_BASEDN);
argParser.addArgument(baseDN);
@@ -387,8 +388,8 @@
return 0;
}
- connectionFactory =
- connectionFactoryProvider.getAuthenticatedConnectionFactory();
+ connectionFactory = connectionFactoryProvider
+ .getAuthenticatedConnectionFactory();
runner.validate();
}
catch (final ArgumentException ae)
diff --git a/sdk/src/com/sun/opends/sdk/tools/PerfToolTCPNIOTransportFactory.java b/sdk/src/com/sun/opends/sdk/tools/PerfToolTCPNIOTransportFactory.java
index 1f6a1ec..c0452ce 100644
--- a/sdk/src/com/sun/opends/sdk/tools/PerfToolTCPNIOTransportFactory.java
+++ b/sdk/src/com/sun/opends/sdk/tools/PerfToolTCPNIOTransportFactory.java
@@ -46,7 +46,8 @@
/**
* The TCPNIOTransportFactory which performance tools will use.
*/
-final class PerfToolTCPNIOTransportFactory extends DefaultNIOTransportFactory
+public final class PerfToolTCPNIOTransportFactory extends
+ DefaultNIOTransportFactory
{
private int selectors;
@@ -115,7 +116,7 @@
}
final String selectorsStr = System
.getProperty("org.opends.sdk.ldap.transport.selectors");
- if (threadsStr != null)
+ if (selectorsStr != null)
{
selectors = Integer.parseInt(selectorsStr);
}
diff --git a/sdk/src/com/sun/opends/sdk/tools/PerformanceRunner.java b/sdk/src/com/sun/opends/sdk/tools/PerformanceRunner.java
index b4c5300..9f4ab43 100644
--- a/sdk/src/com/sun/opends/sdk/tools/PerformanceRunner.java
+++ b/sdk/src/com/sun/opends/sdk/tools/PerformanceRunner.java
@@ -33,16 +33,18 @@
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.util.*;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
-import com.sun.opends.sdk.util.StaticUtils;
import org.opends.sdk.*;
+import org.opends.sdk.responses.BindResult;
import org.opends.sdk.responses.ExtendedResult;
import org.opends.sdk.responses.Result;
import com.sun.opends.sdk.tools.AuthenticatedConnectionFactory.AuthenticatedAsynchronousConnection;
+import com.sun.opends.sdk.util.StaticUtils;
@@ -51,6 +53,170 @@
*/
abstract class PerformanceRunner implements ConnectionEventListener
{
+ abstract class ConnectionWorker
+ {
+ private final AtomicInteger operationsInFlight = new AtomicInteger();
+
+ private volatile int count;
+
+ private final AsynchronousConnection staticConnection;
+
+ private final ConnectionFactory connectionFactory;
+
+ private final CountDownLatch latch = new CountDownLatch(1);
+
+
+
+ ConnectionWorker(final AsynchronousConnection staticConnection,
+ final ConnectionFactory connectionFactory)
+ {
+ this.staticConnection = staticConnection;
+ this.connectionFactory = connectionFactory;
+ }
+
+
+
+ public void operationCompleted(final AsynchronousConnection connection)
+ {
+ if (operationsInFlight.decrementAndGet() == 0
+ && this.staticConnection == null)
+ {
+ connection.close();
+ }
+ startWork();
+ }
+
+
+
+ public abstract FutureResult<?> performOperation(
+ final AsynchronousConnection connection,
+ final DataSource[] dataSources, final long startTime);
+
+
+
+ public void startWork()
+ {
+ if (!stopRequested && !(maxIterations > 0 && count >= maxIterations))
+ {
+ if (this.staticConnection == null)
+ {
+ connectionFactory
+ .getAsynchronousConnection(new ResultHandler<AsynchronousConnection>()
+ {
+ public void handleErrorResult(final ErrorResultException e)
+ {
+ app.println(LocalizableMessage.raw(e.getResult()
+ .getDiagnosticMessage()));
+ if (e.getCause() != null && app.isVerbose())
+ {
+ e.getCause().printStackTrace(app.getErrorStream());
+ }
+ stopRequested = true;
+ }
+
+
+
+ public void handleResult(final AsynchronousConnection result)
+ {
+ doWork(result);
+ }
+ });
+ }
+ else
+ {
+ if (!noRebind
+ && this.staticConnection instanceof AuthenticatedAsynchronousConnection)
+ {
+ final AuthenticatedAsynchronousConnection ac =
+ (AuthenticatedAsynchronousConnection) this.staticConnection;
+ ac.rebind(new ResultHandler<BindResult>()
+ {
+ public void handleErrorResult(final ErrorResultException e)
+ {
+ app.println(LocalizableMessage.raw(e.getResult().toString()));
+ if (e.getCause() != null && app.isVerbose())
+ {
+ e.getCause().printStackTrace(app.getErrorStream());
+ }
+ stopRequested = true;
+ }
+
+
+
+ public void handleResult(final BindResult result)
+ {
+ doWork(staticConnection);
+ }
+ });
+ }
+ else
+ {
+ doWork(staticConnection);
+ }
+ }
+ }
+ else
+ {
+ latch.countDown();
+ }
+ }
+
+
+
+ public void waitFor() throws InterruptedException
+ {
+ latch.await();
+ }
+
+
+
+ private void doWork(final AsynchronousConnection connection)
+ {
+ long start;
+ double sleepTimeInMS = 0;
+ final int opsToPerform = isAsync ? numConcurrentTasks : numConcurrentTasks
+ - operationsInFlight.get();
+ for (int i = 0; i < opsToPerform; i++)
+ {
+ if (maxIterations > 0 && count >= maxIterations)
+ {
+ break;
+ }
+ start = System.nanoTime();
+ performOperation(connection, dataSources.get(), start);
+ operationRecentCount.getAndIncrement();
+ operationsInFlight.getAndIncrement();
+ count++;
+
+ if (targetThroughput > 0)
+ {
+ try
+ {
+ if (sleepTimeInMS > 1)
+ {
+ Thread.sleep((long) Math.floor(sleepTimeInMS));
+ }
+ }
+ catch (final InterruptedException e)
+ {
+ continue;
+ }
+
+ sleepTimeInMS += targetTimeInMS
+ - ((System.nanoTime() - start) / 1000000.0);
+ if (sleepTimeInMS < -60000)
+ {
+ // If we fall behind by 60 seconds, just forget about
+ // catching up
+ sleepTimeInMS = -60000;
+ }
+ }
+ }
+ }
+ }
+
+
+
/**
* Statistics thread base implementation.
*/
@@ -263,8 +429,8 @@
if (resultCount > 0)
{
strings[2] = String.format("%.3f",
- (waitTime - (gcDuration - lastGCDuration))
- / (double) resultCount / 1000000.0);
+ (waitTime - (gcDuration - lastGCDuration)) / (double) resultCount
+ / 1000000.0);
}
else
{
@@ -370,7 +536,7 @@
{
// Script-friendly.
app.getOutputStream().print(averageDuration);
- for (String s : strings)
+ for (final String s : strings)
{
app.getOutputStream().print(",");
app.getOutputStream().print(s);
@@ -399,12 +565,17 @@
class UpdateStatsResultHandler<S extends Result> implements ResultHandler<S>
{
private final long startTime;
+ private final AsynchronousConnection connection;
+ private final ConnectionWorker worker;
- UpdateStatsResultHandler(final long startTime)
+ UpdateStatsResultHandler(final long startTime,
+ final AsynchronousConnection connection, final ConnectionWorker worker)
{
this.startTime = startTime;
+ this.connection = connection;
+ this.worker = worker;
}
@@ -418,6 +589,8 @@
{
app.println(LocalizableMessage.raw(error.getResult().toString()));
}
+
+ worker.operationCompleted(connection);
}
@@ -426,6 +599,7 @@
{
successRecentCount.getAndIncrement();
updateStats();
+ worker.operationCompleted(connection);
}
@@ -487,8 +661,7 @@
AsynchronousConnection connection;
final double targetTimeInMS =
- (1.0 / (targetThroughput /
- (double) (numThreads * numConnections))) * 1000.0;
+ (1.0 / (targetThroughput / (double) (numConcurrentTasks * numConnections))) * 1000.0;
double sleepTimeInMS = 0;
long start;
while (!stopRequested && !(maxIterations > 0 && count >= maxIterations))
@@ -797,20 +970,20 @@
private final AtomicLong waitRecentTime = new AtomicLong();
- private final AtomicReference<ReversableArray> eTimeBuffer =
- new AtomicReference<ReversableArray>(new ReversableArray(100000));
+ private final AtomicReference<ReversableArray> eTimeBuffer = new AtomicReference<ReversableArray>(
+ new ReversableArray(100000));
private final ConsoleApplication app;
private DataSource[] dataSourcePrototypes;
// Thread local copies of the data sources
- private final ThreadLocal<DataSource[]> dataSources =
- new ThreadLocal<DataSource[]>()
+ private final ThreadLocal<DataSource[]> dataSources = new ThreadLocal<DataSource[]>()
{
/**
* {@inheritDoc}
*/
+ @Override
protected DataSource[] initialValue()
{
final DataSource[] prototypes = getDataSources();
@@ -827,7 +1000,7 @@
private volatile boolean stopRequested;
- private int numThreads;
+ private int numConcurrentTasks;
private int numConnections;
@@ -841,7 +1014,9 @@
private int statsInterval;
- private final IntegerArgument numThreadsArgument;
+ private double targetTimeInMS;
+
+ private final IntegerArgument numConcurrentTasksArgument;
private final IntegerArgument maxIterationsArgument;
@@ -864,52 +1039,52 @@
PerformanceRunner(final ArgumentParser argParser,
- final ConsoleApplication app,
- boolean neverRebind, boolean neverAsynchronous,
- boolean alwaysSingleThreaded)
+ final ConsoleApplication app, final boolean neverRebind,
+ final boolean neverAsynchronous, final boolean alwaysSingleThreaded)
throws ArgumentException
{
this.app = app;
- numThreadsArgument = new IntegerArgument("numThreads", 't', "numThreads",
- false, false, true, LocalizableMessage.raw("{numThreads}"), 1, null,
- true, 1, false, 0, LocalizableMessage
- .raw("Number of worker threads per connection"));
- numThreadsArgument.setPropertyName("numThreads");
- if(!alwaysSingleThreaded)
+ numConcurrentTasksArgument = new IntegerArgument("numConcurrentTasks", 't',
+ "numConcurrentTasks", false, false, true,
+ LocalizableMessage.raw("{numConcurrentTasks}"), 1, null, true, 1,
+ false, 0,
+ LocalizableMessage.raw("Number of concurrent tasks per connection"));
+ numConcurrentTasksArgument.setPropertyName("numConcurrentTasks");
+ if (!alwaysSingleThreaded)
{
- argParser.addArgument(numThreadsArgument);
+ argParser.addArgument(numConcurrentTasksArgument);
}
else
{
- numThreadsArgument.addValue("1");
+ numConcurrentTasksArgument.addValue("1");
}
numConnectionsArgument = new IntegerArgument("numConnections", 'c',
- "numConnections", false, false, true, LocalizableMessage
- .raw("{numConnections}"), 1, null, true, 1, false, 0,
+ "numConnections", false, false, true,
+ LocalizableMessage.raw("{numConnections}"), 1, null, true, 1, false, 0,
LocalizableMessage.raw("Number of connections"));
numConnectionsArgument.setPropertyName("numConnections");
argParser.addArgument(numConnectionsArgument);
maxIterationsArgument = new IntegerArgument("maxIterations", 'm',
- "maxIterations", false, false, true, LocalizableMessage
- .raw("{maxIterations}"), 0, null, LocalizableMessage
- .raw("Max iterations, 0 for unlimited"));
+ "maxIterations", false, false, true,
+ LocalizableMessage.raw("{maxIterations}"), 0, null,
+ LocalizableMessage.raw("Max iterations, 0 for unlimited"));
maxIterationsArgument.setPropertyName("maxIterations");
argParser.addArgument(maxIterationsArgument);
statsIntervalArgument = new IntegerArgument("statInterval", 'i',
- "statInterval", false, false, true, LocalizableMessage
- .raw("{statInterval}"), 5, null, true, 1, false, 0,
+ "statInterval", false, false, true,
+ LocalizableMessage.raw("{statInterval}"), 5, null, true, 1, false, 0,
LocalizableMessage
.raw("Display results each specified number of seconds"));
statsIntervalArgument.setPropertyName("statInterval");
argParser.addArgument(statsIntervalArgument);
targetThroughputArgument = new IntegerArgument("targetThroughput", 'M',
- "targetThroughput", false, false, true, LocalizableMessage
- .raw("{targetThroughput}"), 0, null, LocalizableMessage
- .raw("Target average throughput to achieve"));
+ "targetThroughput", false, false, true,
+ LocalizableMessage.raw("{targetThroughput}"), 0, null,
+ LocalizableMessage.raw("Target average throughput to achieve"));
targetThroughputArgument.setPropertyName("targetThroughput");
argParser.addArgument(targetThroughputArgument);
@@ -929,7 +1104,7 @@
noRebindArgument = new BooleanArgument("noRebind", 'F', "noRebind",
LocalizableMessage.raw("Keep connections open and don't rebind"));
noRebindArgument.setPropertyName("noRebind");
- if(!neverRebind)
+ if (!neverRebind)
{
argParser.addArgument(noRebindArgument);
}
@@ -939,24 +1114,30 @@
}
asyncArgument = new BooleanArgument("asynchronous", 'A', "asynchronous",
- LocalizableMessage.raw("Use asynchronous mode and don't " +
- "wait for results before sending the next request"));
+ LocalizableMessage.raw("Use asynchronous mode and don't "
+ + "wait for results before sending the next request"));
asyncArgument.setPropertyName("asynchronous");
- if(!neverAsynchronous)
+ if (!neverAsynchronous)
{
argParser.addArgument(asyncArgument);
}
- arguments = new StringArgument("argument", 'g', "argument", false, true,
- true, LocalizableMessage.raw("{generator function or static string}"),
- null, null,
- LocalizableMessage.raw("Argument used to evaluate the Java " +
- "style format strings in program parameters (ie. Base DN, " +
- "Search Filter). The set of all arguments provided form the " +
- "the argument list in order. Besides static string " +
- "arguments, they can be generated per iteration with the " +
- "following functions: " + StaticUtils.EOL +
- DataSource.getUsage()));
+ arguments = new StringArgument(
+ "argument",
+ 'g',
+ "argument",
+ false,
+ true,
+ true,
+ LocalizableMessage.raw("{generator function or static string}"),
+ null,
+ null,
+ LocalizableMessage.raw("Argument used to evaluate the Java "
+ + "style format strings in program parameters (ie. Base DN, "
+ + "Search Filter). The set of all arguments provided form the "
+ + "the argument list in order. Besides static string "
+ + "arguments, they can be generated per iteration with the "
+ + "following functions: " + StaticUtils.EOL + DataSource.getUsage()));
argParser.addArgument(arguments);
}
@@ -986,8 +1167,7 @@
- public void handleUnsolicitedNotification(
- final ExtendedResult notification)
+ public void handleUnsolicitedNotification(final ExtendedResult notification)
{
// Ignore
}
@@ -997,20 +1177,19 @@
public final void validate() throws ArgumentException
{
numConnections = numConnectionsArgument.getIntValue();
- numThreads = numThreadsArgument.getIntValue();
- maxIterations = maxIterationsArgument.getIntValue() /
- numConnections / numThreads;
+ numConcurrentTasks = numConcurrentTasksArgument.getIntValue();
+ maxIterations = maxIterationsArgument.getIntValue() / numConnections;
statsInterval = statsIntervalArgument.getIntValue() * 1000;
targetThroughput = targetThroughputArgument.getIntValue();
isAsync = asyncArgument.isPresent();
noRebind = noRebindArgument.isPresent();
- if (!noRebindArgument.isPresent() && this.numThreads > 1)
+ if (!noRebindArgument.isPresent() && this.numConcurrentTasks > 1)
{
throw new ArgumentException(LocalizableMessage.raw("--"
+ noRebindArgument.getLongIdentifier() + " must be used if --"
- + numThreadsArgument.getLongIdentifier() + " is > 1"));
+ + numConcurrentTasksArgument.getLongIdentifier() + " is > 1"));
}
if (!noRebindArgument.isPresent() && asyncArgument.isPresent())
@@ -1021,6 +1200,9 @@
}
dataSourcePrototypes = DataSource.parse(arguments.getValues());
+
+ targetTimeInMS =
+ (1.0 / (targetThroughput / (double) (numConcurrentTasks * numConnections))) * 1000.0;
}
@@ -1037,22 +1219,22 @@
+ abstract ConnectionWorker newConnectionWorker(
+ final AsynchronousConnection connection,
+ final ConnectionFactory connectionFactory);
+
+
+
abstract StatsThread newStatsThread();
- abstract WorkerThread newWorkerThread(AsynchronousConnection connection,
- ConnectionFactory connectionFactory);
-
-
-
final int run(final ConnectionFactory connectionFactory)
{
- final List<Thread> threads = new ArrayList<Thread>();
+ final List<ConnectionWorker> workers = new ArrayList<ConnectionWorker>();
final List<AsynchronousConnection> connections = new ArrayList<AsynchronousConnection>();
AsynchronousConnection connection = null;
- Thread thread;
try
{
for (int i = 0; i < numConnections; i++)
@@ -1063,21 +1245,18 @@
connection.addConnectionEventListener(this);
connections.add(connection);
}
- for (int j = 0; j < numThreads; j++)
- {
- thread = newWorkerThread(connection, connectionFactory);
-
- threads.add(thread);
- thread.start();
- }
+ final ConnectionWorker worker = newConnectionWorker(connection,
+ connectionFactory);
+ workers.add(worker);
+ worker.startWork();
}
final Thread statsThread = newStatsThread();
statsThread.start();
- for (final Thread t : threads)
+ for (final ConnectionWorker w : workers)
{
- t.join();
+ w.waitFor();
}
stopRequested = true;
statsThread.join();
diff --git a/sdk/src/com/sun/opends/sdk/tools/SearchRate.java b/sdk/src/com/sun/opends/sdk/tools/SearchRate.java
index 332f510..8ee12d6 100644
--- a/sdk/src/com/sun/opends/sdk/tools/SearchRate.java
+++ b/sdk/src/com/sun/opends/sdk/tools/SearchRate.java
@@ -61,13 +61,15 @@
private final class SearchStatsHandler extends
UpdateStatsResultHandler<Result> implements SearchResultHandler
{
- private SearchStatsHandler(final long startTime)
+ private SearchStatsHandler(final long startTime,
+ final AsynchronousConnection connection, final ConnectionWorker worker)
{
- super(startTime);
+ super(startTime, connection, worker);
}
+ @Override
public boolean handleEntry(final SearchResultEntry entry)
{
entryRecentCount.getAndIncrement();
@@ -76,6 +78,7 @@
+ @Override
public boolean handleReference(final SearchResultReference reference)
{
return true;
@@ -117,7 +120,7 @@
- private final class SearchWorkerThread extends WorkerThread
+ private final class SearchWorkerThread extends ConnectionWorker
{
private SearchRequest sr;
@@ -158,7 +161,8 @@
sr.setFilter(String.format(filter, data));
sr.setName(String.format(baseDN, data));
}
- return connection.search(sr, new SearchStatsHandler(startTime));
+ return connection.search(sr, new SearchStatsHandler(startTime,
+ connection, this));
}
}
@@ -185,18 +189,19 @@
@Override
- StatsThread newStatsThread()
+ ConnectionWorker newConnectionWorker(
+ final AsynchronousConnection connection,
+ final ConnectionFactory connectionFactory)
{
- return new SearchStatsThread();
+ return new SearchWorkerThread(connection, connectionFactory);
}
@Override
- WorkerThread newWorkerThread(final AsynchronousConnection connection,
- final ConnectionFactory connectionFactory)
+ StatsThread newStatsThread()
{
- return new SearchWorkerThread(connection, connectionFactory);
+ return new SearchStatsThread();
}
}
@@ -365,10 +370,10 @@
{
// Create the command-line argument parser for use with this
// program.
- final LocalizableMessage toolDescription =
- INFO_SEARCHRATE_TOOL_DESCRIPTION.get();
- final ArgumentParser argParser = new ArgumentParser(SearchRate.class
- .getName(), toolDescription, false, true, 1, 0,
+ final LocalizableMessage toolDescription = INFO_SEARCHRATE_TOOL_DESCRIPTION
+ .get();
+ final ArgumentParser argParser = new ArgumentParser(
+ SearchRate.class.getName(), toolDescription, false, true, 1, 0,
"[filter format string] [attributes ...]");
ConnectionFactoryProvider connectionFactoryProvider;
@@ -385,8 +390,7 @@
try
{
TransportFactory.setInstance(new PerfToolTCPNIOTransportFactory());
- connectionFactoryProvider =
- new ConnectionFactoryProvider(argParser, this);
+ connectionFactoryProvider = new ConnectionFactoryProvider(argParser, this);
runner = new SearchPerformanceRunner(argParser, this);
propertiesFileArgument = new StringArgument("propertiesFilePath", null,
@@ -415,17 +419,17 @@
searchScope = new MultiChoiceArgument<SearchScope>("searchScope", 's',
"searchScope", false, true, INFO_SEARCH_SCOPE_PLACEHOLDER.get(),
- SearchScope.values(), false, INFO_SEARCH_DESCRIPTION_SEARCH_SCOPE
- .get());
+ SearchScope.values(), false,
+ INFO_SEARCH_DESCRIPTION_SEARCH_SCOPE.get());
searchScope.setPropertyName("searchScope");
searchScope.setDefaultValue(SearchScope.WHOLE_SUBTREE);
argParser.addArgument(searchScope);
dereferencePolicy = new MultiChoiceArgument<DereferenceAliasesPolicy>(
"derefpolicy", 'a', "dereferencePolicy", false, true,
- INFO_DEREFERENCE_POLICE_PLACEHOLDER.get(), DereferenceAliasesPolicy
- .values(), false, INFO_SEARCH_DESCRIPTION_DEREFERENCE_POLICY
- .get());
+ INFO_DEREFERENCE_POLICE_PLACEHOLDER.get(),
+ DereferenceAliasesPolicy.values(), false,
+ INFO_SEARCH_DESCRIPTION_DEREFERENCE_POLICY.get());
dereferencePolicy.setPropertyName("dereferencePolicy");
dereferencePolicy.setDefaultValue(DereferenceAliasesPolicy.NEVER);
argParser.addArgument(dereferencePolicy);
@@ -460,8 +464,8 @@
return 0;
}
- connectionFactory =
- connectionFactoryProvider.getAuthenticatedConnectionFactory();
+ connectionFactory = connectionFactoryProvider
+ .getAuthenticatedConnectionFactory();
runner.validate();
}
catch (final ArgumentException ae)
diff --git a/sdk/src/org/opends/sdk/AVA.java b/sdk/src/org/opends/sdk/AVA.java
index 6ed0388..70c5784 100644
--- a/sdk/src/org/opends/sdk/AVA.java
+++ b/sdk/src/org/opends/sdk/AVA.java
@@ -32,6 +32,8 @@
import static com.sun.opends.sdk.messages.Messages.*;
import static com.sun.opends.sdk.util.StaticUtils.*;
+import java.util.Comparator;
+
import org.opends.sdk.schema.*;
import com.sun.opends.sdk.util.StaticUtils;
@@ -105,8 +107,8 @@
}
catch (final UnknownSchemaElementException e)
{
- final LocalizableMessage message = ERR_RDN_TYPE_NOT_FOUND.get(ava, e
- .getMessageObject());
+ final LocalizableMessage message = ERR_RDN_TYPE_NOT_FOUND.get(ava,
+ e.getMessageObject());
throw new LocalizedIllegalArgumentException(message);
}
}
@@ -138,8 +140,8 @@
char c;
if ((c = reader.read()) != '=')
{
- final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_NO_EQUAL.get(reader
- .getString(), attribute.getNameOrOID(), c);
+ final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_NO_EQUAL.get(
+ reader.getString(), attribute.getNameOrOID(), c);
throw new LocalizedIllegalArgumentException(message);
}
@@ -665,6 +667,12 @@
private final ByteString attributeValue;
+ // Cached normalized value using equality matching rule.
+ private ByteString equalityNormalizedAttributeValue = null;
+
+ // Cached normalized value using ordering matching rule.
+ private ByteString orderingNormalizedAttributeValue = null;
+
/**
@@ -676,8 +684,8 @@
* @param attributeValue
* The attribute value.
* @throws NullPointerException
- * If {@code attributeType} or {@code attributeValue} was {@code
- * null}.
+ * If {@code attributeType} or {@code attributeValue} was
+ * {@code null}.
*/
public AVA(final AttributeType attributeType, final ByteString attributeValue)
throws NullPointerException
@@ -704,8 +712,8 @@
* @throws UnknownSchemaElementException
* If {@code attributeType} was not found in the default schema.
* @throws NullPointerException
- * If {@code attributeType} or {@code attributeValue} was {@code
- * null}.
+ * If {@code attributeType} or {@code attributeValue} was
+ * {@code null}.
*/
public AVA(final String attributeType, final Object attributeValue)
throws UnknownSchemaElementException, NullPointerException
@@ -722,55 +730,27 @@
/**
* {@inheritDoc}
*/
+ @Override
public int compareTo(final AVA ava)
{
- int result = attributeType.compareTo(ava.attributeType);
+ final int result = attributeType.compareTo(ava.attributeType);
if (result != 0)
{
return result > 0 ? 1 : -1;
}
- final ByteString normalizedValue = getNormalizeValue();
+
+ final ByteString normalizedValue = getOrderingNormalizedValue();
+ final ByteString otherNormalizedValue = ava.getOrderingNormalizedValue();
final MatchingRule rule = attributeType.getOrderingMatchingRule();
- try
+ if (rule != null)
{
- if (rule != null)
- {
- // Check equality assertion first.
- final Assertion lteAssertion = rule
- .getLessOrEqualAssertion(ava.attributeValue);
- final ConditionResult lteResult = lteAssertion.matches(normalizedValue);
- final Assertion gteAssertion = rule
- .getGreaterOrEqualAssertion(ava.attributeValue);
- final ConditionResult gteResult = gteAssertion.matches(normalizedValue);
-
- if (lteResult.equals(gteResult))
- {
- // it is equal to the assertion value.
- return 0;
- }
- else if (lteResult == ConditionResult.TRUE)
- {
- return -1;
- }
- else
- {
- return 1;
- }
- }
+ final Comparator<ByteSequence> comparator = rule.comparator();
+ return comparator.compare(normalizedValue, otherNormalizedValue);
}
- catch (final DecodeException de)
+ else
{
- // use the bytestring comparison as default.
+ return normalizedValue.compareTo(otherNormalizedValue);
}
-
- if (result == 0)
- {
- final ByteString nv1 = normalizedValue;
- final ByteString nv2 = ava.getNormalizeValue();
- result = nv1.compareTo(nv2);
- }
-
- return result;
}
@@ -787,7 +767,26 @@
}
else if (obj instanceof AVA)
{
- return compareTo((AVA) obj) == 0;
+ final AVA ava = (AVA) obj;
+
+ if (!attributeType.equals(ava.attributeType))
+ {
+ return false;
+ }
+
+ final ByteString normalizedValue = getEqualityNormalizedValue();
+ final ByteString otherNormalizedValue = ava.getEqualityNormalizedValue();
+ final MatchingRule rule = attributeType.getEqualityMatchingRule();
+ if (rule != null)
+ {
+ final Comparator<ByteSequence> comparator = rule.comparator();
+ return comparator.compare(normalizedValue, otherNormalizedValue) != 0 ? false
+ : true;
+ }
+ else
+ {
+ return normalizedValue.equals(otherNormalizedValue);
+ }
}
else
{
@@ -827,7 +826,8 @@
@Override
public int hashCode()
{
- return attributeType.hashCode() * 31 + getNormalizeValue().hashCode();
+ return attributeType.hashCode() * 31
+ + getEqualityNormalizedValue().hashCode();
}
@@ -844,25 +844,6 @@
- private ByteString getNormalizeValue()
- {
- final MatchingRule matchingRule = attributeType.getEqualityMatchingRule();
- if (matchingRule != null)
- {
- try
- {
- return matchingRule.normalizeAttributeValue(attributeValue);
- }
- catch (final DecodeException de)
- {
- // Ignore - we'll drop back to the user provided value.
- }
- }
- return attributeValue;
- }
-
-
-
StringBuilder toString(final StringBuilder builder)
{
if (!attributeType.getNames().iterator().hasNext())
@@ -925,4 +906,72 @@
}
return builder;
}
+
+
+
+ private ByteString getEqualityNormalizedValue()
+ {
+ final ByteString normalizedValue = equalityNormalizedAttributeValue;
+
+ if (normalizedValue != null)
+ {
+ return normalizedValue;
+ }
+
+ final MatchingRule matchingRule = attributeType.getEqualityMatchingRule();
+ if (matchingRule != null)
+ {
+ try
+ {
+ equalityNormalizedAttributeValue = matchingRule
+ .normalizeAttributeValue(attributeValue);
+ }
+ catch (final DecodeException de)
+ {
+ // Unable to normalize, so default to byte-wise comparison.
+ equalityNormalizedAttributeValue = attributeValue;
+ }
+ }
+ else
+ {
+ // No matching rule, so default to byte-wise comparison.
+ equalityNormalizedAttributeValue = attributeValue;
+ }
+
+ return equalityNormalizedAttributeValue;
+ }
+
+
+
+ private ByteString getOrderingNormalizedValue()
+ {
+ final ByteString normalizedValue = orderingNormalizedAttributeValue;
+
+ if (normalizedValue != null)
+ {
+ return normalizedValue;
+ }
+
+ final MatchingRule matchingRule = attributeType.getEqualityMatchingRule();
+ if (matchingRule != null)
+ {
+ try
+ {
+ orderingNormalizedAttributeValue = matchingRule
+ .normalizeAttributeValue(attributeValue);
+ }
+ catch (final DecodeException de)
+ {
+ // Unable to normalize, so default to equality matching.
+ orderingNormalizedAttributeValue = getEqualityNormalizedValue();
+ }
+ }
+ else
+ {
+ // No matching rule, so default to equality matching.
+ orderingNormalizedAttributeValue = getEqualityNormalizedValue();
+ }
+
+ return orderingNormalizedAttributeValue;
+ }
}
diff --git a/sdk/tests/unit-tests-testng/src/com/sun/opends/sdk/ldap/ASN1BufferReaderTestCase.java b/sdk/tests/unit-tests-testng/src/com/sun/opends/sdk/ldap/ASN1BufferReaderTestCase.java
index 68bfa1a..5c33709 100644
--- a/sdk/tests/unit-tests-testng/src/com/sun/opends/sdk/ldap/ASN1BufferReaderTestCase.java
+++ b/sdk/tests/unit-tests-testng/src/com/sun/opends/sdk/ldap/ASN1BufferReaderTestCase.java
@@ -35,6 +35,7 @@
import org.opends.sdk.asn1.ASN1Reader;
import org.opends.sdk.asn1.ASN1ReaderTestCase;
+import org.glassfish.grizzly.TransportFactory;
import org.glassfish.grizzly.memory.ByteBufferWrapper;
@@ -49,7 +50,8 @@
throws IOException
{
final ByteBufferWrapper buffer = new ByteBufferWrapper(ByteBuffer.wrap(b));
- final ASN1BufferReader reader = new ASN1BufferReader(maxElementSize);
+ final ASN1BufferReader reader = new ASN1BufferReader(maxElementSize,
+ TransportFactory.getInstance().getDefaultMemoryManager());
reader.appendBytesRead(buffer);
return reader;
}
diff --git a/sdk/tests/unit-tests-testng/src/com/sun/opends/sdk/ldap/ASN1BufferWriterTestCase.java b/sdk/tests/unit-tests-testng/src/com/sun/opends/sdk/ldap/ASN1BufferWriterTestCase.java
index f1d4cf2..18125d4 100644
--- a/sdk/tests/unit-tests-testng/src/com/sun/opends/sdk/ldap/ASN1BufferWriterTestCase.java
+++ b/sdk/tests/unit-tests-testng/src/com/sun/opends/sdk/ldap/ASN1BufferWriterTestCase.java
@@ -38,6 +38,7 @@
import org.opends.sdk.asn1.ASN1WriterTestCase;
import org.glassfish.grizzly.Buffer;
+import org.glassfish.grizzly.TransportFactory;
import org.glassfish.grizzly.memory.ByteBufferWrapper;
@@ -68,7 +69,8 @@
throws DecodeException, IOException
{
final ByteBufferWrapper buffer = new ByteBufferWrapper(ByteBuffer.wrap(encodedBytes));
- final ASN1BufferReader reader = new ASN1BufferReader(0);
+ final ASN1BufferReader reader = new ASN1BufferReader(0, TransportFactory
+ .getInstance().getDefaultMemoryManager());
reader.appendBytesRead(buffer);
return reader;
}
--
Gitblit v1.10.0