lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From andyetitmo...@apache.org
Subject svn commit: r1694798 [1/3] - in /lucene/dev/trunk: lucene/tools/forbiddenApis/ solr/ solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/ solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/ solr/con...
Date Sat, 08 Aug 2015 13:40:00 GMT
Author: andyetitmoves
Date: Sat Aug  8 13:39:58 2015
New Revision: 1694798

URL: http://svn.apache.org/r1694798
Log:
SOLR-7859: Clamp down on use of System.currentTimeMillis

 - Use RTimer where currentTimeMillis is used for timing
 - Abstract out a new class TimeOut for when currentTimeMillis/nanoTime
   is used to timeout operations.
 - Used `new Date()` in some cases where that is the logical intent.
 - Deprecated a couple of APIs which were publicly exposing epoch time,
   in favour of Date objects to make the intent clearer.
 - A couple of cases had currentTimeMillis in dead code.
 - In some cases where currentTimeMillis was used to just generate a name,
   used nanoTime instead (really it should be some sequence/random number
   in such a case).
 - In some other cases where stamps were used for SQL queries, HTTP headers,
   comparing against data in external files, ZK etc., used SuppressForbidden.
 - Also currently allow the use of currentTimeMillis in commit data,
   this is then used in replication -- this is concerning since absolute
   times are being compared, but that can be dealt with separately.


Added:
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/TimeOut.java   (with props)
Modified:
    lucene/dev/trunk/lucene/tools/forbiddenApis/solr.txt
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/MailEntityProcessor.java
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractDataImportHandlerTestCase.java
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractSqlEntityProcessorTestCase.java
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestFileListEntityProcessor.java
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSimplePropertiesWriter.java
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestZKPropertiesWriter.java
    lucene/dev/trunk/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java
    lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java
    lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java
    lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/LeaderInitiatedRecoveryThread.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrCore.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/CdcrReplicatorState.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/DebugComponent.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/OpenExchangeRatesOrgProvider.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/servlet/cache/HttpCacheHeaderUtil.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/store/blockcache/BlockCacheLocation.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateLog.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/VersionInfo.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/SimplePostTool.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/SolrLogLayout.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/stats/Clock.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/xslt/TransformerProvider.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/DistributedIntervalFacetingTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/SolrInfoMBeanTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPISolrJTests.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ConcurrentDeleteAndCreateCollectionTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/DeleteInactiveReplicaTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/DeleteLastCustomShardedReplicaTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/DeleteReplicaTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/DistribDocExpirationUpdateProcessorTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderInitiatedRecoveryOnCommitTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/MigrateRouteKeyTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/OverseerCollectionProcessorTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/OverseerRolesTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/SolrXmlInZkTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestRebalanceLeaders.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ZkCLITest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/hdfs/StressHdfsTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/OpenCloseCoreStressTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestBlobHandler.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminHandlerTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/request/TestWriterPerf.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/AbstractCurrencyFieldTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/OpenExchangeRatesOrgProviderTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/DocSetPerf.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestFastLRUCache.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestSearchPerf.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestSolrJ.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/servlet/CacheHeaderTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/servlet/NoCacheHeaderTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/AutoCommitTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/SoftAutoCommitTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/TestIndexingPerformance.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/BitSetPerf.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/TestUtils.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrClient.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/ParallelStream.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/RoutingRule.java
    lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTestsBase.java
    lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrClient.java
    lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/common/util/TestJavaBinCodec.java
    lucene/dev/trunk/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
    lucene/dev/trunk/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java
    lucene/dev/trunk/solr/test-framework/src/java/org/apache/solr/cloud/ZkTestServer.java

Modified: lucene/dev/trunk/lucene/tools/forbiddenApis/solr.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/tools/forbiddenApis/solr.txt?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/tools/forbiddenApis/solr.txt (original)
+++ lucene/dev/trunk/lucene/tools/forbiddenApis/solr.txt Sat Aug  8 13:39:58 2015
@@ -30,4 +30,7 @@ java.util.concurrent.ThreadPoolExecutor#
 
 @defaultMessage Use slf4j classes instead
 org.apache.log4j.**
-java.util.logging.**
\ No newline at end of file
+java.util.logging.**
+
+@defaultMessage Use RTimer/TimeOut/System.nanoTime for time comparisons, and `new Date()` output/debugging/stats of timestamps. If for some miscellaneous reason, you absolutely need to use this, use a SuppressForbidden.
+java.lang.System#currentTimeMillis()

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Sat Aug  8 13:39:58 2015
@@ -87,6 +87,10 @@ Jetty 9.2.11.v20150529
 Upgrading from Solr 5.3
 -----------------------
 
+* SOLR-7859: The following APIs are now deprecated:
+  - SolrCore.getStartTime: Use SolrCore.getStartTimeStamp instead.
+  - SolrIndexSearcher.getOpenTime: Use SolrIndexSearcher.getOpenTimeStamp instead.
+
 Detailed Change List
 ----------------------
 
@@ -108,6 +112,9 @@ New Features
 Bug Fixes
 ----------------------
 
+* SOLR-7859: Fix usage of currentTimeMillis instead of nanoTime in multiple places,
+  whitelist valid uses of currentTimeMillis (Ramkumar Aiyengar)
+
 Optimizations
 ----------------------
 
@@ -345,7 +352,7 @@ Bug Fixes
 * SOLR-7866: VersionInfo caused an unhandled NPE when trying to determine the max value for the
   version field. (Timothy Potter)
 
-* SOLR-7666 (and linked tickets): Many fixes to AngularJS Admin UI bringing it close to feature 
+* SOLR-7666 (and linked tickets): Many fixes to AngularJS Admin UI bringing it close to feature
   parity with existing UI. (Upayavira)
 
 Optimizations

Modified: lucene/dev/trunk/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/MailEntityProcessor.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/MailEntityProcessor.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/MailEntityProcessor.java (original)
+++ lucene/dev/trunk/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/MailEntityProcessor.java Sat Aug  8 13:39:58 2015
@@ -19,6 +19,7 @@ package org.apache.solr.handler.dataimpo
 import com.sun.mail.imap.IMAPMessage;
 
 import org.apache.solr.handler.dataimport.config.ConfigNameConstants;
+import org.apache.solr.util.RTimer;
 import org.apache.tika.Tika;
 import org.apache.tika.metadata.Metadata;
 import org.slf4j.Logger;
@@ -623,8 +624,8 @@ public class MailEntityProcessor extends
           // envelopes; unless you're using gmail server-side filter, which is
           // fast
           LOG.info("Searching folder " + folder.getName() + " for messages");
-          long searchAtMs = System.currentTimeMillis();
-          
+          final RTimer searchTimer = new RTimer();
+
           // If using GMail, speed up the envelope processing by doing a
           // server-side
           // search for messages occurring on or after the fetch date (at
@@ -652,9 +653,8 @@ public class MailEntityProcessor extends
           totalInFolder = messagesInCurBatch.length;
           folder.fetch(messagesInCurBatch, fp);
           current = 0;
-          long tookMs = (System.currentTimeMillis() - searchAtMs);
           LOG.info("Total messages : " + totalInFolder);
-          LOG.info("Search criteria applied. Batching disabled. Took " + tookMs + " (ms)");
+          LOG.info("Search criteria applied. Batching disabled. Took {} (ms)", searchTimer.getTime());
         } else {
           totalInFolder = folder.getMessageCount();
           LOG.info("Total messages : " + totalInFolder);

Modified: lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractDataImportHandlerTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractDataImportHandlerTestCase.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractDataImportHandlerTestCase.java (original)
+++ lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractDataImportHandlerTestCase.java Sat Aug  8 13:39:58 2015
@@ -27,6 +27,7 @@ import java.util.Map;
 import org.apache.commons.io.FileUtils;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SuppressForbidden;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.LocalSolrQueryRequest;
 import org.apache.solr.request.SolrQueryRequest;
@@ -165,6 +166,7 @@ public abstract class AbstractDataImport
     return result;
   }
 
