Package com.pardot.rhombus

Source Code of com.pardot.rhombus.UpdateProcessor

package com.pardot.rhombus;

import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.pardot.rhombus.cobject.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
* Pardot, An ExactTarget Company
* User: robrighter
* Date: 7/5/13
*/
public class UpdateProcessor {

  private static Logger logger = LoggerFactory.getLogger(UpdateProcessor.class);
  private ObjectMapper objectMapper;

  public UpdateProcessor(ObjectMapper om){
    this.objectMapper = om;
  }

  public ObjectMapper getObjectMapper() {
    return objectMapper;
  }

  public void setObjectMapper(ObjectMapper objectMapper) {
    this.objectMapper = objectMapper;
  }

  public void process() throws IOException {
    process(0l);
  }

  public void process(long rowLimit) throws IOException {
    IndexUpdateRow row = objectMapper.getNextUpdateIndexRow(null);
    long examinedRows = 0l;
    while(row != null){
      processRow(row);
      row = objectMapper.getNextUpdateIndexRow(row.getRowKey());
      examinedRows++;
      if(rowLimit > 0 && examinedRows >= rowLimit) {
        break;
      }
    }
  }

  public List<Map<String,Object>> getUpdatesThatHappenedWithinTimeframe(Long timeInNanos) throws IOException {
    return getUpdatesThatHappenedWithinTimeframe(timeInNanos, 0l);
  }

  public List<Map<String,Object>> getUpdatesThatHappenedWithinTimeframe(Long timeInNanos, long rowLimit) throws IOException {
    List<Map<String,Object>> ret = Lists.newArrayList();
    IndexUpdateRow row = objectMapper.getNextUpdateIndexRow(null);
    long examinedRows = 0l;
    while(row != null){
      List<Map<String,Object>> toadd = findUpdatesWithinTimeframe(row,timeInNanos);
      if(toadd.size() > 0){
        ret.addAll(toadd);
      }
      examinedRows++;
      if(rowLimit > 0 && examinedRows >= rowLimit) {
        break;
      }
      row = objectMapper.getNextUpdateIndexRow(row.getRowKey());
    }
    return ret;
  }

  protected List<Map<String,Object>> findUpdatesWithinTimeframe(IndexUpdateRow row, Long timeInNannos){
    List<Map<String,Object>> ret = Lists.newArrayList();
    UUID newer = null;
    int i = 0;
    for(UUID current : row.getIds()){
      if(newer != null){
        ///do stuff
        Long difference = newer.timestamp() - current.timestamp();
        if(difference < timeInNannos){
          Map<String,Object> toadd = Maps.newHashMap();
          toadd.put("rowkey", row.getRowKey());
          toadd.put("new-item", row.getIndexValues().get(i));
          toadd.put("old-item", row.getIndexValues().get(i-1));
          toadd.put("difference", difference);
          ret.add(toadd);
        }
      }
      newer = current;
      i++;
    }
    return ret;
  }

  protected void processRow(IndexUpdateRow row){
    if(row.getIndexValues().size() == 0){
      return;
    }
    if(row.getIndexValues().size() == 1){
      //if this is older than the consistency horizon, just delete it
      Long consistencyHorizon = UUIDs.unixTimestamp(objectMapper.getTimeUUIDAtEndOfConsistencyHorizion());
      if(row.getTimeStampOfMostCurrentUpdate() > consistencyHorizon){
        objectMapper.deleteObsoleteUpdateIndexColumn(row.getRowKey(),row.getIds().get(0));
      }
      return;
    }

    //make a list of all the updated indexes and subtract all the indexes that are current
    Map<String,Object> mostRecentUpdate = row.getIndexValues().get(0);
    row.getIndexValues().remove(0);
    row.getIds().remove(0);
    List<CIndex> listOfIndexesToDelete = Lists.newArrayList();
    List<Map<String,Object>> listOfValuesToDelete = Lists.newArrayList();
    for(Map<String,Object> update: row.getIndexValues()){
      if(!areIndexValuesEqual(mostRecentUpdate, update)){
        listOfValuesToDelete.add(update);
        listOfIndexesToDelete.addAll(
          getListOfEffectedIndexes(objectMapper.getKeyspaceDefinition().getDefinitions().get(row.getObjectName()),
            mostRecentUpdate,
            update
          )
        );
      }
    }
    //delete the list of indexes with a timestamp of the current update
    for(CIndex index : listOfIndexesToDelete){
      for(Map<String,Object> values: listOfValuesToDelete){
        //if any of the values are null we can skip it because its not actually a written index
        if(!areAnyValuesNull(values)){
          objectMapper.deleteObsoleteIndex(row,index, values);
        }
      }
    }

    //now delete the processed update columns in this row
    for(UUID todelete: row.getIds()){
      objectMapper.deleteObsoleteUpdateIndexColumn(row.getRowKey(),todelete);
    }

  }

  protected boolean areAnyValuesNull(Map<String,Object> indexValues){
    for(String key : indexValues.keySet()){
      if(indexValues.get(key) == null){
        return true;
      }
    }
    return false;
  }

  protected List<CIndex> getListOfEffectedIndexes(CDefinition def, Map<String,Object> a, Map<String,Object> b){
    List<CIndex> ret = Lists.newArrayList();
    for(CIndex i: def.getIndexesAsList()){
      Map<String,Object> aValues = i.getIndexKeyAndValues(a);
      Map<String,Object> bValues = i.getIndexKeyAndValues(b);
      if(!areIndexValuesEqual(aValues,bValues)){
        ret.add(i);
      }
    }
    return ret;
  }

  protected boolean areIndexValuesEqual(Map<String,Object> a, Map<String,Object> b){
    if(a.keySet().size() != b.keySet().size()){
      return false;
    }
    for(String key: a.keySet()){
      if(a.get(key) != b.get(key)){
        return false;
      }
    }
    return true;
  }

  public void displayListResults(List<Map<String,Object>> results){
    System.out.println(" Difference | Type | Instance | New Values | Old Values");
    System.out.println("--------------------------------------------------------");
    for(Map<String,Object> item : results){
      String difference = item.get("difference").toString();
      String objName = ((IndexUpdateRowKey)item.get("rowkey")).getObjectName();
      String instanceId = ((IndexUpdateRowKey)item.get("rowkey")).getInstanceId().toString();
      String newValue = item.get("new-item").toString();
      String oldValue = item.get("old-item").toString();

      System.out.println(String.format("%s  %s  %s  %s  %s",
          difference,
          objName,
          instanceId,
          newValue,
          oldValue));
    }
  }
}
TOP

Related Classes of com.pardot.rhombus.UpdateProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.