Package src

Source Code of src.Store

package src;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Stack;
import java.util.Vector;

import zk.ZkCtl;

import lib.Extends;
import lib.FS;

public class Store {

  private HashMap<String, String> cacheMap = new HashMap<String, String>();
  private HashMap<String, HashMap<String, Vector<Handler>>> eventMap = new HashMap<String, HashMap<String, Vector<Handler>>>();

  private ZkCtl zkCtl;
  private boolean zkOk;

  private String hosts;
  private String root;
  private String user;
  private String pass;
  private String cache;
 
  private Stack<String> stack;
 
  public Store(String hosts, String root, String user, String pass,
      String cache){   
    this.zkOk = false;
    this.hosts = hosts;
    this.root = root;
    this.user = user;
    this.pass = pass;
    this.cache = cache;
    this.stack = new Stack<String>();
  }
 
  public void init(){
    this.zkCtl = new ZkCtl(this.hosts, this.root, this.user, this.pass, this);
  }
 
  public void expire(){
    this.init();
  }
 
  public void watch(String prefix){
    if (!this.zkOk) {
      this.stack.push(prefix);
    } else {
      this.zkCtl.watch(prefix);
    }
  }
 
  public void inform(int type){
    switch(type){
    case Constants.ZK_ERROR:
      this.emitEvent(Constants.GLOBAL_PREFIX, Constants.ZK_PATH_ERROR_EVENT, "");
      break;
    case Constants.ZK_NOT_CONNECT:
      this.emitEvent(Constants.GLOBAL_PREFIX, Constants.DISCONNECT_EVENT, "");
      break;
    case Constants.ZK_OK:
      this.zkOk = true;
      while(!this.stack.empty()){
        this.zkCtl.watch(this.stack.pop());
      }
      this.emitEvent(Constants.GLOBAL_PREFIX, Constants.CONNECT_EVENT, "");
      break;
    case Constants.ZK_EXPIRED:
      this.emitEvent(Constants.GLOBAL_PREFIX, Constants.EXPIRED_EVENT, "");
      break;
    default:
      break;
    }
  }
 
  public void setEventHandle(String prefix, String event, Handler handler){
    HashMap<String, Vector<Handler>> map = eventMap.get(prefix);
    if (null == map) {
      map = new HashMap<String, Vector<Handler>>();
      eventMap.put(prefix, map);
    }
    Vector<Handler> handlers = map.get(event);
    if (null == handlers) {
      handlers = new Vector<Handler>();
      eventMap.get(prefix).put(event, handlers);
    }
    handlers.add(handler);
  }
 
  public void emitEvent(String prefix, String event, Object content){
    HashMap<String, Vector<Handler>> map = eventMap.get(prefix);
    if (null == map) {
      return;
    }
   
    Vector<Handler> handlers = map.get(event);
    if (null != handlers) {
      for(int i = 0; i < handlers.size(); i++){
        if(handlers.elementAt(i).getOK()){
          handlers.elementAt(i).callback(content);
        }
      }
    }
  }
 