+  @SuppressForbidden(reason = "Needs currentTimeMillis to set modified time for a file")
   public static File createFile(File tmpdir, String name, byte[] content,
                                 boolean changeModifiedTime) throws IOException {
     File file = new File(tmpdir.getAbsolutePath() + File.separator + name);

Modified: lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractSqlEntityProcessorTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractSqlEntityProcessorTestCase.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractSqlEntityProcessorTestCase.java (original)
+++ lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractSqlEntityProcessorTestCase.java Sat Aug  8 13:39:58 2015
@@ -1,6 +1,7 @@
 package org.apache.solr.handler.dataimport;
 
 import junit.framework.Assert;
+import org.apache.solr.common.util.SuppressForbidden;
 import org.junit.After;
 import org.junit.Before;
 
@@ -445,6 +446,7 @@ public abstract class AbstractSqlEntityP
     return nameArr[0];
   }
   
+  @SuppressForbidden(reason = "Needs currentTimeMillis to set change time for SQL query")
   public IntChanges modifySomePeople() throws Exception {
     underlyingDataModified = true;
     int numberToChange = random().nextInt(people.length + 1);
@@ -519,7 +521,8 @@ public abstract class AbstractSqlEntityP
     c.addedKeys = addSet.toArray(new Integer[addSet.size()]);
     return c;
   }
-  
+
+  @SuppressForbidden(reason = "Needs currentTimeMillis to set change time for SQL query")
   public String[] modifySomeCountries() throws Exception {
     underlyingDataModified = true;
     int numberToChange = random().nextInt(countries.length + 1);
@@ -700,6 +703,8 @@ public abstract class AbstractSqlEntityP
     log.debug(config);
     return config;
   }
+
+  @SuppressForbidden(reason = "Needs currentTimeMillis to set change time for SQL query")
   @Override
   protected void populateData(Connection conn) throws Exception {
     Statement s = null;

Modified: lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestFileListEntityProcessor.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestFileListEntityProcessor.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestFileListEntityProcessor.java (original)
+++ lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestFileListEntityProcessor.java Sat Aug  8 13:39:58 2015
@@ -18,6 +18,7 @@ package org.apache.solr.handler.dataimpo
 
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.TestUtil;
+import org.apache.solr.common.util.SuppressForbidden;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -133,6 +134,7 @@ public class TestFileListEntityProcessor
     return fList;
   }
 
+  @SuppressForbidden(reason = "Needs currentTimeMillis to set last modified time")
   @Test
   public void testNTOT() throws IOException {
     File tmpdir = createTempDir().toFile();

Modified: lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSimplePropertiesWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSimplePropertiesWriter.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSimplePropertiesWriter.java (original)
+++ lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSimplePropertiesWriter.java Sat Aug  8 13:39:58 2015
@@ -11,6 +11,7 @@ import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
 
+import org.apache.solr.common.util.SuppressForbidden;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -46,7 +47,8 @@ public class TestSimplePropertiesWriter
     fileLocation = createTempDir().toFile().getAbsolutePath();
     fileName = "the.properties";
   }
- 
+
+  @SuppressForbidden(reason = "Needs currentTimeMillis to construct date stamps")
   @Test
   public void testSimplePropertiesWriter() throws Exception { 
     

Modified: lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestZKPropertiesWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestZKPropertiesWriter.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestZKPropertiesWriter.java (original)
+++ lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestZKPropertiesWriter.java Sat Aug  8 13:39:58 2015
@@ -28,6 +28,7 @@ import java.util.Map;
 import org.apache.solr.cloud.AbstractZkTestCase;
 import org.apache.solr.cloud.ZkTestServer;
 import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.SuppressForbidden;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.request.LocalSolrQueryRequest;
 import org.apache.solr.request.SolrQueryRequest;
@@ -86,6 +87,7 @@ public class TestZKPropertiesWriter exte
     cc = null;
   }
 
