-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

André,

On 10/23/2009 5:36 PM, André Warnier wrote:
> Sorry Mark, I did just now, and figure that it must be happening
> somewhere around line 600 of that piece of art, but my Java knowledge is
> too limited to figure out what exactly it is doing.

It's not too hard. Starting from line 600, you have:

 600                    int pos = findIgnoreCase(hosts, host);

This method (presumably) locates the index into the 'hosts' array that
the given host matches. findIgnoreCase calls findIgnoreCase (overloaded
to take different parameters) and this happens:

1031     int b = map.length - 1;
1032
1033     // Special cases: -1 and 0
1034     if (b == -1) {
1035        return -1;
1036     }
1037     if (compareIgnoreCase(name, start, end, map[0].name) < 0 ) {
1038        return -1;
1039     }
1040     if (b == 0) {
1041        return 0;
1042     }

So, if there are no hosts (oops) or only one host and it's name doesn't
match the requested host, -1 is returned. If the requested host matches
the only defined host, 0 is returned.

Back to the internalMap method:

 601     if ((pos != -1) && (host.equalsIgnoreCase(hosts[pos].name))) {
 602        mappingData.host = hosts[pos].object;
 603        contexts = hosts[pos].contextList.contexts;
 604        nesting = hosts[pos].contextList.nesting;
 605     } else {
 606        if (defaultHostName == null) {
 607           return;
 608        }
 609        pos = find(hosts, defaultHostName);
 610        if ((pos != -1) && (defaultHostName.equals(hosts[pos].name))) {
 611           mappingData.host = hosts[pos].object;
 612           contexts = hosts[pos].contextList.contexts;
 613           nesting = hosts[pos].contextList.nesting;
 614        } else {
 615           return;
 616        }
 617     }

The variable pos is either -1 (if no host matched) or 0. If it's zero
and the hostname matches (again), it takes the first branch. Otherwise,
it takes the second branch and you get the default host (which has to be
located in the array by looking up its hostname).

So, to answer your question, the hostname is always looked-up in the
list of <Host> elements defined. If it doesn't match, the default
hostname is located in the same list and used.

The logic evaluates a bit more quickly if:

1. You define only a single host.
2. You define it to be the hostname you actually expect clients to use
   (that is, there is a slight performance hit if you just use
   "localhost" like I usually recommend).

I see some potential performance improvements, here, such as the following:

1. Cache a reference to the default <Host>: why bother looking it up for
every single request? It should never change!

2. Short-circuit all this logic when there is only one host and it is
the default host. There's no need to ever do all this mapping work when
that happens.

3. Use more search logic to determine whether the host you matches is an
exact match or a default match at the same time. It looks like
findIgnoreCase does half the work and then internalMap re-checks for
string equality. Presumably, the string equality check has occurred once
already, and need not be repeated.

4. Use a hash to locate matching <Host> (or alias) elements, rather than
the binary-search currently being used. I suspect that, unless /many/
hosts and aliases are defined, searches versus hashes are comparable, so
this may be more trouble than it's worth.

> If it happened to be (2), then one could argue that adding an <Alias>
> matching the real "Host:" of the calls, is actually slightly faster than
> not doing so.

If you look at the addHost method in Mapper.java, you'll see that, for
each <Alias> for a <Host>, the <Host>'s data is copied into the array
used for <Host> elements. Searching a large array is (somewhat) slower
than searching a small array, so you'd actually be making things go more
slowly by adding superfluous <Alias> elements.

> One would just love to catch Chuck some time..

I'll bet he's quick: you'd better wear cleats and gloves.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkrludoACgkQ9CaO5/Lv0PDPeQCffjGqxGcgimSHXIxueEbKnzJx
YMAAoIci+r/WUFQHIwKJpmfPx4fSqPjO
=iDUS
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to