Thoughts on Predicates and/or Matchers
Rob is working on making filter development easier. Currently whenever a user wants to do some custom filtering, they need to extend our
AbstractFilterList
and implement its
filterMatches(Object)
method. This gets the job done but there's some problems:
Discourages code reuse from the filterMatches() method
Reinventing the wheel: many users will end up implementing common requirements like a filterMatches() that tests if an element is in some other list.
Slow: implicitly pairs one AbstractFilterList (and associated costs) for every matching strategy
Not dynamic: filterMatches() method does not lend itself to different behaviour over time
Therefore we're building something smarter using predicates, or as we like to call them, Matcher
s. Since Matcher
s aren't exactly predicates, the name-change makes sense. For example, rarely do predicates fire events when their match logic is modified!
Matchers are great. We can build in a library of ready-to-use matchers for common tasks such as:
Testing for equality with any object, null or otherwise. Via '==' or even '.equals()'
Testing for containment in some other set
Comparison to a constant.
Thresholds
instanceof, .getClass()
Composition of multiple matchers with AND, OR, NOT, XOR etc.
Delegate matchers. I can delegate to another matcher using an extracted bean property of the tested object.
Of course the above Matchers stuff will require a lot of code! Rob's written a lot of it already, but I have this (irrational?) fear that we're getting away from our 'core competency'. Why is this a problem?
That code is going to want to be maintaned! It will require at least one huge effort when we migrate to Java 5.
We're all-of-the-sudden becoming a toolkit for more than list transformations. From here it would seem natural to add Closures as well, since they are necessary for building delegation-capable predicates.
There's already at least three open source predicate toolkits. They're all incompatible with different merits and design goals. We will simply be yet another incompatible implementation to add to the mix. Adapters simplify this problem, but there are limitations! For example, no other predicates toolkit that I found used events to send notification of a mutation. And this feature is a must for our implementation!
So what is the solution? Obviously matchers are a good thing and we want them in our code. Rob is a hell of a coder and he's dedicated to matchers, so most of my complaints about the required effort are muted. But I still think we're getting away from our core-competency! Yuck.
# posted by Jesse Wilson
on Saturday, February 26, 2005
0 comments
post a comment
Notes on variable-height rows in a JTable
Recently Sun hosted a developer web chat,
Getting High Performance from Your Desktop Client. I decided to ask about a problem I faced a few months ago: performance of JTables with variable-height rows.
The PremiseTo track the heights of each row,
JTable
uses a
SizeSequence
. This class stores the height of each row in pixels, plus it includes helper methods to answer common questions,
"What row belongs in pixel P?" and
"What's pixel range for row R?". To make answering these questions snappy, the
SizeSequence
precomputes the answers and stores them in an array.
The ProblemSuppose we add, remove or change the height of a row in our
JTable
. Now our
SizeSequence
's answers array is out of sync. Unfortunately the
SizeSequence
must recalculate the entire answers array. For a table with
R rows, this will require
R operations!
The Problem MultipliesSuppose our table is populated one row at a time. This will be the case for all applications where the rows are streamed or filtered. Now this is
R changes, each one requiring
R operations to update the
SizeSequence
. For a table with
R rows, this will require
R2 operations!
Workaround 1Don't use variable row height
JTable
s!
Workaround 2Bulk up row changes. Instead of adding rows one at a time, add them ten at a time or better, all at once.
Workaround 3Go have a coffee and wait for Sun to resolve issue
6231057. This should shorten the cost of a row change from
R operations to a much more tolerable log
2R.
# posted by Jesse Wilson
on Thursday, February 24, 2005
0 comments
post a comment
Simple mail trick for good or evil
My mail client (Mail.app) allows me to configure which email headers get displayed. I set it up to display some extra headers for my own novelty...
X-Mailer:
display the Mail client program used to craft a given email. This is mostly for my own curiosity. If somebody is using a Mac, I might ask them if they're upgrading to
OS X Tiger. If they're using Outlook, I'll think twice about opening the screensaver attachments!
X-Originating-Ip:
this header appears in Hotmail.com messages. It gives the IP address of the sending user. I can use this to probe for FTP servers, SSH servers and the like on my friend's machines. For non-hotmail users, this IP address is usually found in the last of the
Received:
headers.
# posted by Jesse Wilson
on Monday, February 21, 2005
0 comments
post a comment
32 bit file sizes in Apache HTTPD
Today I backed up some files from my Powerbook to a DVD image. Once I created the DVD image I was going to transfer it to my PC which is the home of my burner. How shall I transfer the file?
Via SMB? Nope. I've had very little success with SMB in the past, and I think it's slow
Via FTP? Nope. The Windows FTP command sucks wind.
Via HTTP? Sure! My Mac has Apache built-in, and then I can download with my browser. This combination might even support resume if the transfer is interrupted.
I dumped the DVD image in my ~/Sites/
folder, which is the Mac-equivalent of ~/public_html
. But when I viewed that directory from my PC, the 4.37 GB file morphed into a 386 MB file. What the heck?
And now a math lesson. My file was 4.37 GB. More precisely: 4699488256 bytes. And unfortunately for me, 4699488256 > (232). In fact, 4.37 GB mod (232) = 386 MB.
Lesson learned? Apache file sizes are 32-bit. Don't transfer anything larger than 4 GB over the web!
# posted by Jesse Wilson
on Wednesday, February 02, 2005
0 comments
post a comment