The actual implementation does not behave as nicely as one would hope, for a few reasons:
1. isEmpty actually tries to load the newestBuild, rather than simply checking whether there is some idOnDisk.
Arguably this is necessary, since there could be an unloadable build record, in which case it would be technically correct for the map to be considered empty.
2. Loading AbstractLazyLoadRunMap.newestBuild calls search(MAX_VALUE, DESC), which behaves oddly, by doing a binary search, and thus perhaps loading lg(|map|) entries.
You would think that it would suffice to check for the last member of idOnDisk in index.byId.
3. The iterator eagerly loads the next value before hasNext has even been called.
Looks bad in a test, though it probably has little practical impact since most callers would be calling hasNext soon afterward anyway.
Might cause one extra build record to be loaded unnecessarily from a limited RunList.
If this is set, use it instead of ServletRequest.getServerPort() for purposes of getRootUrlFromRequest().
Also treat the default port as scheme-specific in that method (which presumes that we in fact got the reported port right).
And enhance the reverse proxy setup monitor to validate that the Referer header (/manage)
actually matches what we have computed from getRootUrlFromRequest;
if it does not, something is messed up, though it may require some digging to find what.
(Would be better to let the monitor specify the exact problem it determined,
though this is not always actually possible;
for example if you are missing AllowEncodedSlashes NoDecode in Apache,
you just get a 404 from Apache without even getting to Jenkins.)
... based on Tyler's discovery at https://gist.github.com/rtyler/9195510
testRemoting(hudson.util.ProcessTreeTest) Time elapsed: 0.097 sec <<< ERROR!
java.util.NoSuchElementException: null
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:897)
at java.util.HashMap$ValueIterator.next(HashMap.java:922)
at hudson.util.ProcessTreeTest$MyCallable.call(ProcessTreeTest.java:42)
at hudson.util.ProcessTreeTest$MyCallable.call(ProcessTreeTest.java:38)
at hudson.remoting.UserRequest.perform(UserRequest.java:118)
at hudson.remoting.UserRequest.perform(UserRequest.java:48)
at hudson.remoting.Request$2.run(Request.java:328)
at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
He runs this on FreeBSD.