for (CountHashMap.Entry entry : cmap.countEntrySet()) {
which you can't do with the somewhat butchered current entrySet()
implementation. Indeed, I'm not sure quite how one is supposed to use that.
Perhaps in an iterator and cast the result to a CountHashMap.Entry?
git-svn-id: https://samskivert.googlecode.com/svn/trunk@2319 6335cc39-0255-0410-8fd6-9bcaacd3b74c
configuration system property is set (and a particular logger is not
specifically configured).
git-svn-id: https://samskivert.googlecode.com/svn/trunk@2315 6335cc39-0255-0410-8fd6-9bcaacd3b74c
samskivert to use logging services without creating a dependency on a logging
implementation.
This is basically what JCL (Jakarta Commons Logging) does except they do
auto-detection based on what's in the classpath and we're only going to
auto-detect log4j and only use it if we see that a log4j configuration has been
provided via a system property (or maybe not at all, I'm not sure yet). The
point is avoid the major gripe about JCL which is that when you stick some
logging system's jar file into your classpath for some other dependency (or
it's there for unknown reasons like maybe your servlet container uses it), all
of a sudden your log output disappears or breaks.
I had an idea while doing this and couldn't resist slipping it in: all of the
logging methods take varargs additional parameters which are a set of key/value
pairs to append to the log message in our standard format with an optional
final exception to be logged as well.
So instead of:
log.warning("Oh crap, the fibbleminscher has exploded [state=" + 15 +
", monkeys=" + StringUtil.toString(_monkeys) + "].");
You do:
log.warning("Oh crap, the fibbleminscher has exploded.", "state", 15,
"monkeys", _monkeys);
The formatter automatically does the StringUtil.toString magic on the arguments
(and does it safely so that if toString throws an exception the log message
isn't lost). You can also throw an exception in the mix:
log.warning("Oh crap, the fibbleminscher has exploded.", "state", 15,
"monkeys", _monkeys, ioe);
Or supply one with no parameters:
log.warning("Oh mammy!", ioe);
Or even just log an exception if you have nothing pithy to add:
log.warning(ioe);
Some research shows that other people have started doing this in their logging
systems as well under the fancier name of parameterized logging. The big
benefit is that you can pass objects that are expensive to toString() and avoid
toString()ing them unless you're actually going to generate the log message.
In our case we also get the benefit of our standard formatting and less
cluttered code (begone lots of + ", ...=" + typing).
I'm going to be doing away with the old samskivert Log code and converting all
of our libraries (and projects) to use this new shim so that we can easily
switch to using log4j, which for other reasons we want to use instead of Java's
built-in logging.
git-svn-id: https://samskivert.googlecode.com/svn/trunk@2311 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This adds extra params around a bunch of things. I'll let the gods of Depot
sort that out.
BTW: Arithmetic.Div is still totally broken. It somehow booches the prepared
statement. I tried changing the operator String to "//" and that sorta worked,
but then the next operator over was missing...
I'm working around this using Mul, but it'd be nice..
git-svn-id: https://samskivert.googlecode.com/svn/trunk@2302 6335cc39-0255-0410-8fd6-9bcaacd3b74c
except where Sun has already done it for us.
- We always return 1, 0, or -1.
- We guard against overflows for ints and longs.
git-svn-id: https://samskivert.googlecode.com/svn/trunk@2300 6335cc39-0255-0410-8fd6-9bcaacd3b74c
explicit reference back to the Interval so that we can clear that
reference when the Interval is cancelled. The reason for this is that
TimerTasks sit on the Timer's internal queue until their scheduled
execution time, even if they've been cancelled. We want to allow
any references that the Interval has to be gc-able after cancellation.
Note two things:
- Once an interval is cancelled, calls to getInterval() or toString()
on the RunBuddy are invalid, even if the calls are happening inside
expired(). This probably will only affect you if you cancel() the interval
in the expired() method, but maybe I should prevent badness here anyway...
- Interval has potential for a small slip that would prevent gc. If
multiple threads are scheduling and cancelling an interval simultaneously,
it's possible (since I avoid synchronizing anywhere) for a task to
be created that incorrectly thinks it should be alive. It will never
expire(), as once it tries to it will discover that it's invalid
and will cancel at that time, but in the meanwhile the task has been
holding onto a reference to the Interval. This would not be an error,
just a non-optimal memory situation, it would rarely occur, and it
probably can never occur in most of our code since we tend to use
a single thread for scheduling and cancelling Intervals.
git-svn-id: https://samskivert.googlecode.com/svn/trunk@2298 6335cc39-0255-0410-8fd6-9bcaacd3b74c