From e4e9b2ebc7d41715fc0c0c8ba07f897fe63a688e Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Wed, 16 Jan 2008 23:19:50 +0000
Subject: [PATCH] This fix removes the option to use nanosecond etime resolution as a JVM property. It is now a global configuration attribute. Due to the 10% throughput decrease I saw when using System.nanoTime, the default still uses System.currentTimeMillis to timestamp operations. System.nanoTime will only be used when the ds-cfg-etime-resolution attribute is set to nano-seconds.
---
opends/resource/schema/02-config.ldif | 8
opends/src/server/org/opends/server/core/SearchOperationBasis.java | 16
opends/src/server/org/opends/server/util/TimeThread.java | 19 +
opends/src/server/org/opends/server/types/AbstractOperation.java | 63 ++++-
opends/resource/config/config.ldif | 1
opends/src/server/org/opends/server/loggers/AccessLogger.java | 415 ++++++++++++++++++++--------------------
opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml | 32 +++
opends/src/server/org/opends/server/core/CoreConfigManager.java | 12
opends/src/server/org/opends/server/util/ServerConstants.java | 10
9 files changed, 326 insertions(+), 250 deletions(-)
diff --git a/opends/resource/config/config.ldif b/opends/resource/config/config.ldif
index 8e6d921..3548cd4 100644
--- a/opends/resource/config/config.ldif
+++ b/opends/resource/config/config.ldif
@@ -49,6 +49,7 @@
ds-cfg-return-bind-error-messages: false
ds-cfg-idle-time-limit: 0 seconds
ds-cfg-save-config-on-successful-startup: true
+ds-cfg-etime-resolution: milli-seconds
ds-cfg-allowed-task: org.opends.server.tasks.AddSchemaFileTask
ds-cfg-allowed-task: org.opends.server.tasks.BackupTask
ds-cfg-allowed-task: org.opends.server.tasks.DisconnectClientTask
diff --git a/opends/resource/schema/02-config.ldif b/opends/resource/schema/02-config.ldif
index a88fbdf..e818a99 100644
--- a/opends/resource/schema/02-config.ldif
+++ b/opends/resource/schema/02-config.ldif
@@ -2172,6 +2172,11 @@
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
SINGLE-VALUE
X-ORIGIN 'OpenDS Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.26027.1.1.442
+ NAME 'ds-cfg-etime-resolution'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.444
NAME 'ds-task-reset-generation-id-new-value'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
@@ -2582,7 +2587,8 @@
ds-cfg-return-bind-error-messages $
ds-cfg-idle-time-limit $
ds-cfg-workflow-configuration-mode $
- ds-cfg-save-config-on-successful-startup )
+ ds-cfg-save-config-on-successful-startup $
+ ds-cfg-etime-resolution )
X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.40
NAME 'ds-cfg-root-dn-user'
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
index a082507..3a5f55f 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
@@ -778,4 +778,36 @@
</ldap:attribute>
</adm:profile>
</adm:property>
+ <adm:property name="etime-resolution" mandatory="false">
+ <adm:synopsis>
+ The resolution to use for operation elapsed processing time (etime)
+ measurements.
+ </adm:synopsis>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>
+ milli-seconds
+ </adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:enumeration>
+ <adm:value name="milli-seconds">
+ <adm:synopsis>
+ Use milli-second resolution.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="nano-seconds">
+ <adm:synopsis>
+ Use nano-second resolution.
+ </adm:synopsis>
+ </adm:value>
+ </adm:enumeration>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-etime-resolution</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
</adm:managed-object>
diff --git a/opends/src/server/org/opends/server/core/CoreConfigManager.java b/opends/src/server/org/opends/server/core/CoreConfigManager.java
index f9fa411..8d5ca58 100644
--- a/opends/src/server/org/opends/server/core/CoreConfigManager.java
+++ b/opends/src/server/org/opends/server/core/CoreConfigManager.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ * Portions Copyright 2006-2008 Sun Microsystems, Inc.
*/
package org.opends.server.core;
import org.opends.messages.Message;
@@ -42,12 +42,7 @@
import org.opends.server.admin.std.server.RootCfg;
import org.opends.server.admin.server.ServerManagementContext;
import org.opends.server.config.ConfigException;
-import org.opends.server.types.AcceptRejectWarn;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.Privilege;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.WritabilityMode;
+import org.opends.server.types.*;
import static org.opends.messages.ConfigMessages.*;
@@ -357,6 +352,9 @@
{
DirectoryServer.setWorkflowConfigurationMode(newMode);
}
+
+ AbstractOperation.setUseNanoTime(globalConfig.getEtimeResolution() ==
+ GlobalCfgDefn.EtimeResolution.NANO_SECONDS);
}
diff --git a/opends/src/server/org/opends/server/core/SearchOperationBasis.java b/opends/src/server/org/opends/server/core/SearchOperationBasis.java
index b3244ac..927fa69 100644
--- a/opends/src/server/org/opends/server/core/SearchOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Portions Copyright 2007 Sun Microsystems, Inc.
+ * Portions Copyright 2006-2008 Sun Microsystems, Inc.
*/
package org.opends.server.core;
@@ -627,8 +627,9 @@
// See if the time limit has expired. If so, then don't send the entry and
// indicate that the search should end.
- if ((getTimeLimit() > 0) && (TimeThread.getTime() >=
- getTimeLimitExpiration()))
+ if ((getTimeLimit() > 0) &&
+ ((getUseNanoTime() ? TimeThread.getNanoTime() :
+ TimeThread.getTime()) >= getTimeLimitExpiration()))
{
setResultCode(ResultCode.TIME_LIMIT_EXCEEDED);
appendErrorMessage(ERR_SEARCH_TIME_LIMIT_EXCEEDED.get(getTimeLimit()));
@@ -1054,8 +1055,9 @@
// See if the time limit has expired. If so, then don't send the entry and
// indicate that the search should end.
- if ((getTimeLimit() > 0) && (TimeThread.getTime() >=
- getTimeLimitExpiration()))
+ if ((getTimeLimit() > 0) &&
+ ((getUseNanoTime() ? TimeThread.getNanoTime() :
+ TimeThread.getTime()) >= getTimeLimitExpiration()))
{
setResultCode(ResultCode.TIME_LIMIT_EXCEEDED);
appendErrorMessage(ERR_SEARCH_TIME_LIMIT_EXCEEDED.get(getTimeLimit()));
@@ -1623,8 +1625,8 @@
else
{
// FIXME -- Factor in the user's effective time limit.
- timeLimitExpiration =
- getProcessingStartTime() + (1000L * timeLimit);
+ timeLimitExpiration = getProcessingStartTime() +
+ ((getUseNanoTime() ? 1000000000L : 1000L) * timeLimit);
}
setTimeLimitExpiration(timeLimitExpiration);
diff --git a/opends/src/server/org/opends/server/loggers/AccessLogger.java b/opends/src/server/org/opends/server/loggers/AccessLogger.java
index d6e86c2..4e055ad 100644
--- a/opends/src/server/org/opends/server/loggers/AccessLogger.java
+++ b/opends/src/server/org/opends/server/loggers/AccessLogger.java
@@ -71,23 +71,24 @@
private static final DebugTracer TRACER = getTracer();
// The set of access loggers that have been registered with the server. It
- // will initially be empty.
- static CopyOnWriteArrayList<AccessLogPublisher> accessPublishers =
- new CopyOnWriteArrayList<AccessLogPublisher>();
+ // will initially be empty.
+ static CopyOnWriteArrayList<AccessLogPublisher> accessPublishers =
+ new CopyOnWriteArrayList<AccessLogPublisher>();
- // The singleton instance of this class for configuration purposes.
- static final AccessLogger instance = new AccessLogger();
+ // The singleton instance of this class for configuration purposes.
+ static final AccessLogger instance = new AccessLogger();
- /**
- * Retrieve the singleton instance of this class.
- *
- * @return The singleton instance of this logger.
- */
- public static AccessLogger getInstance()
- {
- return instance;
- }
+
+ /**
+ * Retrieve the singleton instance of this class.
+ *
+ * @return The singleton instance of this logger.
+ */
+ public static AccessLogger getInstance()
+ {
+ return instance;
+ }
/**
* Add an access log publisher to the access logger.
@@ -144,101 +145,101 @@
* If a problem occurs during initialization that is not
* related to the server configuration.
*/
- public void initializeAccessLogger(List<AccessLogPublisherCfg> configs)
- throws ConfigException, InitializationException
- {
- for(AccessLogPublisherCfg config : configs)
- {
- config.addAccessChangeListener(this);
+ public void initializeAccessLogger(List<AccessLogPublisherCfg> configs)
+ throws ConfigException, InitializationException
+ {
+ for(AccessLogPublisherCfg config : configs)
+ {
+ config.addAccessChangeListener(this);
- if(config.isEnabled())
- {
- AccessLogPublisher AccessLogPublisher = getAccessPublisher(config);
+ if(config.isEnabled())
+ {
+ AccessLogPublisher AccessLogPublisher = getAccessPublisher(config);
- addAccessLogPublisher(AccessLogPublisher);
- }
- }
- }
+ addAccessLogPublisher(AccessLogPublisher);
+ }
+ }
+ }
/**
* {@inheritDoc}
*/
- public boolean isConfigurationAddAcceptable(
- AccessLogPublisherCfg config,
- List<Message> unacceptableReasons)
- {
- return !config.isEnabled() ||
- isJavaClassAcceptable(config, unacceptableReasons);
- }
+ public boolean isConfigurationAddAcceptable(
+ AccessLogPublisherCfg config,
+ List<Message> unacceptableReasons)
+ {
+ return !config.isEnabled() ||
+ isJavaClassAcceptable(config, unacceptableReasons);
+ }
/**
* {@inheritDoc}
*/
- public boolean isConfigurationChangeAcceptable(
- AccessLogPublisherCfg config,
- List<Message> unacceptableReasons)
- {
- return !config.isEnabled() ||
- isJavaClassAcceptable(config, unacceptableReasons);
- }
+ public boolean isConfigurationChangeAcceptable(
+ AccessLogPublisherCfg config,
+ List<Message> unacceptableReasons)
+ {
+ return !config.isEnabled() ||
+ isJavaClassAcceptable(config, unacceptableReasons);
+ }
/**
* {@inheritDoc}
*/
- public ConfigChangeResult applyConfigurationAdd(AccessLogPublisherCfg config)
- {
- // Default result code.
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
+ public ConfigChangeResult applyConfigurationAdd(AccessLogPublisherCfg config)
+ {
+ // Default result code.
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ ArrayList<Message> messages = new ArrayList<Message>();
- config.addAccessChangeListener(this);
+ config.addAccessChangeListener(this);
- if(config.isEnabled())
- {
- try
- {
- AccessLogPublisher AccessLogPublisher = getAccessPublisher(config);
+ if(config.isEnabled())
+ {
+ try
+ {
+ AccessLogPublisher AccessLogPublisher = getAccessPublisher(config);
- addAccessLogPublisher(AccessLogPublisher);
- }
- catch(ConfigException e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
- messages.add(e.getMessageObject());
- resultCode = DirectoryServer.getServerErrorResultCode();
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
+ addAccessLogPublisher(AccessLogPublisher);
+ }
+ catch(ConfigException e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+ messages.add(e.getMessageObject());
+ resultCode = DirectoryServer.getServerErrorResultCode();
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
- messages.add(ERR_CONFIG_LOGGER_CANNOT_CREATE_LOGGER.get(
- String.valueOf(config.dn().toString()),
- stackTraceToSingleLineString(e)));
- resultCode = DirectoryServer.getServerErrorResultCode();
- }
- }
- return new ConfigChangeResult(resultCode, adminActionRequired, messages);
- }
+ messages.add(ERR_CONFIG_LOGGER_CANNOT_CREATE_LOGGER.get(
+ String.valueOf(config.dn().toString()),
+ stackTraceToSingleLineString(e)));
+ resultCode = DirectoryServer.getServerErrorResultCode();
+ }
+ }
+ return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ }
/**
* {@inheritDoc}
*/
- public ConfigChangeResult applyConfigurationChange(
- AccessLogPublisherCfg config)
- {
- // Default result code.
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
+ public ConfigChangeResult applyConfigurationChange(
+ AccessLogPublisherCfg config)
+ {
+ // Default result code.
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ ArrayList<Message> messages = new ArrayList<Message>();
- DN dn = config.dn();
+ DN dn = config.dn();
AccessLogPublisher accessLogPublisher = null;
for(AccessLogPublisher publisher : accessPublishers)
@@ -250,47 +251,47 @@
}
}
- if(accessLogPublisher == null)
- {
- if(config.isEnabled())
- {
- // Needs to be added and enabled.
- return applyConfigurationAdd(config);
- }
- }
- else
- {
- if(config.isEnabled())
- {
- // The publisher is currently active, so we don't need to do anything.
- // Changes to the class name cannot be
- // applied dynamically, so if the class name did change then
- // indicate that administrative action is required for that
- // change to take effect.
- String className = config.getJavaClass();
- if(!className.equals(accessLogPublisher.getClass().getName()))
- {
- adminActionRequired = true;
- }
- }
- else
- {
- // The publisher is being disabled so shut down and remove.
- removeAccessLogPublisher(accessLogPublisher);
- }
- }
+ if(accessLogPublisher == null)
+ {
+ if(config.isEnabled())
+ {
+ // Needs to be added and enabled.
+ return applyConfigurationAdd(config);
+ }
+ }
+ else
+ {
+ if(config.isEnabled())
+ {
+ // The publisher is currently active, so we don't need to do anything.
+ // Changes to the class name cannot be
+ // applied dynamically, so if the class name did change then
+ // indicate that administrative action is required for that
+ // change to take effect.
+ String className = config.getJavaClass();
+ if(!className.equals(accessLogPublisher.getClass().getName()))
+ {
+ adminActionRequired = true;
+ }
+ }
+ else
+ {
+ // The publisher is being disabled so shut down and remove.
+ removeAccessLogPublisher(accessLogPublisher);
+ }
+ }
- return new ConfigChangeResult(resultCode, adminActionRequired, messages);
- }
+ return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ }
/**
* {@inheritDoc}
*/
- public boolean isConfigurationDeleteAcceptable(
- AccessLogPublisherCfg config,
- List<Message> unacceptableReasons)
- {
- DN dn = config.dn();
+ public boolean isConfigurationDeleteAcceptable(
+ AccessLogPublisherCfg config,
+ List<Message> unacceptableReasons)
+ {
+ DN dn = config.dn();
AccessLogPublisher accessLogPublisher = null;
for(AccessLogPublisher publisher : accessPublishers)
@@ -302,14 +303,14 @@
}
}
- return accessLogPublisher != null;
+ return accessLogPublisher != null;
- }
+ }
/**
* {@inheritDoc}
*/
- public ConfigChangeResult applyConfigurationDelete(
+ public ConfigChangeResult applyConfigurationDelete(
AccessLogPublisherCfg config)
{
// Default result code.
@@ -338,92 +339,92 @@
return new ConfigChangeResult(resultCode, adminActionRequired);
}
- private boolean isJavaClassAcceptable(AccessLogPublisherCfg config,
- List<Message> unacceptableReasons)
- {
- String className = config.getJavaClass();
- AccessLogPublisherCfgDefn d = AccessLogPublisherCfgDefn.getInstance();
- ClassPropertyDefinition pd =
- d.getJavaClassPropertyDefinition();
- // Load the class and cast it to a DebugLogPublisher.
- AccessLogPublisher publisher = null;
- Class<? extends AccessLogPublisher> theClass;
- try {
- theClass = pd.loadClass(className, AccessLogPublisher.class);
- publisher = theClass.newInstance();
- } catch (Exception e) {
- Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
- className,
- config.dn().toString(),
- String.valueOf(e));
- unacceptableReasons.add(message);
- return false;
- }
- // Check that the implementation class implements the correct interface.
- try {
- // Determine the initialization method to use: it must take a
- // single parameter which is the exact type of the configuration
- // object.
- Method method = theClass.getMethod("isConfigurationAcceptable",
- AccessLogPublisherCfg.class,
- List.class);
- Boolean acceptable = (Boolean) method.invoke(publisher, config,
- unacceptableReasons);
+ private boolean isJavaClassAcceptable(AccessLogPublisherCfg config,
+ List<Message> unacceptableReasons)
+ {
+ String className = config.getJavaClass();
+ AccessLogPublisherCfgDefn d = AccessLogPublisherCfgDefn.getInstance();
+ ClassPropertyDefinition pd =
+ d.getJavaClassPropertyDefinition();
+ // Load the class and cast it to a DebugLogPublisher.
+ AccessLogPublisher publisher = null;
+ Class<? extends AccessLogPublisher> theClass;
+ try {
+ theClass = pd.loadClass(className, AccessLogPublisher.class);
+ publisher = theClass.newInstance();
+ } catch (Exception e) {
+ Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
+ className,
+ config.dn().toString(),
+ String.valueOf(e));
+ unacceptableReasons.add(message);
+ return false;
+ }
+ // Check that the implementation class implements the correct interface.
+ try {
+ // Determine the initialization method to use: it must take a
+ // single parameter which is the exact type of the configuration
+ // object.
+ Method method = theClass.getMethod("isConfigurationAcceptable",
+ AccessLogPublisherCfg.class,
+ List.class);
+ Boolean acceptable = (Boolean) method.invoke(publisher, config,
+ unacceptableReasons);
- if (! acceptable)
- {
- return false;
- }
- } catch (Exception e) {
- Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
- className,
- config.dn().toString(),
- String.valueOf(e));
- unacceptableReasons.add(message);
- return false;
- }
- // The class is valid as far as we can tell.
- return true;
- }
+ if (! acceptable)
+ {
+ return false;
+ }
+ } catch (Exception e) {
+ Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
+ className,
+ config.dn().toString(),
+ String.valueOf(e));
+ unacceptableReasons.add(message);
+ return false;
+ }
+ // The class is valid as far as we can tell.
+ return true;
+ }
- private AccessLogPublisher getAccessPublisher(AccessLogPublisherCfg config)
- throws ConfigException {
- String className = config.getJavaClass();
- AccessLogPublisherCfgDefn d = AccessLogPublisherCfgDefn.getInstance();
- ClassPropertyDefinition pd =
- d.getJavaClassPropertyDefinition();
- // Load the class and cast it to a AccessLogPublisher.
- Class<? extends AccessLogPublisher> theClass;
- AccessLogPublisher AccessLogPublisher;
- try {
- theClass = pd.loadClass(className, AccessLogPublisher.class);
- AccessLogPublisher = theClass.newInstance();
+ private AccessLogPublisher getAccessPublisher(AccessLogPublisherCfg config)
+ throws ConfigException {
+ String className = config.getJavaClass();
+ AccessLogPublisherCfgDefn d = AccessLogPublisherCfgDefn.getInstance();
+ ClassPropertyDefinition pd =
+ d.getJavaClassPropertyDefinition();
+ // Load the class and cast it to a AccessLogPublisher.
+ Class<? extends AccessLogPublisher> theClass;
+ AccessLogPublisher AccessLogPublisher;
+ try {
+ theClass = pd.loadClass(className, AccessLogPublisher.class);
+ AccessLogPublisher = theClass.newInstance();
- // Determine the initialization method to use: it must take a
- // single parameter which is the exact type of the configuration
- // object.
- Method method = theClass.getMethod("initializeAccessLogPublisher", config
+ // Determine the initialization method to use: it must take a
+ // single parameter which is the exact type of the configuration
+ // object.
+ Method method = theClass.getMethod("initializeAccessLogPublisher", config
.configurationClass());
- method.invoke(AccessLogPublisher, config);
- }
- catch (InvocationTargetException ite)
- {
- // Rethrow the exceptions thrown be the invoked method.
- Throwable e = ite.getTargetException();
- Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
- className, config.dn().toString(), stackTraceToSingleLineString(e));
- throw new ConfigException(message, e);
- }
- catch (Exception e)
- {
- Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
- className, config.dn().toString(), String.valueOf(e));
- throw new ConfigException(message, e);
- }
+ method.invoke(AccessLogPublisher, config);
+ }
+ catch (InvocationTargetException ite)
+ {
+ // Rethrow the exceptions thrown be the invoked method.
+ Throwable e = ite.getTargetException();
+ Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
+ className, config.dn().toString(), stackTraceToSingleLineString(e));
+ throw new ConfigException(message, e);
+ }
+ catch (Exception e)
+ {
+ Message message = ERR_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS.get(
+ className, config.dn().toString(), String.valueOf(e));
+ throw new ConfigException(message, e);
+ }
- // The access publisher has been successfully initialized.
- return AccessLogPublisher;
- }
+ // The access publisher has been successfully initialized.
+ return AccessLogPublisher;
+ }
@@ -569,7 +570,7 @@
/**
- * Writes a message to the access logger with information about the compare
+ * Writes a message to the access logger with information about the compare
* request associated with the provided compare operation.
*
* @param compareOperation The compare operation containing the information
diff --git a/opends/src/server/org/opends/server/types/AbstractOperation.java b/opends/src/server/org/opends/server/types/AbstractOperation.java
index 7866fca..2ba15a7 100644
--- a/opends/src/server/org/opends/server/types/AbstractOperation.java
+++ b/opends/src/server/org/opends/server/types/AbstractOperation.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Portions Copyright 2007 Sun Microsystems, Inc.
+ * Portions Copyright 2006-2008 Sun Microsystems, Inc.
*/
package org.opends.server.types;
import org.opends.messages.Message;
@@ -74,16 +74,6 @@
*/
protected static boolean useNanoTime = false;
- static
- {
- if(System.getProperty(PROPERTY_ETIME_NANO) != null &&
- System.getProperty(PROPERTY_ETIME_NANO).
- equalsIgnoreCase("true"))
- {
- useNanoTime = true;
- }
- }
-
/**
* The client connection with which this operation is associated.
@@ -104,6 +94,12 @@
protected final long operationID;
+ /**
+ * Wether nanotime was used for this operation.
+ */
+ protected final boolean usingNanoTime;
+
+
// Indicates whether this is an internal operation triggered within
// the server itself rather than requested by an external client.
@@ -172,6 +168,7 @@
this.clientConnection = clientConnection;
this.operationID = operationID;
this.messageID = messageID;
+ this.usingNanoTime = useNanoTime;
if (requestControls == null)
{
@@ -1045,7 +1042,7 @@
*/
public final void setProcessingStartTime()
{
- if(useNanoTime)
+ if(usingNanoTime)
{
processingStartTime = System.nanoTime();
}
@@ -1078,7 +1075,7 @@
*/
public final void setProcessingStopTime()
{
- if(useNanoTime)
+ if(usingNanoTime)
{
this.processingStopTime = System.nanoTime();
}
@@ -1091,12 +1088,13 @@
/**
- * Retrieves the length of time in milliseconds that the server
- * spent processing this operation. This should not be called until
- * after the server has sent the response to the client.
+ * Retrieves the length of time in milliseconds or nanoseconds that
+ * the server spent processing this operation. This should not be
+ * called until after the server has sent the response to the
+ * client.
*
- * @return The length of time in milliseconds that the server spent
- * processing this operation.
+ * @return The length of time in milliseconds or nanoseconds that
+ * the server spent processing this operation.
*/
public final long getProcessingTime()
{
@@ -1106,6 +1104,35 @@
/**
+ * Set whether to use nanoTime for the processing time methods.
+ *
+ * @param useNanoTime <code>true</code> to use System.nanoTime
+ * or <code>false</code> to use
+ * System.currentTimeMillis
+ */
+ public static void setUseNanoTime(boolean useNanoTime)
+ {
+ AbstractOperation.useNanoTime = useNanoTime;
+ }
+
+
+
+ /**
+ * Get whether this operation used System.nanoTime or
+ * System.currentTimeMillis for the processing time methods.
+ *
+ * @return <code>true</code> if System.nanoTime is used or
+ * <code>false</code> if System.currentTimeMillis
+ * was used.
+ */
+ public final boolean getUseNanoTime()
+ {
+ return usingNanoTime;
+ }
+
+
+
+ /**
* Performs the work of actually processing this operation. This
* should include all processing for the operation, including
* invoking pre-parse and post-response plugins, logging messages
diff --git a/opends/src/server/org/opends/server/util/ServerConstants.java b/opends/src/server/org/opends/server/util/ServerConstants.java
index eb68b8f..6c047fb 100644
--- a/opends/src/server/org/opends/server/util/ServerConstants.java
+++ b/opends/src/server/org/opends/server/util/ServerConstants.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ * Portions Copyright 2006-2008 Sun Microsystems, Inc.
*/
package org.opends.server.util;
@@ -2770,14 +2770,6 @@
"org.opends.server.UseLastKnownGoodConfiguration";
- /**
- * The name of the system property that can be used to configure the
- * server to report etimes in nanoseconds instead of milliseconds.
- */
- public static final String PROPERTY_ETIME_NANO =
- "org.opends.server.etime.nano";
-
-
/**
* The column at which to wrap long lines of output in the command-line tools.
diff --git a/opends/src/server/org/opends/server/util/TimeThread.java b/opends/src/server/org/opends/server/util/TimeThread.java
index 27a311d..63e9c12 100644
--- a/opends/src/server/org/opends/server/util/TimeThread.java
+++ b/opends/src/server/org/opends/server/util/TimeThread.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ * Portions Copyright 2006-2008 Sun Microsystems, Inc.
*/
package org.opends.server.util;
@@ -93,6 +93,9 @@
// The current time in milliseconds since the epoch.
private static volatile long time;
+ // The current time in nanoseconds.
+ private static volatile long nanoTime;
+
// The date formatter that will be used to obtain the generalized time.
private static SimpleDateFormat generalizedTimeFormatter;
@@ -139,6 +142,7 @@
calendar = new GregorianCalendar();
date = calendar.getTime();
time = date.getTime();
+ nanoTime = System.nanoTime();
generalizedTime = generalizedTimeFormatter.format(date);
localTimestamp = localTimestampFormatter.format(date);
gmtTimestamp = gmtTimestampFormatter.format(date);
@@ -163,6 +167,7 @@
calendar = new GregorianCalendar();
date = calendar.getTime();
time = date.getTime();
+ nanoTime = System.nanoTime();
generalizedTime = generalizedTimeFormatter.format(date);
localTimestamp = localTimestampFormatter.format(date);
gmtTimestamp = gmtTimestampFormatter.format(date);
@@ -223,6 +228,18 @@
return time;
}
+ /**
+ * Retrieves the time in nanoseconds from the most precise available system
+ * timer. The value retured represents nanoseconds since some fixed but
+ * arbitrary time.
+ *
+ * @return The time in nanoseconds from some fixed but arbitrary time.
+ */
+ public static long getNanoTime()
+ {
+ return nanoTime;
+ }
+
/**
--
Gitblit v1.10.0