docs: private boolean isDiskCacheHit(final HttpQuery query,
                                   final long end_time,
                                   final int max_age,
                                   final String basepath) throws IOException {
      final String cachepath = basepath + (query.hasQueryStringParam("ascii")
                                           ? ".txt" : ".png");
      final File cachedfile = new File(cachepath);
      if (cachedfile.exists()) {
        final long bytes = cachedfile.length();
        if (bytes < 21) {  // Minimum possible size for a PNG: 21 bytes.
                           // For .txt files, <21 bytes is almost impossible.
          logWarn(query, "Cached " + cachepath + " is too small ("
                  + bytes + " bytes) to be valid.  Ignoring it.");
          return false;
        }
        if (staleCacheFile(query, end_time, max_age, cachedfile)) {
          return false;
        }
        if (query.hasQueryStringParam("json")) {
          HashMap<String, Object> map = loadCachedJson(query, end_time,
              max_age, basepath);
          if (map == null) {
            map = new HashMap<String, Object>();
          }
          map.put("timing", query.processingTimeMillis());
          map.put("cachehit", "disk");
          query.sendReply(JSON.serializeToBytes(map));
        } else if (query.hasQueryStringParam("png")
                   || query.hasQueryStringParam("ascii")) {
          query.sendFile(cachepath, max_age);
        } else {
          query.sendReply(HttpQuery.makePage("TSDB Query", "Your graph is ready",
              "<img src=\"" + query.request().getUri() + "&amp;png\"/><br/>"
              + "<small>(served from disk cache)</small>"));
        }
        graphs_diskcache_hit.incrementAndGet();
        return true;
      }
      // We didn't find an image.  Do a negative cache check.  If we've seen
      // this query before but there was no result, we at least wrote the JSON.
      final HashMap<String, Object> map = loadCachedJson(query, end_time,
          max_age, basepath);
      // If we don't have a JSON file it's a complete cache miss.  If we have
      // one, and it says 0 data points were plotted, it's a negative cache hit.
      if (map == null || !map.containsKey("plotted") ||
          ((Integer)map.get("plotted")) == 0) {
        return false;
      }
      if (query.hasQueryStringParam("json")) {
        map.put("timing", query.processingTimeMillis());
        map.put("cachehit", "disk");
        query.sendReply(JSON.serializeToBytes(map));
      } else if (query.hasQueryStringParam("png")) {
        query.sendReply(" ");  // Send back an empty response...
      } else {
          query.sendReply(HttpQuery.makePage("TSDB Query", "No results",
              "Sorry, your query didn't return anything.<br/>"
              + "<small>(served from disk cache)</small>"));
      }
      graphs_diskcache_hit.incrementAndGet();
      return true;
    }