public synchronized boolean closeBucket(String bucketName, List<String> clusterNodes) {
    String bucketId = getBucketId(bucketName, clusterNodes);
    String clusterId = getClusterId(clusterNodes);
    if (!openedBuckets.containsKey(bucketId) || !openedClusters.containsKey(clusterId)) {
      return false;
    }
    bucketUsageCounts.put(bucketId, bucketUsageCounts.get(bucketId) - 1);
    clusterUsageCounts.put(clusterId, clusterUsageCounts.get(clusterId) - 1);
    Boolean bucketClosed = true;
    Boolean clusterClosed = true;
    if (bucketUsageCounts.get(bucketId) == 0) {
      bucketClosed = openedBuckets.get(bucketId).close();
      openedBuckets.remove(bucketId);
      bucketUsageCounts.remove(bucketId);
      if (clusterUsageCounts.get(clusterId) == 0) {
        clusterClosed = openedClusters.get(clusterId).disconnect();
        openedClusters.remove(clusterId);
        clusterUsageCounts.remove(clusterId);
      }
    }
    return bucketClosed && clusterClosed;
  }
A synchronized method to close a bucket given the bucket name. Each time this method is called, the counter of
usage of the bucket is decreased by one. Only when the counter becomes zero will the bucket be actually closed.
Same for cluster, only when all buckets within a cluster have been closed will the cluster be closed.
@param bucketName name of the bucket to be opened
@param clusterNodes list of cluster nodes
@return true if bucket is closed successfully, otherwise false.
samza-kv-couchbase/src/main/java/org/apache/samza/table/remote/couchbase/CouchbaseBucketRegistry.java