public static Deferred<Integer> deleteRange(final TSDB tsdb, 
      final byte[] tsuid, final long start_time, final long end_time) {
    if (end_time < 1) {
      throw new IllegalArgumentException("The end timestamp has not been set");
    }
    if (end_time < start_time) {
      throw new IllegalArgumentException(
          "The end timestamp cannot be less than the start timestamp");
    }
    
    final List<Deferred<Object>> delete_requests = new ArrayList<Deferred<Object>>();
    int width = tsuid != null ? 
        Const.SALT_WIDTH() + tsuid.length + Const.TIMESTAMP_BYTES :
      Const.SALT_WIDTH() + TSDB.metrics_width() + Const.TIMESTAMP_BYTES;
    final byte[] start_row = new byte[width];
    final byte[] end_row = new byte[width];
    
    // downsample to seconds for the row keys
    final long start = start_time / 1000;
    final long end = end_time / 1000;
    final long normalized_start = (start - (start % Const.MAX_TIMESPAN));
    final long normalized_end = (end - (end % Const.MAX_TIMESPAN) + Const.MAX_TIMESPAN);
    Bytes.setInt(start_row, (int) normalized_start, 
        Const.SALT_WIDTH() + TSDB.metrics_width());
    Bytes.setInt(end_row, (int) normalized_end, 
        Const.SALT_WIDTH() + TSDB.metrics_width());
    
    if (tsuid != null) {
      // first copy the metric UID then the tags
      System.arraycopy(tsuid, 0, start_row, Const.SALT_WIDTH(), TSDB.metrics_width());
      System.arraycopy(tsuid, 0, end_row, Const.SALT_WIDTH(), TSDB.metrics_width());
      width = Const.SALT_WIDTH() + TSDB.metrics_width() + Const.TIMESTAMP_BYTES;
      final int remainder = tsuid.length - TSDB.metrics_width();
      System.arraycopy(tsuid, TSDB.metrics_width(), start_row, width, remainder);
      System.arraycopy(tsuid, TSDB.metrics_width(), end_row, width, remainder);
    }

    /**
     * Iterates through the scanner results in an asynchronous manner, returning
     * once the scanner returns a null result set.
     */
    final class ScannerCB implements Callback<Deferred<List<Deferred<Object>>>, 
        ArrayList<ArrayList<KeyValue>>> {
      final Scanner scanner;

      public ScannerCB() {
        scanner = tsdb.getClient().newScanner(tsdb.dataTable());
        scanner.setStartKey(start_row);
        scanner.setStopKey(end_row);
        scanner.setFamily(FAMILY);
        if (tsuid != null) {
          final List<String> tsuids = new ArrayList<String>(1);
          tsuids.add(UniqueId.uidToString(tsuid));
          Internal.createAndSetTSUIDFilter(scanner, tsuids);
        }
      }
      
      public Deferred<List<Deferred<Object>>> scan() {
        return scanner.nextRows().addCallbackDeferring(this);
      }
      
      @Override
      public Deferred<List<Deferred<Object>>> call (
          final ArrayList<ArrayList<KeyValue>> rows) throws Exception {
        if (rows == null || rows.isEmpty()) {
          return Deferred.fromResult(delete_requests);
        }
        
        for (final ArrayList<KeyValue> row : rows) {
          final long base_time = Internal.baseTime(tsdb, row.get(0).key());
          for (KeyValue column : row) {
            if ((column.qualifier().length == 3 || column.qualifier().length == 5)
                && column.qualifier()[0] == PREFIX()) {
              final long timestamp = timeFromQualifier(column.qualifier(), 
                  base_time);
              if (timestamp < start_time || timestamp > end_time) {
                continue;
              }
              final DeleteRequest delete = new DeleteRequest(tsdb.dataTable(), 
                  column.key(), FAMILY, column.qualifier());
              delete_requests.add(tsdb.getClient().delete(delete));
            }
          }
        }
        return scan();
      }
    }

    /** Called when the scanner is done. Delete requests may still be pending */
    final class ScannerDoneCB implements Callback<Deferred<ArrayList<Object>>, 
      List<Deferred<Object>>> {
      @Override
      public Deferred<ArrayList<Object>> call(final List<Deferred<Object>> deletes)
          throws Exception {
        return Deferred.group(delete_requests);
      }
    }
    
    /** Waits on the group of deferreds to complete before returning the count */
    final class GroupCB implements Callback<Deferred<Integer>, ArrayList<Object>> {
      @Override
      public Deferred<Integer> call(final ArrayList<Object> deletes)
          throws Exception {
        return Deferred.fromResult(deletes.size());
      }
    }
    
    Deferred<ArrayList<Object>> scanner_done = new ScannerCB().scan()
        .addCallbackDeferring(new ScannerDoneCB());
    return scanner_done.addCallbackDeferring(new GroupCB());
  }