+  @SuppressForbidden(reason = "Needs currentTimeMillis to construct date stamps")
   @Test
   public void testZKPropertiesWriter() throws Exception {
     // test using ZooKeeper

Modified: lucene/dev/trunk/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java (original)
+++ lucene/dev/trunk/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java Sat Aug  8 13:39:58 2015
@@ -40,6 +40,7 @@ import org.apache.lucene.misc.IndexMerge
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.NoLockFactory;
 import org.apache.solr.store.hdfs.HdfsDirectory;
+import org.apache.solr.util.RTimer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -133,38 +134,37 @@ public class TreeMergeOutputFormat exten
 
         context.setStatus("Logically merging " + shards.size() + " shards into one shard");
         LOG.info("Logically merging " + shards.size() + " shards into one shard: " + workDir);
-        long start = System.nanoTime();
+        RTimer timer = new RTimer();
         
         writer.addIndexes(indexes); 
         // TODO: avoid intermediate copying of files into dst directory; rename the files into the dir instead (cp -> rename) 
         // This can improve performance and turns this phase into a true "logical" merge, completing in constant time.
         // See https://issues.apache.org/jira/browse/LUCENE-4746
-        
+
+        timer.stop();
         if (LOG.isDebugEnabled()) {
-          context.getCounter(SolrCounters.class.getName(), SolrCounters.LOGICAL_TREE_MERGE_TIME.toString()).increment(System.currentTimeMillis() - start);
+          context.getCounter(SolrCounters.class.getName(), SolrCounters.LOGICAL_TREE_MERGE_TIME.toString()).increment((long) timer.getTime());
         }
-        float secs = (System.nanoTime() - start) / (float)(10^9);
-        LOG.info("Logical merge took {} secs", secs);        
+        LOG.info("Logical merge took {}ms", timer.getTime());
         int maxSegments = context.getConfiguration().getInt(TreeMergeMapper.MAX_SEGMENTS_ON_TREE_MERGE, Integer.MAX_VALUE);
         context.setStatus("Optimizing Solr: forcing mtree merge down to " + maxSegments + " segments");
         LOG.info("Optimizing Solr: forcing tree merge down to {} segments", maxSegments);
-        start = System.nanoTime();
+        timer = new RTimer();
         if (maxSegments < Integer.MAX_VALUE) {
           writer.forceMerge(maxSegments); 
           // TODO: consider perf enhancement for no-deletes merges: bulk-copy the postings data 
           // see http://lucene.472066.n3.nabble.com/Experience-with-large-merge-factors-tp1637832p1647046.html
         }
+        timer.stop();
         if (LOG.isDebugEnabled()) {
-          context.getCounter(SolrCounters.class.getName(), SolrCounters.PHYSICAL_TREE_MERGE_TIME.toString()).increment(System.currentTimeMillis() - start);
+          context.getCounter(SolrCounters.class.getName(), SolrCounters.PHYSICAL_TREE_MERGE_TIME.toString()).increment((long) timer.getTime());
         }
-        secs = (System.nanoTime() - start) / (float)(10^9);
-        LOG.info("Optimizing Solr: done forcing tree merge down to {} segments in {} secs", maxSegments, secs);
-        
-        start = System.nanoTime();
+        LOG.info("Optimizing Solr: done forcing tree merge down to {} segments in {}ms", maxSegments, timer.getTime());
+
+        timer = new RTimer();
         LOG.info("Optimizing Solr: Closing index writer");
         writer.close();
-        secs = (System.nanoTime() - start) / (float)(10^9);
-        LOG.info("Optimizing Solr: Done closing index writer in {} secs", secs);
+        LOG.info("Optimizing Solr: Done closing index writer in {}ms", timer.getTime());
         context.setStatus("Done");
       } finally {
         heartBeater.cancelHeartBeat();

Modified: lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java (original)
+++ lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java Sat Aug  8 13:39:58 2015
@@ -34,6 +34,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.hadoop.fs.FileSystem;
@@ -75,6 +76,7 @@ import org.apache.solr.hadoop.hack.MiniM
 import org.apache.solr.morphlines.solr.AbstractSolrMorphlineTestBase;
 import org.apache.solr.util.BadHdfsThreadsFilter;
 import org.apache.solr.util.BadMrClusterThreadsFilter;
+import org.apache.solr.util.TimeOut;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -638,11 +640,10 @@ public class MorphlineGoLiveMiniMRTest e
     request.setPath("/admin/collections");
     cloudClient.request(request);
 
-    
-    long timeout = System.currentTimeMillis() + 10000;
+    final TimeOut timeout = new TimeOut(10, TimeUnit.SECONDS);
     while (cloudClient.getZkStateReader().getClusterState().hasCollection(replicatedCollection)) {
-      if (System.currentTimeMillis() > timeout) {
-        throw new AssertionError("Timeout waiting to see removed collection leave clusterstate");
+      if (timeout.hasTimedOut()) {
+         throw new AssertionError("Timeout waiting to see removed collection leave clusterstate");
       }
       
       Thread.sleep(200);

Modified: lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java (original)
+++ lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java Sat Aug  8 13:39:58 2015
@@ -18,7 +18,6 @@ package org.apache.solr.hadoop.hack;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Random;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -30,7 +29,6 @@ import org.apache.hadoop.mapred.MapTaskC
 import org.apache.hadoop.mapred.TaskCompletionEvent;
 import org.apache.hadoop.security.AccessControlException;
 import org.apache.hadoop.security.UserGroupInformation;
-import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.lucene.util.LuceneTestCase;
 
 
@@ -176,14 +174,6 @@ public class MiniMRCluster {
       int numTaskTrackers, String namenode, int numDir, String[] racks,
       String[] hosts, UserGroupInformation ugi, JobConf conf,
       int numTrackerToExclude) throws Exception {
-    this(jobTrackerPort, taskTrackerPort, numTaskTrackers, namenode, numDir,
-        racks, hosts, ugi, conf, numTrackerToExclude, new Clock());
-  }
-
-  public MiniMRCluster(int jobTrackerPort, int taskTrackerPort,
-      int numTaskTrackers, String namenode, int numDir, String[] racks,
-      String[] hosts, UserGroupInformation ugi, JobConf conf,
-      int numTrackerToExclude, Clock clock) throws Exception {
     if (conf == null) conf = new JobConf();
     FileSystem.setDefaultUri(conf, namenode);
     String identifier = this.getClass().getSimpleName() + "_"
@@ -273,11 +263,4 @@ public class MiniMRCluster {
       LOG.error(e);
     }
   }
-  
-  static class Clock {
-    long getTime() {
-      return System.currentTimeMillis();
-    }
-  }
-
 }

Modified: lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java (original)
+++ lucene/dev/trunk/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java Sat Aug  8 13:39:58 2015
@@ -38,7 +38,6 @@ import org.apache.hadoop.yarn.exceptions
 import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
 import org.apache.hadoop.yarn.factories.RecordFactory;
 import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider;
-import org.apache.hadoop.yarn.ipc.RPCUtil;
 import org.apache.hadoop.yarn.server.api.ResourceTracker;
 import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatRequest;
 import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatResponse;
@@ -102,7 +101,7 @@ public class MiniYARNCluster extends Com
       // symlink as the test working directory.
       String targetPath = targetWorkDir.getAbsolutePath();
       File link = new File(System.getProperty("java.io.tmpdir"),
-        String.valueOf(System.currentTimeMillis()));
+        String.valueOf(System.nanoTime()));
       String linkPath = link.getAbsolutePath();
 
       try {

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/LeaderInitiatedRecoveryThread.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/LeaderInitiatedRecoveryThread.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/LeaderInitiatedRecoveryThread.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/LeaderInitiatedRecoveryThread.java Sat Aug  8 13:39:58 2015
@@ -11,6 +11,7 @@ import org.apache.solr.common.cloud.ZkCo
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.params.CoreAdminParams.CoreAdminAction;
 import org.apache.solr.core.CoreContainer;
+import org.apache.solr.util.RTimer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -73,7 +74,7 @@ public class LeaderInitiatedRecoveryThre
   }
   
   public void run() {
-    long startMs = System.currentTimeMillis();
+    RTimer timer = new RTimer();
     try {
       sendRecoveryCommandWithRetry();
     } catch (Exception exc) {
@@ -84,8 +85,7 @@ public class LeaderInitiatedRecoveryThre
         throw new SolrException(ErrorCode.SERVER_ERROR, exc);
       }
     }
-    long diffMs = (System.currentTimeMillis() - startMs);
-    log.info(getName()+" completed successfully after running for "+Math.round(diffMs/1000L)+" secs");    
+    log.info("{} completed successfully after running for {}ms", getName(), timer.getTime());
   }
   
   protected void sendRecoveryCommandWithRetry() throws Exception {    

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java Sat Aug  8 13:39:58 2015
@@ -80,6 +80,8 @@ import org.apache.solr.handler.component
 import org.apache.solr.handler.component.ShardRequest;
 import org.apache.solr.handler.component.ShardResponse;
 import org.apache.solr.update.SolrIndexSplitter;
+import org.apache.solr.util.RTimer;
+import org.apache.solr.util.TimeOut;
 import org.apache.solr.util.stats.Snapshot;
 import org.apache.solr.util.stats.Timer;
 import org.apache.zookeeper.CreateMode;
@@ -722,9 +724,9 @@ public class OverseerCollectionMessageHa
   }
 
   private boolean waitForCoreNodeGone(String collectionName, String shard, String replicaName, int timeoutms) throws InterruptedException {
-    long waitUntil = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeoutms, TimeUnit.MILLISECONDS);
+    TimeOut timeout = new TimeOut(timeoutms, TimeUnit.MILLISECONDS);
     boolean deleted = false;
