Author: bodewig
Date: Mon Mar 5 19:38:11 2012
New Revision: 1297194
URL: http://svn.apache.org/viewvc?rev=1297194&view=rev
Log:
cache in AbsoluteTimeDateFormatter must be sensitive to subclass. LOG4NET-323
Added:
logging/log4net/trunk/tests/src/DateFormatter/
logging/log4net/trunk/tests/src/DateFormatter/AbsoluteTimeDateFormatterTest.cs
(with props)
Modified:
logging/log4net/trunk/src/DateFormatter/AbsoluteTimeDateFormatter.cs
Modified: logging/log4net/trunk/src/DateFormatter/AbsoluteTimeDateFormatter.cs
URL:
http://svn.apache.org/viewvc/logging/log4net/trunk/src/DateFormatter/AbsoluteTimeDateFormatter.cs?rev=1297194&r1=1297193&r2=1297194&view=diff
==============================================================================
--- logging/log4net/trunk/src/DateFormatter/AbsoluteTimeDateFormatter.cs
(original)
+++ logging/log4net/trunk/src/DateFormatter/AbsoluteTimeDateFormatter.cs Mon
Mar 5 19:38:11 2012
@@ -18,6 +18,7 @@
#endregion
using System;
+using System.Collections;
using System.IO;
using System.Text;
@@ -103,19 +104,31 @@ namespace log4net.DateFormatter
// Calculate the current time precise only to the second
long currentTimeToTheSecond = (dateToFormat.Ticks -
(dateToFormat.Ticks % TimeSpan.TicksPerSecond));
+ string timeString = null;
// Compare this time with the stored last time
// If we are in the same second then append
// the previously calculated time string
- if (s_lastTimeToTheSecond != currentTimeToTheSecond)
- {
+ if (s_lastTimeToTheSecond != currentTimeToTheSecond)
+ {
+ s_lastTimeStrings.Clear();
+ }
+ else
+ {
+ timeString = (string) s_lastTimeStrings[GetType()];
+ }
+
+ if (timeString == null)
+ {
// lock so that only one thread can use the
buffer and
- // update the s_lastTimeToTheSecond and
s_lastTimeString
+ // update the s_lastTimeToTheSecond and
s_lastTimeStrings
// PERF: Try removing this lock and using a new
StringBuilder each time
lock(s_lastTimeBuf)
{
- if (s_lastTimeToTheSecond !=
currentTimeToTheSecond)
- {
+ timeString = (string)
s_lastTimeStrings[GetType()];
+
+ if (timeString == null)
+ {
// We are in a new second.
s_lastTimeBuf.Length = 0;
@@ -123,7 +136,7 @@ namespace log4net.DateFormatter
FormatDateWithoutMillis(dateToFormat, s_lastTimeBuf);
// Render the string buffer to
a string
- string currentDateWithoutMillis
= s_lastTimeBuf.ToString();
+ timeString =
s_lastTimeBuf.ToString();
#if NET_1_1
// Ensure that the above string
is written into the variable NOW on all threads.
@@ -131,12 +144,12 @@ namespace log4net.DateFormatter
System.Threading.Thread.MemoryBarrier();
#endif
// Store the time as a string
(we only have to do this once per second)
- s_lastTimeString =
currentDateWithoutMillis;
+ s_lastTimeStrings[GetType()] =
timeString;
s_lastTimeToTheSecond =
currentTimeToTheSecond;
}
}
}
- writer.Write(s_lastTimeString);
+ writer.Write(timeString);
// Append the current millisecond info
writer.Write(',');
@@ -190,7 +203,7 @@ namespace log4net.DateFormatter
/// Last stored time with precision up to the second, formatted
/// as a string.
/// </summary>
- private static string s_lastTimeString;
+ private static Hashtable s_lastTimeStrings = new Hashtable();
#endregion Private Static Fields
}
Added:
logging/log4net/trunk/tests/src/DateFormatter/AbsoluteTimeDateFormatterTest.cs
URL:
http://svn.apache.org/viewvc/logging/log4net/trunk/tests/src/DateFormatter/AbsoluteTimeDateFormatterTest.cs?rev=1297194&view=auto
==============================================================================
---
logging/log4net/trunk/tests/src/DateFormatter/AbsoluteTimeDateFormatterTest.cs
(added)
+++
logging/log4net/trunk/tests/src/DateFormatter/AbsoluteTimeDateFormatterTest.cs
Mon Mar 5 19:38:11 2012
@@ -0,0 +1,105 @@
+#region Apache License
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to you under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#endregion
+
+using System;
+using System.IO;
+using System.Text;
+using log4net.DateFormatter;
+using NUnit.Framework;
+
+namespace log4net.Tests.DateFormatter
+{
+
+ [TestFixture]
+ public class AbsoluteTimeDateFormatterTest
+ {
+
+ [TearDown]
+ public void resetCounts()
+ {
+ FormatterOne.invocations = 0;
+ }
+
+ [Test]
+ public void CacheWorksForSameTicks()
+ {
+ StringWriter sw = new StringWriter();
+ FormatterOne f1 = new FormatterOne();
+ FormatterOne f2 = new FormatterOne();
+ DateTime dt = DateTime.Now;
+ f1.FormatDate(dt, sw);
+ f2.FormatDate(dt, sw);
+ Assert.AreEqual(1, FormatterOne.invocations);
+ }
+
+ [Test]
+ public void CacheWorksForSameSecond()
+ {
+ StringWriter sw = new StringWriter();
+ FormatterOne f1 = new FormatterOne();
+ FormatterOne f2 = new FormatterOne();
+ DateTime dt1 = DateTime.Today;
+ DateTime dt2 = dt1.AddMilliseconds(600);
+ f1.FormatDate(dt1, sw);
+ f2.FormatDate(dt2, sw);
+ Assert.AreEqual(1, FormatterOne.invocations);
+ }
+
+ [Test]
+ public void CacheExpiresWhenCrossingSecond()
+ {
+ StringWriter sw = new StringWriter();
+ FormatterOne f1 = new FormatterOne();
+ FormatterOne f2 = new FormatterOne();
+ DateTime dt1 = DateTime.Today.AddMinutes(1);
+ DateTime dt2 = dt1.AddMilliseconds(1100);
+ f1.FormatDate(dt1, sw);
+ f2.FormatDate(dt2, sw);
+ Assert.AreEqual(2, FormatterOne.invocations);
+ }
+
+ [Test]
+ public void CacheIsLocalToSubclass()
+ {
+ StringWriter sw = new StringWriter();
+ FormatterOne f1 = new FormatterOne();
+ FormatterTwo f2 = new FormatterTwo();
+ DateTime dt1 = DateTime.Today.AddMinutes(10);
+ f1.FormatDate(dt1, sw);
+ f2.FormatDate(dt1, sw);
+ Assert.AreEqual(2, FormatterOne.invocations);
+ }
+ }
+
+ internal class FormatterOne : AbsoluteTimeDateFormatter
+ {
+ internal static int invocations = 0;
+
+ override protected void FormatDateWithoutMillis(DateTime dateToFormat,
+ StringBuilder buffer)
+ {
+ invocations++;
+ }
+
+ }
+
+ internal class FormatterTwo : FormatterOne
+ {
+ }
+}
Propchange:
logging/log4net/trunk/tests/src/DateFormatter/AbsoluteTimeDateFormatterTest.cs
------------------------------------------------------------------------------
svn:eol-style = native