[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [PATCH] javahl using microsecond time in LogMessage

From: Blair Zajac <blair_at_orcaware.com>
Date: 2007-04-18 02:15:13 CEST

Mark Phippard wrote:
> On 4/17/07, Blair Zajac <blair@orcaware.com> wrote:
>> Working on a new Java Subversion project, I have a number of
>> repositories that by design will have revisions that do not have
>> monotonically increasing dates. So I'll be doing my own date to
>> revision search through a log history.
>>
>> So I need two things, one is microseconds time since 1970 as stored in
>> apr_time_t and I want to do the sorting fast. Currently, the
>> java.util.Date's contain microsecond time since 1970, so the sorting
>> algorithm may not be accurate if I truncate the times. Also, if I use
>> new log message callback in trunk's SVNClient.logMessages(), then I can
>> get the timestamp and with the attached patch, not have to construct
>> java.util.Date's and only use the timestamp.
>>
>> The current LogMessage class grows an additional field, but besides
>> calling the new constructor from the C++ code, will there be any
>> ramifications of doing this?
>>
>> Is this a safe change to make? Will it break anything for older clients?
>
> In my opinion, the change is safe.
>
>
>> I know in C land, adding a field to a class or structure can be
>> problematic, but in Java, will their be an issue?
>>
>> I need to add a new constructor, but I'm keeping the old one around and
>> populating it from the timestamp in the java.util.Date, in case anybody
>> calls it?
>
> I am attaching a tweaked patch. Basically I just ditched the Date
> field from the LogMessage class. There is no point in carrying it
> around in the class when we can make it on the fly from the timeMicros
> field. What do you think?

Well, depending upon the usage, we could be constructing a bunch of them
every time the date is needed.

How about setting the date field to null upon construction for the new
constructor and then when it's first requested, we calculate the date
and cache it.

Here's a patch that does that.

I realized that the part of this patch that changes everything but the
LogMessage is safe to commit, so I'll probably do that shortly. The
change the LogMessage can be separate, depending upon what we decide here.

Regards,
Blair

Index: subversion/bindings/javahl/native/LogMessageCallback.cpp
===================================================================
--- subversion/bindings/javahl/native/LogMessageCallback.cpp (revision 24623)
+++ subversion/bindings/javahl/native/LogMessageCallback.cpp (working copy)
@@ -87,7 +87,7 @@
         }
         sm_mid = env->GetMethodID(clazz, "singleMessage",
             "([L"JAVA_PACKAGE"/ChangePath;JLjava/lang/String;"
- "Ljava/util/Date;Ljava/lang/String;)V");
+ "JLjava/lang/String;)V");
         if (JNIUtil::isJavaExceptionThrown())
         {
            return SVN_NO_ERROR;
@@ -116,17 +116,10 @@
         }
     }
 
- jobject jdate = NULL;
+ apr_time_t commit_time = 0;
     if (date != NULL && *date != '\0')
     {
- apr_time_t timeTemp;
-
- SVN_ERR(svn_time_from_cstring(&timeTemp, date, pool));
- jdate = JNIUtil::createDate(timeTemp);
- if (JNIUtil::isJavaExceptionThrown())
- {
- return SVN_NO_ERROR;
- }
+ SVN_ERR(svn_time_from_cstring(&commit_time, date, pool));
     }
 
     jstring jauthor = JNIUtil::makeJString(author);
@@ -211,7 +204,7 @@
     }
 
     env->CallVoidMethod(m_callback, sm_mid, jChangedPaths, (jlong)rev, jauthor,
- jdate, jmessage);
+ (jlong)commit_time, jmessage);
     if (JNIUtil::isJavaExceptionThrown())
     {
        return SVN_NO_ERROR;
Index: subversion/bindings/javahl/src/org/tigris/subversion/javahl/LogMessageCallback.java
===================================================================
--- subversion/bindings/javahl/src/org/tigris/subversion/javahl/LogMessageCallback.java (revision 24623)
+++ subversion/bindings/javahl/src/org/tigris/subversion/javahl/LogMessageCallback.java (working copy)
@@ -15,9 +15,8 @@
  * ====================================================================
  * @endcopyright
  */
-package org.tigris.subversion.javahl;
 
-import java.util.Date;
+package org.tigris.subversion.javahl;
 
 /**
  * This interface is used to receive every log message for the log
@@ -31,9 +30,13 @@
      * @param changedPaths the paths that were changed
      * @param revision the revision of the commit
      * @param author the author of the commit
- * @param date the date of the commit
+ * @param timeMicros the time of the commit measured in the number
+ * of microseconds since 00:00:00 January 1, 1970 UTC
      * @param message the log message for the commit
      */
- public void singleMessage(ChangePath[] changedPaths, long revision,
- String author, Date date, String message);
+ public void singleMessage(ChangePath[] changedPaths,
+ long revision,
+ String author,
+ long timeMicros,
+ String message);
 }