  public String get(String key){
    if (cacheMap.isEmpty()) {
      String path = this.cache +  "/" + Extends.getPid();
      if (FS.existDir(path)) {
        this.load(path, "");
      } else {
        this.totalLoad(this.cache);
        this.load(path, "");
     
    }
    return cacheMap.get(key);
  }
 
  public void set(String k, String v){
    cacheMap.put(k, v);
  }
 
  public void check(String key, String value){
    if (cacheMap.get(key) ==  null || !cacheMap.get(key).equals(value)){
      if(this.dump(key)){
        cacheMap.clear();
        this.emitEvent(key, Constants.DATA_CHANGE_EVENT, value);
      } else {
        this.emitEvent(key, Constants.DUMP_FAIL_EVENT, key);
      }
    }
  }
 
  public void totalLoad(String path){
    File file = new File(path);
    File[] files = file.listFiles();
   
    File tmpFile = new File(path + "/" + Extends.getPid() + "_tmp");
    FS.mkdir(tmpFile.getAbsolutePath());
   
    HashMap<String, Integer> map = new HashMap<String, Integer>();
   
    for(int i = 0; i < files.length; i++){
      if(!files[i].getName().matches("\\d+")){
        continue;
      }
     
      try {
        this.innerLoad(files[i].getName(), tmpFile.getAbsolutePath(), map);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
   
    File dest = new File(this.cache + "/" + String.valueOf(Extends.getPid()));
    if (dest.exists()) {
      FS.rmdir(tmpFile.getAbsolutePath());
    } else {
      tmpFile.renameTo(dest);
   
  }
 
  public void innerLoad(String src, String dest, HashMap<String, Integer> map) throws IOException{
    File[] files = new File(this.cache + "/" + src).listFiles();
    for(int i = 0; i < files.length; i++){
      String name = files[i].getName();
      String path = files[i].getAbsolutePath();
     
      if (files[i].isFile()) {
        File file = new File(path.substring(0, path.length() - Constants.FILE_SUFFIX.length()));
        if((file.exists() && file.isDirectory()) || name.matches(".*\\" + Constants.MD5_SUFFIX + "$")){
          continue;
         
        } else {
          int version = this.getVersion(FS.read(path));       
          String key = this.getKey(src, name);
          if (map.get(key) == null || version > map.get(key)){         
            FS.cp(path, dest + "/" + name);
            map.put(key, version);
          }
        }
      }
     
      if (files[i].isDirectory()) {
        File file = new File(path + ".data");
        if (file.exists()) {
          int version = this.getVersion(FS.read(file.getAbsolutePath()));
          String key = src.substring(src.indexOf("/") + 1) + "/" + name;
          if (map.get(key) == null || version > map.get(key)){
            FS.cp(file.getAbsolutePath(), dest + "/" + file.getName());
            FS.cp(path, dest + "/" + name);
            this.calMd5(files[i].getAbsolutePath());
           
            map.put(key, version);
          }
         
        } else {
          FS.mkdir(dest + "/" + name);
          this.innerLoad(src + "/" + name, dest + "/" + name, map);
        }
      }
    }
  }
 
  private String getKey(String prefix, String name){
    prefix = prefix.substring(prefix.indexOf("/") + 1);
    name = name.substring(0, name.length() - ".data".length());
    return prefix + "/" + name;
  }
 
  private int getVersion(String content){
    content = content.substring(0, content.indexOf("\r\n"));
    return Integer.parseInt(content.substring(content.indexOf(":") + 1));
  }
 
  public void load(String path, String relative){
    File file = new File(path);
    if (file.isDirectory()) {
      File[] files = file.listFiles();
      for (int i = 0; i < files.length; i++) {
        String name = files[i].getName();
        this.load(path + "/" + name, relative + "/" + name);
      }
    } else if (file.isFile()) {
      String key = relative.substring(0, relative.length()- ".data".length());
      String val = FS.read(file.getAbsolutePath());
      val = val.substring(val.indexOf("\r\n") + 2);
      this.set(key, val);
    }
  }
 
  public boolean dump(String key){
    File f = new File(this.cache + "/" + Extends.getPid() + "/" + key)

    String md5File = f.getAbsolutePath() + Constants.MD5_SUFFIX;
    if (new File(md5File).exists() && !FS.read(md5File).equals(calMd5(f.getAbsolutePath()))) {
      return false;
    }
   
    String prefix = key.substring(0,key.lastIndexOf("/"));
    HashMap<String, String> tree = this.zkCtl.getTree(key);
   
    String tmpPath = f.getParent() + "_tmp";
   
    Iterator<String> i = tree.keySet().iterator();
    while (i.hasNext()) {
      String k = i.next().toString();
      String v = tree.get(k);
      FS.dump(this.addPath(tmpPath, k.substring(prefix.length())) + Constants.FILE_SUFFIX, v);
    }
   
    File file2 = new File(f.getParent());
    if (file2.exists()) {
      File[] files = file2.listFiles();
      for(int j = 0; j < files.length; j++){
        if (!files[j].getName().equals(f.getName()) && !files[j].getName().equals(f.getName() + Constants.FILE_SUFFIX)) {
          try {
            FS.cp(files[j].getAbsolutePath(), tmpPath + "/" + files[j].getName());
          } catch (IOException e) {
            this.emitEvent(Constants.GLOBAL_PREFIX, Constants.DUMP_ERROR_EVENT, key);
            e.printStackTrace();
          }
        }
      }
    }

    FS.dump(tmpPath + "/" + f.getName() + Constants.MD5_SUFFIX, this.calMd5(tmpPath + "/" + f.getName()));
   
    FS.rmdir(f.getParent());
    File oldFile = new File(tmpPath);
    File newFile = new File(f.getParent());
    oldFile.renameTo(newFile);
    return true;
  }

  public String calMd5(String path) {
    File f = new File(path);
    File[] files = f.listFiles();
    String md5s = "";
    for(int i = 0; i < files.length; i++){
      if (files[i].getName().matches(".md5$")) {
        continue;
      }
      if (files[i].isDirectory()) {
        md5s += this.calMd5(files[i].getAbsolutePath());
      } else {
        md5s += Extends.getMD5Str(FS.read(files[i].getAbsolutePath()));
      }
    }
    return Extends.getMD5Str(md5s);
  }
 
  private String addPath(String prefix, String path){
    if (!prefix.substring(prefix.length()-1).equals("/") && !path.substring(0).equals("/")) {
      return FS.normalize(prefix + "/" + path);
    }
    return FS.normalize(prefix + path);
  }
   
}
TOP

Related Classes of src.Store

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.