/* This file is part of VoltDB.
 * Copyright (C) 2008-2016 VoltDB Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

package windowing;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import org.voltdb.client.ClientResponse;
import org.voltdb.client.ClientResponseWithPartitionKey;
import org.voltdb.types.TimestampType;

/**
 * Runnable-implementor that runs a stored procedure at every partition.
 * Each stored procedure deletes tuples that are older than a given
 * cutoff date or past the maximum desired row count for the partition.
 * All stored procedures are run concurrently using asynchronous calls.
 *
 */
public class ContinuousDeleter implements Runnable {

    // Global state
    final WindowingApp app;

    // track failures for reporting
    final AtomicLong failureCount = new AtomicLong(0);

    ContinuousDeleter(WindowingApp app) {
        this.app = app;
    }

    @Override
    public void run() {

        // Will be set to true if any partition needs to delete more rows to meet the goals.
        AtomicBoolean unfinished = new AtomicBoolean(false);

        // Default yield time between deletes. May be shortened if there are a ton of tuples that need deleting.
        long yieldTimeMs = app.config.deleteyieldtime;

        try {
            // Get the targets from the main app class. Only one will be used, depending on whether the user is deleting
            // old rows by date or by row count.
            TimestampType dateTarget = app.getTargetDate();
            long rowTarget = app.getTargetRowsPerPartition();
            // Send the procedure call to all partitions and get results from each partitions.
            ClientResponseWithPartitionKey[] responses;
            if (app.config.historyseconds > 0) {
                responses = app.client.callAllPartitionProcedure("DeleteAfterDate", dateTarget, app.config.deletechunksize);
            }
            // Deleting all rows beyond a given rowcount...
            else /* if (app.config.maxrows > 0) */ {
                responses = app.client.callAllPartitionProcedure("DeleteOldestToTarget", rowTarget, app.config.deletechunksize);
            }

            app.updatePartitionCount(responses.length);
            for (ClientResponseWithPartitionKey resp: responses) {
                if (resp.response.getStatus() == ClientResponse.SUCCESS) {
                    long tuplesDeleted = resp.response.getResults()[0].asScalarLong();
                    app.addToDeletedTuples(tuplesDeleted);

                    // If the procedure deleted up to its limit, reduce the time before the deletes process runs again.
                    if (tuplesDeleted >= app.config.deletechunksize) {
                        unfinished.set(true);
                    }
                } else {
                    failureCount.incrementAndGet();
                }
            }
            // If this round of deletes didn't remove all of the tuples that could have been removed, reduce the pause time before the
            // next round to zero. If this process still can't keep up, then you can always add a second ContinuousDeleter instance in
            // WindowingApp and schedule two of them to run concurrently.
            if (unfinished.get()) {
                yieldTimeMs = 0;
            }

        } catch (Exception e) {
            failureCount.incrementAndGet();
        } catch (Throwable t) {
            t.printStackTrace();
            // Live dangerously and ignore this.
        } finally {
            // Use a finally block to ensure this task is re-scheduled.
            app.scheduler.schedule(this, yieldTimeMs, TimeUnit.MILLISECONDS);
        }
    }
}

@@ -2996,68 +2996,8 @@
   %7D%0A
-            // Deleting all rows beyond a given rowcount...%0A
     

fix compiling issue