private void handleDeleteBucket(HttpExchange exchange, String bucketName) throws IOException { if (buckets.containsKey(bucketName)) { Bucket bucket = buckets.get(bucketName); if (bucket.isEmpty()) { respondErrorAndClose(exchange, ErrorResponse.BUCKET_NOT_EMPTY); } else { buckets.remove(bucketName); respondAndClose(exchange, HttpURLConnection.HTTP_NO_CONTENT); } } else { respondErrorAndClose(exchange, ErrorResponse.NO_SUCH_BUCKET); } }
/** * Gets the Buckets for the specified keys. A bucket is built around an IdentifiableValue so you * can putAll() them without the risk of overwriting other threads' changes. Buckets also hide the * underlying details of storage for negative, empty, and uncacheable results. * * <p>Note that worst case (a cold cache), obtaining each bucket might require three memcache * requests: a getIdentifiable() which returns null, a put(EMPTY), and another getIdentifiable(). * Since there is no batch getIdentifiable(), this is *per key*. * * <p>When keys are uncacheable (per CacheControl) or the memcache is down, you will still get an * empty bucket back. The bucket will have null IdentifiableValue so we can identify it as * uncacheable. * * @return the buckets requested. Buckets will never be null. You will always get a bucket for * every key. */ public Map<Key, Bucket> getAll(Iterable<Key> keys) { Map<Key, Bucket> result = new HashMap<>(); // Sort out the ones that are uncacheable Set<Key> potentials = new HashSet<>(); for (Key key : keys) { if (cacheControl.getExpirySeconds(key) == null) result.put(key, new Bucket(key)); else potentials.add(key); } Map<Key, IdentifiableValue> ivs; try { ivs = this.memcache.getIdentifiables(potentials); } catch (Exception ex) { // This should really only be a problem if the serialization format for an Entity changes, // or someone put a badly-serializing object in the cache underneath us. log.log(Level.WARNING, "Error obtaining cache for " + potentials, ex); ivs = new HashMap<>(); } // Figure out cold cache values Map<Key, Object> cold = new HashMap<>(); for (Key key : potentials) if (ivs.get(key) == null) cold.put(key, null); if (!cold.isEmpty()) { // The cache is cold for those values, so start them out with nulls that we can make an IV for this.memcache.putAll(cold); try { Map<Key, IdentifiableValue> ivs2 = this.memcache.getIdentifiables(cold.keySet()); ivs.putAll(ivs2); } catch (Exception ex) { // At this point we should just not worry about it, the ivs will be null and uncacheable } } // Now create the remaining buckets for (Key key : keys) { // iv might still be null, which is ok - that means uncacheable IdentifiableValue iv = ivs.get(key); Bucket buck = (iv == null) ? new Bucket(key) : new Bucket(key, iv); result.put(key, buck); if (buck.isEmpty()) this.stats.recordMiss(buck.getKey()); else this.stats.recordHit(buck.getKey()); } return result; }