public static Deferred < Integer > deleteRange ( final TSDB tsdb , final byte [ ] tsuid , final long start_time , final long end_time ) { if ( end_time < 1 ) { throw new IllegalArgumentException ( "The end timestamp has not been set" ) ; } if ( end_time < start_time ) { throw new IllegalArgumentException ( "The end timestamp cannot be less than the start timestamp" ) ; } final List < Deferred < Object > > delete_requests = new ArrayList < Deferred < Object > > ( ) ; int width = tsuid != null ? Const . SALT_WIDTH ( ) + tsuid . length + Const . TIMESTAMP_BYTES : Const . SALT_WIDTH ( ) + TSDB . metrics_width ( ) + Const . TIMESTAMP_BYTES ; final byte [ ] start_row = new byte [ width ] ; final byte [ ] end_row = new byte [ width ] ; final long start = start_time / 1000 ; final long end = end_time / 1000 ; final long normalized_start = ( start - ( start % Const . MAX_TIMESPAN ) ) ; final long normalized_end = ( end - ( end % Const . MAX_TIMESPAN ) + Const . MAX_TIMESPAN ) ; Bytes . setInt ( start_row , ( int ) normalized_start , Const . SALT_WIDTH ( ) + TSDB . metrics_width ( ) ) ; Bytes . setInt ( end_row , ( int ) normalized_end , Const . SALT_WIDTH ( ) + TSDB . metrics_width ( ) ) ; if ( tsuid != null ) { System . arraycopy ( tsuid , 0 , start_row , Const . SALT_WIDTH ( ) , TSDB . metrics_width ( ) ) ; System . arraycopy ( tsuid , 0 , end_row , Const . SALT_WIDTH ( ) , TSDB . metrics_width ( ) ) ; width = Const . SALT_WIDTH ( ) + TSDB . metrics_width ( ) + Const . TIMESTAMP_BYTES ; final int remainder = tsuid . length - TSDB . metrics_width ( ) ; System . arraycopy ( tsuid , TSDB . metrics_width ( ) , start_row , width , remainder ) ; System . arraycopy ( tsuid , TSDB . metrics_width ( ) , end_row , width , remainder ) ; } final class ScannerCB implements Callback < Deferred < List < Deferred < Object > > > , ArrayList < ArrayList < KeyValue > > > { final Scanner scanner ; public ScannerCB ( ) { scanner = tsdb . getClient ( ) . newScanner ( tsdb . dataTable ( ) ) ; scanner . setStartKey ( start_row ) ; scanner . setStopKey ( end_row ) ; scanner . setFamily ( FAMILY ) ; if ( tsuid != null ) { final List < String > tsuids = new ArrayList < String > ( 1 ) ; tsuids . add ( UniqueId . uidToString ( tsuid ) ) ; Internal . createAndSetTSUIDFilter ( scanner , tsuids ) ; } } public Deferred < List < Deferred < Object > > > scan ( ) { return scanner . nextRows ( ) . addCallbackDeferring ( this ) ; } @ Override public Deferred < List < Deferred < Object > > > call ( final ArrayList < ArrayList < KeyValue > > rows ) throws Exception { if ( rows == null || rows . isEmpty ( ) ) { return Deferred . fromResult ( delete_requests ) ; } for ( final ArrayList < KeyValue > row : rows ) { final long base_time = Internal . baseTime ( tsdb , row . get ( 0 ) . key ( ) ) ; for ( KeyValue column : row ) { if ( ( column . qualifier ( ) . length == 3 || column . qualifier ( ) . length == 5 ) && column . qualifier ( ) [ 0 ] == PREFIX ( ) ) { final long timestamp = timeFromQualifier ( column . qualifier ( ) , base_time ) ; if ( timestamp < start_time || timestamp > end_time ) { continue ; } final DeleteRequest delete = new DeleteRequest ( tsdb . dataTable ( ) , column . key ( ) , FAMILY , column . qualifier ( ) ) ; delete_requests . add ( tsdb . getClient ( ) . delete ( delete ) ) ; } } } return scan ( ) ; } } final class ScannerDoneCB implements Callback < Deferred < ArrayList < Object > > , List < Deferred < Object > > > { @ Override public Deferred < ArrayList < Object > > call ( final List < Deferred < Object > > deletes ) throws Exception { return Deferred . group ( delete_requests ) ; } } final class GroupCB implements Callback < Deferred < Integer > , ArrayList < Object > > { @ Override public Deferred < Integer > call ( final ArrayList < Object > deletes ) throws Exception { return Deferred . fromResult ( deletes . size ( ) ) ; } } Deferred < ArrayList < Object > > scanner_done = new ScannerCB ( ) . scan ( ) . addCallbackDeferring ( new ScannerDoneCB ( ) ) ; return scanner_done . addCallbackDeferring ( new GroupCB ( ) ) ; }
Deletes global or TSUID associated annotiations for the given time range.
@param tsdb The TSDB object to use for storage access
@param tsuid An optional TSUID. If set to null, then global annotations for
the given range will be deleted
@param start_time A start timestamp in milliseconds
@param end_time An end timestamp in millseconds
@return The number of annotations deleted
@throws IllegalArgumentException if the timestamps are invalid
@since 2.1