Package org.gridkit.coherence.utils.flash

Source Code of org.gridkit.coherence.utils.flash.FlashUpdater$CleanupEntryProcessor

package org.gridkit.coherence.utils.flash;

import java.util.HashMap;
import java.util.Map;

import com.tangosol.io.Serializer;
import com.tangosol.net.Member;
import com.tangosol.net.NamedCache;
import com.tangosol.net.PartitionedService;
import com.tangosol.util.Binary;
import com.tangosol.util.BinaryEntry;
import com.tangosol.util.ExternalizableHelper;
import com.tangosol.util.UID;
import com.tangosol.util.InvocableMap.Entry;
import com.tangosol.util.filter.AlwaysFilter;
import com.tangosol.util.processor.AbstractProcessor;

/**
* A helper class for flash-update implementation.
*
* @author Alexey Ragozin (alexey.ragozin@gmail.com)
*/
public class FlashUpdater {
 
  private int decorationNo = ExternalizableHelper.DECO_CUSTOM;
  private int putBatchSize = 32;
 
  private NamedCache cache;
 
  private Map<UID, Map<Object, Object>> nodeBuffer = new HashMap<UID, Map<Object, Object>>();
 
  private boolean dirty = false;
 
  public FlashUpdater(NamedCache cache) {
    this.cache = cache;
  }

  /**
   * Size limit for bulk updates.
   * @param size
   */
  public void setBatchSize(int size) {
    this.putBatchSize = size;
  }

  /**
   * Sets decoration ID used to temporary store new value.
   * @param decorationNo
   */
  public void setDecorationNo(int decorationNo) {
    if (dirty) {
      throw new IllegalStateException("Operation in progress");
    }
    this.decorationNo = decorationNo;
  }
 
  /**
   * Replace all old values by new ones, via singe operation.
   */
  public void commit() {
    for(Map.Entry<UID, Map<Object, Object>> entry : nodeBuffer.entrySet()) {
      push(entry.getValue());
    }
    nodeBuffer.clear();
    cache.invokeAll(AlwaysFilter.INSTANCE, new CommitEntryProcessor(decorationNo));
    dirty = false;
  }
 
  private void push(Map<Object, Object> batch) {
    Serializer serializer = cache.getCacheService().getSerializer();
    Map<Binary, Binary> binMap = new HashMap<Binary, Binary>(batch.size());
    for(Map.Entry<Object, Object> entry: batch.entrySet()) {
      Binary key = ExternalizableHelper.toBinary(entry.getKey(), serializer);
      Binary value = ExternalizableHelper.toBinary(entry.getValue(), serializer);
      binMap.put(key, value);
    };
    this.cache.invokeAll(batch.keySet(), new PushEntryProcessor(binMap, decorationNo));
  }

  /**
   * Put new value to cache. To remove existing key, you should put <code>null</code> as new value.
   * None of changes will be visible until you call {@link #commit()}.
   */
  public void put(Object key, Object value) {
    dirty = true;
    Member member = ((PartitionedService)cache.getCacheService()).getKeyOwner(key);
    UID id = member.getUid();
    Map<Object, Object> buf = nodeBuffer.get(id);
    if (buf == null) {
      buf = new HashMap<Object, Object>();
      nodeBuffer.put(id, buf);
    }
    buf.put(key, value);
    if (buf.size() >= putBatchSize) {
      push(buf);
      buf.clear();
    }
  }
 
  /**
   * Put new values to cache. To remove existing key, you should put <code>null</code> as new value.
   * None of changes will be visible until you call {@link #commit()}.
   */
  public <K, V> void putAll(Map<K, V> map) {
    for(Map.Entry<K, V> entry: map.entrySet()) {
      put(entry.getKey(), entry.getValue());
    }
  }
 
  /**
   * Remove uncommitted values from cache. Useful if there is a chance what previous flash-update wasn't finished.  
   */
  public void cleanup() {
    cache.invokeAll(AlwaysFilter.INSTANCE, new CleanupEntryProcessor(decorationNo));
    dirty = false;
  }
 
  public static class PushEntryProcessor extends AbstractProcessor {
   
    private static final long serialVersionUID = 20101026L;
   
    private int decorationNo;
    private Map<Binary, Binary> values;
   
    public PushEntryProcessor(Map<Binary, Binary> values, int decorationNo) {
      this.values = values;
      this.decorationNo = decorationNo;
    }

    @Override
    public Object process(Entry e) {
      BinaryEntry be = (BinaryEntry)e;
      Binary binaryKey = be.getBinaryKey();
      Binary newValue = values.get(binaryKey);
      if (newValue != null) {
        Binary value = be.getBinaryValue();
        value = ExternalizableHelper.decorate(value, decorationNo, newValue);
        be.updateBinaryValue(value);
      }
      return null;
    }
  }

  public static class CommitEntryProcessor extends AbstractProcessor {

    private static final long serialVersionUID = 20101026L;
   
    private int decorationNo;
   
    public CommitEntryProcessor(int decorationNo) {
      this.decorationNo = decorationNo;
    }
   
    @Override
    public Object process(Entry e) {
      BinaryEntry be = (BinaryEntry)e;
      Binary oldValue = be.getBinaryValue();
      Binary newValue = ExternalizableHelper.getDecoration(oldValue, decorationNo);
      if (newValue != null) {
        if (newValue.length() == 0) {
          be.remove(false);
        }
        else {
          be.updateBinaryValue(newValue);
        }
      }
      return null;
    }
  }
 
  public static class CleanupEntryProcessor extends AbstractProcessor {

    private static final long serialVersionUID = 20101026L;
   
    private int decorationNo;
   
    public CleanupEntryProcessor(int decorationNo) {
      this.decorationNo = decorationNo;
    }
   
    @Override
    public Object process(Entry e) {
      BinaryEntry be = (BinaryEntry)e;
      Binary oldValue = be.getBinaryValue();
      Binary newValue = ExternalizableHelper.getDecoration(oldValue, decorationNo);
      if (newValue != null) {
        Binary nv = ExternalizableHelper.undecorate(oldValue, decorationNo);
        be.updateBinaryValue(nv);
      }
      return null;
    }
  } 
}
TOP

Related Classes of org.gridkit.coherence.utils.flash.FlashUpdater$CleanupEntryProcessor

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.