Index: subversion/bindings/javahl/src/org/tigris/subversion/javahl/tests/BasicTests.java
===================================================================
--- subversion/bindings/javahl/src/org/tigris/subversion/javahl/tests/BasicTests.java (revision 24623)
+++ subversion/bindings/javahl/src/org/tigris/subversion/javahl/tests/BasicTests.java (working copy)
@@ -1876,6 +1876,18 @@
         assertEquals("wrong copy source rev", -1, cp[0].getCopySrcRevision());
         assertNull("wrong copy source path", cp[0].getCopySrcPath());
         assertEquals("wrong action", 'A', cp[0].getAction());
+ assertEquals("wrong time with getTimeMicros()",
+ lm[0].getTimeMicros()/1000,
+ lm[0].getDate().getTime());
+ assertEquals("wrong time with getTimeMillis()",
+ lm[0].getTimeMillis(),
+ lm[0].getDate().getTime());
+ assertEquals("wrong date with getTimeMicros()",
+ lm[0].getDate(),
+ new java.util.Date(lm[0].getTimeMicros()/1000));
+ assertEquals("wrong date with getTimeMillis()",
+ lm[0].getDate(),
+ new java.util.Date(lm[0].getTimeMillis()));
     }
 
     /**
Index: subversion/bindings/javahl/src/org/tigris/subversion/javahl/LogMessage.java
===================================================================
--- subversion/bindings/javahl/src/org/tigris/subversion/javahl/LogMessage.java (revision 24623)
+++ subversion/bindings/javahl/src/org/tigris/subversion/javahl/LogMessage.java (working copy)
@@ -32,6 +32,12 @@
     private String message;
 
     /**
+ * The time of the commit measured in the number of microseconds
+ * since 00:00:00 January 1, 1970 UTC.
+ */
+ private long timeMicros;
+
+ /**
      * The date of the commit.
      */
     private Date date;
@@ -54,16 +60,21 @@
     private ChangePath[] changedPaths;
 
     /**
- * This constructor is only called only from the thin wrapper.
+ * This constructor is the original constructor from Subversion
+ * 1.4 and older.
+ *
      * @param m the log message text
      * @param d the date of the commit
      * @param r the number of the revision
      * @param a the author of the commit
      * @param cp the items changed by this commit
+ * @deprecated Use the constructor that takes the number of
+ * microseconds since 00:00:00 January 1, 1970 UTC
      */
     LogMessage(ChangePath[] cp, long r, String a, Date d, String m)
     {
         message = m;
+ timeMicros = 1000*d.getTime();
         date = d;
         revision = r;
         author = a;
@@ -71,6 +82,27 @@
     }
 
     /**
+ * This constructor is only called only from the thin wrapper.
+ *
+ * @param m the log message text
+ * @param t the time of the commit measured in the number of
+ * microseconds since 00:00:00 January 1, 1970 UTC
+ * @param r the number of the revision
+ * @param a the author of the commit
+ * @param cp the items changed by this commit
+ * @since 1.5
+ */
+ LogMessage(ChangePath[] cp, long r, String a, long t, String m)
+ {
+ message = m;
+ timeMicros = t;
+ date = null;
+ revision = r;
+ author = a;
+ changedPaths = cp;
+ }
+
+ /**
      * Return the log message text
      * @return the log message text
      */
@@ -80,11 +112,37 @@
     }
 
     /**
+ * Returns the time of the commit
+ * @return the time of the commit measured in the number of
+ * microseconds since 00:00:00 January 1, 1970 UTC
+ * @since 1.5
+ */
+ public long getTimeMicros()
+ {
+ return timeMicros;
+ }
+
+ /**
+ * Returns the time of the commit
+ * @return the time of the commit measured in the number of
+ * milliseconds since 00:00:00 January 1, 1970 UTC
+ * @since 1.5
+ */
+ public long getTimeMillis()
+ {
+ return timeMicros/1000;
+ }
+
+ /**
      * Returns the date of the commit
      * @return the date of the commit
      */
     public Date getDate()
     {
+ if (null == date) {
+ date = new Date(timeMicros/1000);
+ }
+
         return date;
     }
 
Index: subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java
===================================================================
--- subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java (revision 24623)
+++ subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java (working copy)
@@ -1856,11 +1856,17 @@
     {
         private List messages = new ArrayList();
 
- public void singleMessage(ChangePath[] changedPaths, long revision,
- String author, Date date, String message)
- {
- LogMessage msg = new LogMessage(changedPaths, revision, author,
- date, message);
+ public void singleMessage(ChangePath[] changedPaths,
+ long revision,
+ String author,
+ long timeMicros,
+ String message)
+ {
+ LogMessage msg = new LogMessage(changedPaths,
+ revision,
+ author,
+ timeMicros,
+ message);
             messages.add(msg);
         }
 

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Apr 18 02:15:31 2007

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.