/**
  * Purge expired entries. Expiration entries are stored in a single key (expirationKey) within a
  * specific ColumnFamily (set by configuration). The entries are grouped by expiration timestamp
  * in SuperColumns within which each entry's key is mapped to a column
  */
 @Override
 protected void purgeInternal() throws CacheLoaderException {
   if (trace) log.trace("purgeInternal");
   Cassandra.Client cassandraClient = null;
   try {
     cassandraClient = dataSource.getConnection();
     // We need to get all supercolumns from the beginning of time until
     // now, in SLICE_SIZE chunks
     SlicePredicate predicate = new SlicePredicate();
     predicate.setSlice_range(
         new SliceRange(
             ByteBufferUtil.EMPTY_BYTE_BUFFER,
             ByteBufferUtil.bytes(System.currentTimeMillis()),
             false,
             SLICE_SIZE));
     Map<ByteBuffer, Map<String, List<Mutation>>> mutationMap =
         new HashMap<ByteBuffer, Map<String, List<Mutation>>>();
     for (boolean complete = false; !complete; ) {
       // Get all columns
       List<ColumnOrSuperColumn> slice =
           cassandraClient.get_slice(
               expirationKey, expirationColumnParent, predicate, readConsistencyLevel);
       complete = slice.size() < SLICE_SIZE;
       // Delete all keys returned by the slice
       for (ColumnOrSuperColumn crumb : slice) {
         SuperColumn scol = crumb.getSuper_column();
         for (Iterator<Column> i = scol.getColumnsIterator(); i.hasNext(); ) {
           Column col = i.next();
           // Remove the entry row
           remove0(ByteBuffer.wrap(col.getName()), mutationMap);
         }
         // Remove the expiration supercolumn
         addMutation(
             mutationMap,
             expirationKey,
             config.expirationColumnFamily,
             ByteBuffer.wrap(scol.getName()),
             null,
             null);
       }
     }
     cassandraClient.batch_mutate(mutationMap, writeConsistencyLevel);
   } catch (Exception e) {
     throw new CacheLoaderException(e);
   } finally {
     dataSource.releaseConnection(cassandraClient);
   }
 }