-    while (System.nanoTime() < waitUntil) {
+    while (! timeout.hasTimedOut()) {
       Thread.sleep(100);
       DocCollection docCollection = zkStateReader.getClusterState().getCollection(collectionName);
       if(docCollection != null) {
@@ -775,10 +777,9 @@ public class OverseerCollectionMessageHa
           Utils.toJSON(m));
 
       // wait for a while until we don't see the collection
-      long now = System.nanoTime();
-      long timeout = now + TimeUnit.NANOSECONDS.convert(30, TimeUnit.SECONDS);
+      TimeOut timeout = new TimeOut(30, TimeUnit.SECONDS);
       boolean removed = false;
-      while (System.nanoTime() < timeout) {
+      while (! timeout.hasTimedOut()) {
         Thread.sleep(100);
         removed = !zkStateReader.getClusterState().hasCollection(collection);
         if (removed) {
@@ -815,11 +816,10 @@ public class OverseerCollectionMessageHa
       throws KeeperException, InterruptedException {
     final String collectionName = message.getStr(COLLECTION_PROP);
 
-    // wait for a while until the state format changes
-    long now = System.nanoTime();
-    long timeout = now + TimeUnit.NANOSECONDS.convert(30, TimeUnit.SECONDS);
     boolean firstLoop = true;
-    while (System.nanoTime() < timeout) {
+    // wait for a while until the state format changes
+    TimeOut timeout = new TimeOut(30, TimeUnit.SECONDS);
+    while (! timeout.hasTimedOut()) {
       DocCollection collection = zkStateReader.getClusterState().getCollection(collectionName);
       if (collection == null) {
         throw new SolrException(ErrorCode.BAD_REQUEST, "Collection: " + collectionName + " not found");
@@ -875,11 +875,10 @@ public class OverseerCollectionMessageHa
 
   private void checkForAlias(String name, String value) {
 
-    long now = System.nanoTime();
-    long timeout = now + TimeUnit.NANOSECONDS.convert(30, TimeUnit.SECONDS);
+    TimeOut timeout = new TimeOut(30, TimeUnit.SECONDS);
     boolean success = false;
     Aliases aliases = null;
-    while (System.nanoTime() < timeout) {
+    while (! timeout.hasTimedOut()) {
       aliases = zkStateReader.getAliases();
       String collections = aliases.getCollectionAlias(name);
       if (collections != null && collections.equals(value)) {
@@ -894,11 +893,10 @@ public class OverseerCollectionMessageHa
 
   private void checkForAliasAbsence(String name) {
 
-    long now = System.nanoTime();
-    long timeout = now + TimeUnit.NANOSECONDS.convert(30, TimeUnit.SECONDS);
+    TimeOut timeout = new TimeOut(30, TimeUnit.SECONDS);
     boolean success = false;
     Aliases aliases = null;
-    while (System.nanoTime() < timeout) {
+    while (! timeout.hasTimedOut()) {
       aliases = zkStateReader.getAliases();
       String collections = aliases.getCollectionAlias(name);
       if (collections == null) {
@@ -959,9 +957,9 @@ public class OverseerCollectionMessageHa
         
     Overseer.getInQueue(zkStateReader.getZkClient()).offer(Utils.toJSON(message));
     // wait for a while until we see the shard
-    long waitUntil = System.nanoTime() + TimeUnit.NANOSECONDS.convert(30, TimeUnit.SECONDS);
+    TimeOut timeout = new TimeOut(30, TimeUnit.SECONDS);
     boolean created = false;
-    while (System.nanoTime() < waitUntil) {
+    while (! timeout.hasTimedOut()) {
       Thread.sleep(100);
       created = zkStateReader.getClusterState().getCollection(collectionName).getSlice(sliceName) != null;
       if (created) break;
@@ -1460,7 +1458,7 @@ public class OverseerCollectionMessageHa
 
   private void waitForNewShard(String collectionName, String sliceName) throws KeeperException, InterruptedException {
     log.info("Waiting for slice {} of collection {} to be available", sliceName, collectionName);
-    long startTime = System.currentTimeMillis();
+    RTimer timer = new RTimer();
     int retryCount = 320;
     while (retryCount-- > 0) {
       DocCollection collection = zkStateReader.getClusterState().getCollection(collectionName);
@@ -1470,8 +1468,8 @@ public class OverseerCollectionMessageHa
       }
       Slice slice = collection.getSlice(sliceName);
       if (slice != null) {
-        log.info("Waited for {} seconds for slice {} of collection {} to be available",
-            (System.currentTimeMillis() - startTime) / 1000, sliceName, collectionName);
+        log.info("Waited for {}ms for slice {} of collection {} to be available",
+            timer.getTime(), sliceName, collectionName);
         return;
       }
       Thread.sleep(1000);
@@ -1479,7 +1477,7 @@ public class OverseerCollectionMessageHa
     }
     throw new SolrException(ErrorCode.SERVER_ERROR,
         "Could not find new slice " + sliceName + " in collection " + collectionName
-            + " even after waiting for " + (System.currentTimeMillis() - startTime) / 1000 + " seconds"
+            + " even after waiting for " + timer.getTime() + "ms"
     );
   }
 
@@ -1541,10 +1539,9 @@ public class OverseerCollectionMessageHa
       Overseer.getInQueue(zkStateReader.getZkClient()).offer(Utils.toJSON(m));
       
       // wait for a while until we don't see the shard
-      long now = System.nanoTime();
-      long timeout = now + TimeUnit.NANOSECONDS.convert(30, TimeUnit.SECONDS);
+      TimeOut timeout = new TimeOut(30, TimeUnit.SECONDS);
       boolean removed = false;
-      while (System.nanoTime() < timeout) {
+      while (! timeout.hasTimedOut()) {
         Thread.sleep(100);
         removed = zkStateReader.getClusterState().getSlice(collection, sliceId) == null;
         if (removed) {
@@ -1672,17 +1669,16 @@ public class OverseerCollectionMessageHa
         "routeKey", SolrIndexSplitter.getRouteKey(splitKey) + "!",
         "range", splitRange.toString(),
         "targetCollection", targetCollection.getName(),
-        // TODO: look at using nanoTime here?
-        "expireAt", String.valueOf(System.currentTimeMillis() + timeout));
+        "expireAt", RoutingRule.makeExpiryAt(timeout));
     log.info("Adding routing rule: " + m);
     Overseer.getInQueue(zkStateReader.getZkClient()).offer(
         Utils.toJSON(m));
 
     // wait for a while until we see the new rule
     log.info("Waiting to see routing rule updated in clusterstate");
-    long waitUntil = System.nanoTime() + TimeUnit.NANOSECONDS.convert(60, TimeUnit.SECONDS);
+    TimeOut waitUntil = new TimeOut(60, TimeUnit.SECONDS);
     boolean added = false;
-    while (System.nanoTime() < waitUntil) {
+    while (! waitUntil.hasTimedOut()) {
       Thread.sleep(100);
       Map<String, RoutingRule> rules = zkStateReader.getClusterState().getSlice(sourceCollection.getName(), sourceSlice.getName()).getRoutingRules();
       if (rules != null) {
@@ -2006,9 +2002,9 @@ public class OverseerCollectionMessageHa
       Overseer.getInQueue(zkStateReader.getZkClient()).offer(Utils.toJSON(message));
 
       // wait for a while until we don't see the collection
-      long waitUntil = System.nanoTime() + TimeUnit.NANOSECONDS.convert(30, TimeUnit.SECONDS);
+      TimeOut waitUntil = new TimeOut(30, TimeUnit.SECONDS);
       boolean created = false;
-      while (System.nanoTime() < waitUntil) {
+      while (! waitUntil.hasTimedOut()) {
         Thread.sleep(100);
         created = zkStateReader.getClusterState().getCollections().contains(collectionName);
         if(created) break;
@@ -2142,7 +2138,7 @@ public class OverseerCollectionMessageHa
 
   private Map<String, Replica> waitToSeeReplicasInState(String collectionName, Collection<String> coreNames) throws InterruptedException {
     Map<String, Replica> result = new HashMap<>();
-    long endTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(30, TimeUnit.SECONDS);
+    TimeOut timeout = new TimeOut(30, TimeUnit.SECONDS);
     while (true) {
       DocCollection coll = zkStateReader.getClusterState().getCollection(collectionName);
       for (String coreName : coreNames) {
@@ -2160,7 +2156,7 @@ public class OverseerCollectionMessageHa
       if (result.size() == coreNames.size()) {
         return result;
       }
-      if (System.nanoTime() > endTime) {
+      if (timeout.hasTimedOut()) {
         throw new SolrException(ErrorCode.SERVER_ERROR, "Timed out waiting to see all replicas: " + coreNames + " in cluster state.");
       }
       

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrCore.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrCore.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrCore.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrCore.java Sat Aug  8 13:39:58 2015
@@ -53,6 +53,7 @@ import java.util.concurrent.CopyOnWriteA
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.locks.ReentrantLock;
@@ -178,7 +179,8 @@ public final class SolrCore implements S
   private final UpdateHandler updateHandler;
   private final SolrCoreState solrCoreState;
 
-  private final long startTime;
+  private final Date startTime = new Date();
+  private final long startNanoTime = System.nanoTime();
   private final RequestHandlers reqHandlers;
   private final PluginBag<SearchComponent> searchComponents = new PluginBag<>(SearchComponent.class, this);
   private final PluginBag<UpdateRequestProcessorFactory> updateProcessors = new PluginBag<>(UpdateRequestProcessorFactory.class, this);
@@ -194,7 +196,18 @@ public final class SolrCore implements S
 
   private final ReentrantLock ruleExpiryLock;
 
-  public long getStartTime() { return startTime; }
+  public Date getStartTimeStamp() { return startTime; }
+
+  @Deprecated
+  public long getStartTime() { return startTime.getTime(); }
+
+  public long getStartNanoTime() {
+    return startNanoTime;
+  }
+
+  public long getUptimeMs() {
+    return TimeUnit.MILLISECONDS.convert(System.nanoTime() - startNanoTime, TimeUnit.NANOSECONDS);
+  }
 
   private final RestManager restManager;
 
@@ -674,7 +687,6 @@ public final class SolrCore implements S
     this.ulogDir = null;
     this.solrConfig = null;
     this.configSetProperties = null;
-    this.startTime = System.currentTimeMillis();
     this.maxWarmingSearchers = 2;  // we don't have a config yet, just pick a number.
     this.slowQueryThresholdMillis = -1;
     this.resourceLoader = null;
@@ -741,7 +753,6 @@ public final class SolrCore implements S
 
     this.schema = initSchema(config, schema);
 
-    this.startTime = System.currentTimeMillis();
     this.maxWarmingSearchers = config.maxWarmingSearchers;
     this.slowQueryThresholdMillis = config.slowQueryThresholdMillis;
 
@@ -2431,7 +2442,7 @@ public final class SolrCore implements S
   public NamedList getStatistics() {
     NamedList<Object> lst = new SimpleOrderedMap<>();
     lst.add("coreName", name==null ? "(null)" : name);
-    lst.add("startTime", new Date(startTime));
+    lst.add("startTime", startTime);
     lst.add("refCount", getOpenCount());
     lst.add("instanceDir", resourceLoader.getInstanceDir());
     lst.add("indexDir", getIndexDir());

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/CdcrReplicatorState.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/CdcrReplicatorState.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/CdcrReplicatorState.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/CdcrReplicatorState.java Sat Aug  8 13:39:58 2015
@@ -98,7 +98,7 @@ class CdcrReplicatorState {
       errorCounters.put(error, 0l);
     }
     errorCounters.put(error, errorCounters.get(error) + 1);
-    errorsQueue.add(new ErrorQueueEntry(error, System.currentTimeMillis()));
+    errorsQueue.add(new ErrorQueueEntry(error, new Date()));
     consecutiveErrors++;
   }
 
@@ -133,7 +133,7 @@ class CdcrReplicatorState {
       Iterator<ErrorQueueEntry> it = errorsQueue.iterator();
       while (it.hasNext()) {
         ErrorQueueEntry entry = it.next();
-        lastErrors.add(new String[]{DateFormatUtil.formatExternal(new Date(entry.timestamp)), entry.type.toLower()});
+        lastErrors.add(new String[]{DateFormatUtil.formatExternal(entry.timestamp), entry.type.toLower()});
       }
     }
     return lastErrors;
@@ -240,9 +240,9 @@ class CdcrReplicatorState {
   private class ErrorQueueEntry {
 
     private ErrorType type;
-    private long timestamp;
+    private Date timestamp;
 
-    private ErrorQueueEntry(ErrorType type, long timestamp) {
+    private ErrorQueueEntry(ErrorType type, Date timestamp) {
       this.type = type;
       this.timestamp = timestamp;
     }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java Sat Aug  8 13:39:58 2015
@@ -72,6 +72,7 @@ import org.apache.solr.common.params.Mod
 import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.FastInputStream;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SuppressForbidden;
 import org.apache.solr.core.DirectoryFactory;
 import org.apache.solr.core.DirectoryFactory.DirContext;
 import org.apache.solr.core.IndexDeletionPolicyWrapper;
@@ -87,6 +88,7 @@ import org.apache.solr.util.DefaultSolrT
 import org.apache.solr.util.FileUtils;
 import org.apache.solr.util.PropertiesInputStream;
 import org.apache.solr.util.PropertiesOutputStream;
+import org.apache.solr.util.RTimer;
 import org.apache.solr.util.RefCounted;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -132,7 +134,8 @@ public class IndexFetcher {
 
   final ReplicationHandler replicationHandler;
 
-  private volatile long replicationStartTime;
+  private volatile Date replicationStartTimeStamp;
+  private RTimer replicationTimer;
 
   private final SolrCore solrCore;
 
@@ -275,7 +278,7 @@ public class IndexFetcher {
 
     boolean cleanupDone = false;
     boolean successfulInstall = false;
-    replicationStartTime = System.currentTimeMillis();
+    markReplicationStart();
     Directory tmpIndexDir = null;
     String tmpIndex;
     Directory indexDir = null;
@@ -339,6 +342,7 @@ public class IndexFetcher {
         return true;
       }
 
+      // TODO: Should we be comparing timestamps (across machines) here?
       if (!forceReplication && IndexDeletionPolicyWrapper.getCommitTimestamp(commit) == latestVersion) {
         //master and slave are already in sync just return
         LOG.info("Slave in sync with master.");
@@ -434,9 +438,7 @@ public class IndexFetcher {
           if (tlogFilesToDownload != null) {
             downloadTlogFiles(timestamp, latestGeneration);
           }
-          LOG.info("Total time taken for download : "
-              + ((System.currentTimeMillis() - replicationStartTime) / 1000)
-              + " secs");
+          LOG.info("Total time taken for download: {} secs", getReplicationTimeElapsed());
           Collection<Map<String,Object>> modifiedConfFiles = getModifiedConfFiles(confFilesToDownload);
           if (!modifiedConfFiles.isEmpty()) {
             reloadCore = true;
@@ -515,7 +517,7 @@ public class IndexFetcher {
           successfulInstall = fetchLatestIndex(true, reloadCore);
         }
 
-        replicationStartTime = 0;
+        markReplicationStop();
         return successfulInstall;
       } catch (ReplicationHandlerException e) {
         LOG.error("User aborted Replication");
@@ -548,7 +550,7 @@ public class IndexFetcher {
       core.getUpdateHandler().getSolrCoreState().setLastReplicateIndexSuccess(successfulInstall);
 
       filesToDownload = filesDownloaded = confFilesDownloaded = confFilesToDownload = null;
-      replicationStartTime = 0;
+      markReplicationStop();
       dirFileFetcher = null;
       localFileFetcher = null;
       if (fsyncService != null && !fsyncService.isShutdown()) fsyncService
@@ -610,6 +612,7 @@ public class IndexFetcher {
    * restarts.
    * @throws IOException on IO error
    */
+  @SuppressForbidden(reason = "Need currentTimeMillis for debugging/stats")
   private void logReplicationTimeAndConfFiles(Collection<Map<String, Object>> modifiedConfFiles, boolean successfulInstall) throws IOException {
     List<String> confFiles = new ArrayList<>();
     if (modifiedConfFiles != null && !modifiedConfFiles.isEmpty())
@@ -618,7 +621,7 @@ public class IndexFetcher {
 
     Properties props = replicationHandler.loadReplicationProperties();
     long replicationTime = System.currentTimeMillis();
-    long replicationTimeTaken = (replicationTime - getReplicationStartTime()) / 1000;
+    long replicationTimeTaken = getReplicationTimeElapsed();
     Directory dir = null;
     try {
       dir = solrCore.getDirectoryFactory().get(solrCore.getDataDir(), DirContext.META_DATA, solrCore.getSolrConfig().indexConfig.lockType);
@@ -1219,14 +1222,25 @@ public class IndexFetcher {
     stop = true;
   }
 
-  long getReplicationStartTime() {
-    return replicationStartTime;
+  @SuppressForbidden(reason = "Need currentTimeMillis for debugging/stats")
+  private void markReplicationStart() {
+    replicationTimer = new RTimer();
+    replicationStartTimeStamp = new Date();
+  }
+
+  private void markReplicationStop() {
+    replicationStartTimeStamp = null;
+    replicationTimer = null;
+  }
+
+  Date getReplicationStartTimeStamp() {
+    return replicationStartTimeStamp;
   }
 
   long getReplicationTimeElapsed() {
     long timeElapsed = 0;
-    if (getReplicationStartTime() > 0)
-      timeElapsed = TimeUnit.SECONDS.convert(System.currentTimeMillis() - getReplicationStartTime(), TimeUnit.MILLISECONDS);
+    if (replicationStartTimeStamp != null)
+      timeElapsed = TimeUnit.SECONDS.convert((long) replicationTimer.getTime(), TimeUnit.MILLISECONDS);
     return timeElapsed;
   }
 

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java Sat Aug  8 13:39:58 2015
@@ -36,6 +36,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Random;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
@@ -71,6 +72,7 @@ import org.apache.solr.common.util.FastO
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.common.util.StrUtils;
+import org.apache.solr.common.util.SuppressForbidden;
 import org.apache.solr.core.CloseHook;
 import org.apache.solr.core.DirectoryFactory;
 import org.apache.solr.core.DirectoryFactory.DirContext;
@@ -182,7 +184,7 @@ public class ReplicationHandler extends
 
   private final Map<String, FileInfo> confFileInfoCache = new HashMap<>();
 
-  private Integer reserveCommitDuration = readInterval("00:00:10");
+  private Integer reserveCommitDuration = readIntervalMs("00:00:10");
 
   volatile IndexCommit indexCommitPoint;
 
@@ -190,8 +192,7 @@ public class ReplicationHandler extends
 
   private AtomicBoolean replicationEnabled = new AtomicBoolean(true);
 
-  private Integer pollInterval;
-
+  private Long pollIntervalNs;
   private String pollIntervalStr;
 
   /**
@@ -693,10 +694,15 @@ public class ReplicationHandler extends
     return pollDisabled.get();
   }
 
-  Long getNextScheduledExecTime() {
-    Long nextTime = null;
+  @SuppressForbidden(reason = "Need currentTimeMillis, to output next execution time in replication details")
+  private void markScheduledExecutionStart() {
+    executorStartTime = System.currentTimeMillis();
+  }
+
+  private Date getNextScheduledExecTime() {
+    Date nextTime = null;
     if (executorStartTime > 0)
-      nextTime = executorStartTime + pollInterval;
+      nextTime = new Date(executorStartTime + TimeUnit.MILLISECONDS.convert(pollIntervalNs, TimeUnit.NANOSECONDS));
     return nextTime;
   }
 
@@ -843,8 +849,9 @@ public class ReplicationHandler extends
       if (getPollInterval() != null) {
         slave.add(POLL_INTERVAL, getPollInterval());
       }
-      if (getNextScheduledExecTime() != null && !isPollingDisabled()) {
-        slave.add(NEXT_EXECUTION_AT, new Date(getNextScheduledExecTime()).toString());
+      Date nextScheduled = getNextScheduledExecTime();
+      if (nextScheduled != null && !isPollingDisabled()) {
+        slave.add(NEXT_EXECUTION_AT, nextScheduled.toString());
       } else if (isPollingDisabled()) {
         slave.add(NEXT_EXECUTION_AT, "Polling disabled");
       }
@@ -915,8 +922,9 @@ public class ReplicationHandler extends
 
           long estimatedTimeRemaining = 0;
 
-          if (fetcher.getReplicationStartTime() > 0) {
-            slave.add("replicationStartTime", new Date(fetcher.getReplicationStartTime()).toString());
+          Date replicationStartTimeStamp = fetcher.getReplicationStartTimeStamp();
+          if (replicationStartTimeStamp != null) {
+            slave.add("replicationStartTime", replicationStartTimeStamp.toString());
           }
           long elapsed = fetcher.getReplicationTimeElapsed();
           slave.add("timeElapsed", String.valueOf(elapsed) + "s");
@@ -1030,8 +1038,8 @@ public class ReplicationHandler extends
 
   private void setupPolling(String intervalStr) {
     pollIntervalStr = intervalStr;
-    pollInterval = readInterval(pollIntervalStr);
-    if (pollInterval == null || pollInterval <= 0) {
+    pollIntervalNs = readIntervalNs(pollIntervalStr);
+    if (pollIntervalNs == null || pollIntervalNs <= 0) {
       LOG.info(" No value set for 'pollInterval'. Timer Task not started.");
       return;
     }
@@ -1045,7 +1053,7 @@ public class ReplicationHandler extends
         }
         try {
           LOG.debug("Polling for index modifications");
-          executorStartTime = System.currentTimeMillis();
+          markScheduledExecutionStart();
           doFetch(null, false);
         } catch (Exception e) {
           LOG.error("Exception in fetching index", e);
@@ -1054,9 +1062,12 @@ public class ReplicationHandler extends
     };
     executorService = Executors.newSingleThreadScheduledExecutor(
         new DefaultSolrThreadFactory("indexFetcher"));
-    long initialDelay = pollInterval - (System.currentTimeMillis() % pollInterval);
-    executorService.scheduleAtFixedRate(task, initialDelay, pollInterval, TimeUnit.MILLISECONDS);
-    LOG.info("Poll Scheduled at an interval of " + pollInterval + "ms");
+    // Randomize initial delay, with a minimum of 1ms
+    long initialDelayNs = new Random().nextLong() % pollIntervalNs
+        + TimeUnit.NANOSECONDS.convert(1, TimeUnit.MILLISECONDS);
+    executorService.scheduleAtFixedRate(task, initialDelayNs, pollIntervalNs, TimeUnit.NANOSECONDS);
+    LOG.info("Poll scheduled at an interval of {}ms",
+        TimeUnit.MILLISECONDS.convert(pollIntervalNs, TimeUnit.NANOSECONDS));
   }
 
   @Override
@@ -1178,7 +1189,7 @@ public class ReplicationHandler extends
       }
       String reserve = (String) master.get(RESERVE);
       if (reserve != null && !reserve.trim().equals("")) {
-        reserveCommitDuration = readInterval(reserve);
+        reserveCommitDuration = readIntervalMs(reserve);
       }
       LOG.info("Commits will be reserved for  " + reserveCommitDuration);
       isMaster = true;
@@ -1534,36 +1545,34 @@ public class ReplicationHandler extends
 
   }
 
-  static Integer readInterval(String interval) {
+  private static Integer readIntervalMs(String interval) {
+    return (int) TimeUnit.MILLISECONDS.convert(readIntervalNs(interval), TimeUnit.NANOSECONDS);
+  }
+
+  private static Long readIntervalNs(String interval) {
     if (interval == null)
       return null;
     int result = 0;
-    if (interval != null) {
-      Matcher m = INTERVAL_PATTERN.matcher(interval.trim());
-      if (m.find()) {
-        String hr = m.group(1);
-        String min = m.group(2);
-        String sec = m.group(3);
-        result = 0;
-        try {
-          if (sec != null && sec.length() > 0)
-            result += Integer.parseInt(sec);
-          if (min != null && min.length() > 0)
-            result += (60 * Integer.parseInt(min));
-          if (hr != null && hr.length() > 0)
-            result += (60 * 60 * Integer.parseInt(hr));
-          result *= 1000;
-        } catch (NumberFormatException e) {
-          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
-              INTERVAL_ERR_MSG);
-        }
-      } else {
-        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
-            INTERVAL_ERR_MSG);
+    Matcher m = INTERVAL_PATTERN.matcher(interval.trim());
+    if (m.find()) {
+      String hr = m.group(1);
+      String min = m.group(2);
+      String sec = m.group(3);
+      result = 0;
+      try {
+        if (sec != null && sec.length() > 0)
+          result += Integer.parseInt(sec);
+        if (min != null && min.length() > 0)
+          result += (60 * Integer.parseInt(min));
+        if (hr != null && hr.length() > 0)
+          result += (60 * 60 * Integer.parseInt(hr));
+        return TimeUnit.NANOSECONDS.convert(result, TimeUnit.SECONDS);
+      } catch (NumberFormatException e) {
+        throw new SolrException(ErrorCode.SERVER_ERROR, INTERVAL_ERR_MSG);
       }
-
+    } else {
+      throw new SolrException(ErrorCode.SERVER_ERROR, INTERVAL_ERR_MSG);
     }
-    return result;
   }
 
   private static final String LOCATION = "location";

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java Sat Aug  8 13:39:58 2015
@@ -21,6 +21,7 @@ import org.apache.solr.common.SolrExcept
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.common.util.SuppressForbidden;
 import org.apache.solr.core.PluginInfo;
 import org.apache.solr.core.PluginBag;
 import org.apache.solr.core.SolrCore;
@@ -56,9 +57,16 @@ public abstract class RequestHandlerBase
   private final AtomicLong numErrors = new AtomicLong();
   private final AtomicLong numTimeouts = new AtomicLong();
   private final Timer requestTimes = new Timer();
-  private final long handlerStart = System.currentTimeMillis();
+
+  private final long handlerStart;
+
   private PluginInfo pluginInfo;
 
+  @SuppressForbidden(reason = "Need currentTimeMillis, used only for stats output")
+  public RequestHandlerBase() {
+    handlerStart = System.currentTimeMillis();
+  }
+
   /**
    * Initializes the {@link org.apache.solr.request.SolrRequestHandler} by creating three {@link org.apache.solr.common.params.SolrParams} named.
    * <table border="1" summary="table of parameters">

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java Sat Aug  8 13:39:58 2015
@@ -72,6 +72,7 @@ import org.apache.solr.response.SolrQuer
 import org.apache.solr.schema.SchemaManager;
 import org.apache.solr.util.CommandOperation;
 import org.apache.solr.util.DefaultSolrThreadFactory;
+import org.apache.solr.util.RTimer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -644,7 +645,7 @@ public class SolrConfigHandler extends R
                                               String prop,
                                               int expectedVersion,
                                               int maxWaitSecs) {
-    long startMs = System.currentTimeMillis();
+    final RTimer timer = new RTimer();
     // get a list of active replica cores to query for the schema zk version (skipping this core of course)
     List<PerReplicaCallable> concurrentTasks = new ArrayList<>();
 
@@ -702,10 +703,8 @@ public class SolrConfigHandler extends R
       ExecutorUtil.shutdownNowAndAwaitTermination(parallelExecutor);
     }
 
-    long diffMs = (System.currentTimeMillis() - startMs);
-    log.info(formatString(
-        "Took {0} secs to set the property {1} to be of version {2} for collection {3}",
-        Math.round(diffMs / 1000d), prop, expectedVersion, collection));
+    log.info("Took {}ms to set the property {} to be of version {} for collection {}",
+        timer.getTime(), prop, expectedVersion, collection);
   }
 
   public static List<String> getActiveReplicaCoreUrls(ZkController zkController,
@@ -754,13 +753,13 @@ public class SolrConfigHandler extends R
 
     @Override
     public Boolean call() throws Exception {
-      long startTime = System.currentTimeMillis();
+      final RTimer timer = new RTimer();
       int attempts = 0;
       try (HttpSolrClient solr = new HttpSolrClient(coreUrl)) {
         // eventually, this loop will get killed by the ExecutorService's timeout
         while (true) {
           try {
-            long timeElapsed = (System.currentTimeMillis() - startTime) / 1000;
+            long timeElapsed = (long) timer.getTime() / 1000;
             if (timeElapsed >= maxWait) {
               return false;
             }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java Sat Aug  8 13:39:58 2015
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -31,7 +30,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 
 import com.google.common.collect.ImmutableMap;
@@ -1165,8 +1163,8 @@ public class CoreAdminHandler extends Re
           info.add("dataDir", normalizePath(core.getDataDir()));
           info.add("config", core.getConfigResource());
           info.add("schema", core.getSchemaResource());
-          info.add("startTime", new Date(core.getStartTime()));
-          info.add("uptime", System.currentTimeMillis() - core.getStartTime());
+          info.add("startTime", core.getStartTimeStamp());
+          info.add("uptime", core.getUptimeMs());
           if (isIndexInfoNeeded) {
             RefCounted<SolrIndexSearcher> searcher = core.getSearcher();
             try {

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java Sat Aug  8 13:39:58 2015
@@ -130,7 +130,7 @@ public class SystemInfoHandler extends R
     info.add( "now", new Date() );
     
     // Start Time
-    info.add( "start", new Date(core.getStartTime()) );
+    info.add( "start", core.getStartTimeStamp() );
 
     // Solr Home
     SimpleOrderedMap<Object> dirs = new SimpleOrderedMap<>();

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/DebugComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/DebugComponent.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/DebugComponent.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/DebugComponent.java Sat Aug  8 13:39:58 2015
@@ -36,6 +36,7 @@ import org.apache.solr.common.params.Com
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.common.util.SuppressForbidden;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.search.DocList;
 import org.apache.solr.search.QueryParsing;
@@ -145,7 +146,8 @@ public class DebugComponent extends Sear
     rb.rsp.addToLog(CommonParams.REQUEST_ID, rid); //to see it in the logs of the landing core
     
   }
-  
+
+  @SuppressForbidden(reason = "Need currentTimeMillis, only used for naming")
   private String generateRid(ResponseBuilder rb) {
     String hostName = rb.req.getCore().getCoreDescriptor().getCoreContainer().getHostName();
     return hostName + "-" + rb.req.getCore().getName() + "-" + System.currentTimeMillis() + "-" + ridCounter.getAndIncrement();

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java Sat Aug  8 13:39:58 2015
@@ -17,6 +17,7 @@
 
 package org.apache.solr.request;
 
+import org.apache.solr.common.util.SuppressForbidden;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.search.SolrIndexSearcher;
 import org.apache.solr.util.RTimer;
@@ -54,12 +55,15 @@ public abstract class SolrQueryRequestBa
   protected Map<String,Object> json;
 
   private final RTimer requestTimer;
+  protected final long startTime;
 
+  @SuppressForbidden(reason = "Need currentTimeMillis to get start time for request (to be used for stats/debugging)")
   public SolrQueryRequestBase(SolrCore core, SolrParams params, RTimer requestTimer) {
     this.core = core;
     this.schema = null == core ? null : core.getLatestSchema();
     this.params = this.origParams = params;
     this.requestTimer = requestTimer;
+    this.startTime = System.currentTimeMillis();
   }
 
   public SolrQueryRequestBase(SolrCore core, SolrParams params) {
@@ -88,7 +92,7 @@ public abstract class SolrQueryRequestBa
     this.params = params;
   }
 
-  protected final long startTime=System.currentTimeMillis();
+
   // Get the start time of this request in milliseconds
   @Override
   public long getStartTime() {

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java Sat Aug  8 13:39:58 2015
@@ -47,6 +47,7 @@ import org.apache.solr.core.SolrResource
 import org.apache.solr.rest.schema.FieldTypeXmlAdapter;
 import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.apache.solr.util.FileUtils;
+import org.apache.solr.util.RTimer;
 import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.data.Stat;
@@ -212,7 +213,7 @@ public final class ManagedIndexSchema ex
   public static void waitForSchemaZkVersionAgreement(String collection, String localCoreNodeName,
                                                      int schemaZkVersion, ZkController zkController, int maxWaitSecs)
   {
-    long startMs = System.currentTimeMillis();
+    RTimer timer = new RTimer();
 
     // get a list of active replica cores to query for the schema zk version (skipping this core of course)
     List<GetZkSchemaVersionCallable> concurrentTasks = new ArrayList<>();
@@ -271,9 +272,8 @@ public final class ManagedIndexSchema ex
         parallelExecutor.shutdownNow();
     }
 
-    long diffMs = (System.currentTimeMillis() - startMs);
-    log.info("Took "+Math.round(diffMs/1000d)+" secs for "+concurrentTasks.size()+
-        " replicas to apply schema update version "+schemaZkVersion+" for collection "+collection);
+    log.info("Took {}ms for {} replicas to apply schema update version {} for collection {}",
+        timer.getTime(), concurrentTasks.size(), schemaZkVersion, collection);
   }
 
   protected static List<String> getActiveReplicaCoreUrls(ZkController zkController, String collection, String localCoreNodeName) {

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/OpenExchangeRatesOrgProvider.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/OpenExchangeRatesOrgProvider.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/OpenExchangeRatesOrgProvider.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/OpenExchangeRatesOrgProvider.java Sat Aug  8 13:39:58 2015
@@ -25,6 +25,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.solr.common.util.SuppressForbidden;
 import org.noggit.JSONParser;
 import org.apache.lucene.analysis.util.ResourceLoader;
 import org.apache.solr.common.SolrException;
@@ -84,12 +85,9 @@ public class OpenExchangeRatesOrgProvide
     if (sourceCurrencyCode == null || targetCurrencyCode == null) {
       throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Cannot get exchange rate; currency was null.");
     }
-    
-    if ((rates.getTimestamp() + refreshIntervalSeconds)*1000 < System.currentTimeMillis()) {
-      log.debug("Refresh interval has expired. Refreshing exchange rates.");
-      reload();
-    }
-    
+
+    reloadIfExpired();
+
     Double source = (Double) rates.getRates().get(sourceCurrencyCode);
     Double target = (Double) rates.getRates().get(targetCurrencyCode);
 
@@ -102,6 +100,14 @@ public class OpenExchangeRatesOrgProvide
     return target / source;  
   }
 
+  @SuppressForbidden(reason = "Need currentTimeMillis, for comparison with stamp in an external file")
+  private void reloadIfExpired() {
+    if ((rates.getTimestamp() + refreshIntervalSeconds)*1000 < System.currentTimeMillis()) {
+      log.debug("Refresh interval has expired. Refreshing exchange rates.");
+      reload();
+    }
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) return true;

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java Sat Aug  8 13:39:58 2015
@@ -61,6 +61,7 @@ import org.apache.solr.request.SolrQuery
 import org.apache.solr.request.SolrRequestInfo;
 import org.apache.solr.schema.TrieField;
 import org.apache.solr.search.join.ScoreJoinQParserPlugin;
+import org.apache.solr.util.RTimer;
 import org.apache.solr.util.RefCounted;
 
 public class JoinQParserPlugin extends QParserPlugin {
@@ -138,7 +139,7 @@ public class JoinQParserPlugin extends Q
             QParser parser = QParser.getParser(v, "lucene", otherReq);
             fromQuery = parser.getQuery();
             fromHolder = fromCore.getRegisteredSearcher();
-            if (fromHolder != null) fromCoreOpenTime = fromHolder.get().getOpenTime();
+            if (fromHolder != null) fromCoreOpenTime = fromHolder.get().getOpenNanoTime();
           } finally {
             otherReq.close();
             fromCore.close();
@@ -290,13 +291,13 @@ class JoinQuery extends Query {
     public Scorer scorer(LeafReaderContext context) throws IOException {
       if (filter == null) {
         boolean debug = rb != null && rb.isDebug();
-        long start = debug ? System.currentTimeMillis() : 0;
+        RTimer timer = (debug ? new RTimer() : null);
         resultSet = getDocSet();
-        long end = debug ? System.currentTimeMillis() : 0;
+        if (timer != null) timer.stop();
 
         if (debug) {
           SimpleOrderedMap<Object> dbg = new SimpleOrderedMap<>();
-          dbg.add("time", (end-start));
+          dbg.add("time", (long) timer.getTime());
           dbg.add("fromSetSize", fromSetSize);  // the input
           dbg.add("toSetSize", resultSet.size());    // the output
 

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java Sat Aug  8 13:39:58 2015
@@ -114,8 +114,9 @@ public class SolrIndexSearcher extends I
   private boolean debug = log.isDebugEnabled();
 
   private final String name;
-  private long openTime = System.currentTimeMillis();
-  private long registerTime = 0;
+  private final Date openTime = new Date();
+  private final long openNanoTime = System.nanoTime();
+  private Date registerTime;
   private long warmupTime = 0;
   private final DirectoryReader reader;
   private final boolean closeReader;
@@ -394,7 +395,7 @@ public class SolrIndexSearcher extends I
       cache.setState(SolrCache.State.LIVE);
       core.getInfoRegistry().put(cache.name(), cache);
     }
-    registerTime=System.currentTimeMillis();
+    registerTime = new Date();
   }
 
   /**
@@ -2240,13 +2241,23 @@ public class SolrIndexSearcher extends I
    */
   public Object cacheInsert(String cacheName, Object key, Object val) {
     SolrCache cache = cacheMap.get(cacheName);
-    return cache==null ? null : cache.put(key,val);
+    return cache==null ? null : cache.put(key, val);
   }
 
-  public long getOpenTime() {
+  public Date getOpenTimeStamp() {
     return openTime;
   }
 
+  // public but primarily for test case usage
+  public long getOpenNanoTime() {
+    return openNanoTime;
+  }
+
+  @Deprecated
+  public long getOpenTime() {
+    return openTime.getTime();
+  }
+
   @Override
   public Explanation explain(Query query, int doc) throws IOException {
     return super.explain(QueryUtils.makeQueryable(query), doc);
@@ -2297,8 +2308,8 @@ public class SolrIndexSearcher extends I
     lst.add("reader", reader.toString());
     lst.add("readerDir", reader.directory());
     lst.add("indexVersion", reader.getVersion());
-    lst.add("openedAt", new Date(openTime));
-    if (registerTime!=0) lst.add("registeredAt", new Date(registerTime));
+    lst.add("openedAt", openTime);
+    if (registerTime!=null) lst.add("registeredAt", registerTime);
     lst.add("warmupTime", warmupTime);
     return lst;
   }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java Sat Aug  8 13:39:58 2015
@@ -251,7 +251,7 @@ public class ScoreJoinQParserPlugin exte
 
             fromHolder = fromCore.getRegisteredSearcher();
             if (fromHolder != null) {
-              fromCoreOpenTime = fromHolder.get().getOpenTime();
+              fromCoreOpenTime = fromHolder.get().getOpenNanoTime();
             }
             return new OtherCoreJoinQuery(fromQuery, fromField, fromIndex, fromCoreOpenTime,
                 scoreMode, toField);

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java Sat Aug  8 13:39:58 2015
@@ -46,6 +46,7 @@ import org.apache.solr.common.params.Sol
 import org.apache.solr.common.util.Base64;
 import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.StrUtils;
+import org.apache.solr.common.util.SuppressForbidden;
 import org.apache.solr.common.util.Utils;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.handler.RequestHandlerBase;
@@ -86,6 +87,7 @@ public class PKIAuthenticationPlugin ext
   }
 
 
+  @SuppressForbidden(reason = "Needs currentTimeMillis to compare against time in header")
   @Override
   public void doAuthenticate(ServletRequest request, ServletResponse response, FilterChain filterChain) throws Exception {
 
@@ -248,7 +250,7 @@ public class PKIAuthenticationPlugin ext
 
   }
 
-
+  @SuppressForbidden(reason = "Needs currentTimeMillis to set current time in header")
   void setHeader(HttpRequest httpRequest) {
     SolrRequestInfo reqInfo = getRequestInfo();
     String usr = null;

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/servlet/cache/HttpCacheHeaderUtil.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/servlet/cache/HttpCacheHeaderUtil.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/servlet/cache/HttpCacheHeaderUtil.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/servlet/cache/HttpCacheHeaderUtil.java Sat Aug  8 13:39:58 2015
@@ -27,6 +27,7 @@ import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.solr.common.util.SuppressForbidden;
 import org.apache.solr.core.IndexDeletionPolicyWrapper;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.core.SolrConfig;
@@ -153,7 +154,7 @@ public final class HttpCacheHeaderUtil {
       lastMod =
         LastModFrom.DIRLASTMOD == lastModFrom
         ? IndexDeletionPolicyWrapper.getCommitTimestamp(searcher.getIndexReader().getIndexCommit())
-        : searcher.getOpenTime();
+        : searcher.getOpenTimeStamp().getTime();
     } catch (IOException e) {
       // we're pretty freaking screwed if this happens
       throw new SolrException(ErrorCode.SERVER_ERROR, e);
@@ -164,6 +165,11 @@ public final class HttpCacheHeaderUtil {
     return lastMod - (lastMod % 1000L);
   }
 
+  @SuppressForbidden(reason = "Need currentTimeMillis to send out cache control headers externally")
+  private static long timeNowForHeader() {
+    return System.currentTimeMillis();
+  }
+
   /**
    * Set the Cache-Control HTTP header (and Expires if needed)
    * based on the SolrConfig.
@@ -183,8 +189,7 @@ public final class HttpCacheHeaderUtil {
     }
     Long maxAge = conf.getHttpCachingConfig().getMaxAge();
     if (null != maxAge) {
-      resp.setDateHeader("Expires", System.currentTimeMillis()
-                         + (maxAge * 1000L));
+      resp.setDateHeader("Expires", timeNowForHeader() + (maxAge * 1000L));
     }
 
     return;
@@ -330,11 +335,12 @@ public final class HttpCacheHeaderUtil {
     // As long as no time machines get invented this is safe
     resp.setHeader("Expires", "Sat, 01 Jan 2000 01:00:00 GMT");
 
+    long timeNowForHeader = timeNowForHeader();
     // We signal "just modified" just in case some broken
     // proxy cache does not follow the above headers
-    resp.setDateHeader("Last-Modified", System.currentTimeMillis());
+    resp.setDateHeader("Last-Modified", timeNowForHeader);
     
     // We override the ETag with something different
-    resp.setHeader("ETag", '"'+Long.toHexString(System.currentTimeMillis())+'"');
+    resp.setHeader("ETag", '"'+Long.toHexString(timeNowForHeader)+'"');
   } 
 }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/store/blockcache/BlockCacheLocation.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/store/blockcache/BlockCacheLocation.java?rev=1694798&r1=1694797&r2=1694798&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/store/blockcache/BlockCacheLocation.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/store/blockcache/BlockCacheLocation.java Sat Aug  8 13:39:58 2015
@@ -19,6 +19,8 @@ package org.apache.solr.store.blockcache
 
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import org.apache.solr.common.util.SuppressForbidden;
+
 /**
  * @lucene.experimental
  */
@@ -26,10 +28,14 @@ public class BlockCacheLocation {
   
   private int block;
   private int bankId;
-  private long lastAccess = System.currentTimeMillis();
-  private long accesses;
+  private long lastAccess;
+  private long accesses = -1;
   private AtomicBoolean removed = new AtomicBoolean(false);
-  
+
+  public BlockCacheLocation() {
+    touch();
+  }
+
   public void setBlock(int block) {
     this.block = block;
   }
@@ -45,12 +51,13 @@ public class BlockCacheLocation {
   public int getBankId() {
     return bankId;
   }
-  
+
+  @SuppressForbidden(reason = "Need currentTimeMillis, only used by unused getLastAccess")
   public void touch() {
     lastAccess = System.currentTimeMillis();
     accesses++;
   }
-  
+
   public long getLastAccess() {
     return lastAccess;
   }



Mime
View raw message