Hi Alan, Paul,

Just a comment on comment: wouldn't the variant with a single compute replace a Package with itself on each repeated call? Semantically it is the same, but there is a volatile memory store on the cache-hit involved where in the original variant, it isn't...

On 03/11/2016 05:50 PM, Paul Sandoz wrote:
j.l.ClassLoader
—

1777         // define Package object if the named package is not yet defined
1778         NamedPackage p = packages.computeIfAbsent(name,
1779                                                   k -> 
NamedPackage.toPackage(name, m));
1780         if (p instanceof Package)
1781             return (Package)p;
1782
1783         // otherwise, replace the NamedPackage object with Package object
1784         return (Package)packages.compute(name, this::toPackage);

You could merge the computeIfAbsent and compute into a single compute call if 
you so wish.

return (Package)packages.compute((n, p) -> {
   // define Package object if the named package is not yet defined
   if (p == null) return NamedPackage.toPackage(name, m);
   // otherwise, replace the NamedPackage object with Package object
   return (p instanceof Package) ? p : toPackage(n, p);
});

You could pre-screen the .compute with a .get and this would be the more optimal (no locking on cache-hits):

NamedPackage p = packages.get(name);
if (p instanceof Package) {
    return (Package) p;
}

return (Package)packages.compute((n, p) -> {
// define Package object if it is not yet defined or replace it if it is a NamedPackage
  return (p instanceof Package) ? p : NamedPackage.toPackage(n, m);
});

See, no private ClassLoader.toPackage(String name, NamedPackage p) needed.


If you also care for constant lambda, this could be optimized even further, but for the price of more complex code:


NamedPackage p = packages.get(name);

if (p instanceof Package) {
    return (Package) p;
} else if (p == null) {
    Package pkg = NamedPackage.toPackage(name, m);
    p = packages.putIfAbsent(name, pkg);
    if (p == null) {
        return pkg;
    }
}

return (Package)packages.compute((n, p) -> {
    assert p != null;
    // replace NamedPackage with Package
return (p instanceof Package) ? p : NamedPackage.toPackage(p.name(), p.module());
});


Regards, Peter

Reply via email to