// Path: src/main/java/fr/eurecom/hybris/Hybris.java
// public class HybrisWatcher implements CuratorWatcher {
// 
//     private boolean changed = false;
//     public boolean isChanged() { return this.changed; }
// 
//     /**
//      * Process a notification sent by ZooKeeper
//      * @see org.apache.curator.framework.api.CuratorWatcher#process(org.apache.zookeeper.WatchedEvent)
//      */
//     public void process(WatchedEvent event) throws Exception {
//         this.changed = true;
//     }
// }
// 
// Path: src/main/java/fr/eurecom/hybris/mds/Metadata.java
// public static class Timestamp implements KryoSerializable {
// 
//     private int num;
//     private String cid;
// 
//     public Timestamp() { }
//     public Timestamp(int n, String c) {
//         this.num = n;
//         this.cid = c;
//     }
// 
//     public static Timestamp parseString(String tsStr) {
//         String[] tsParts = tsStr.split("_");
//         int n = Integer.parseInt(tsParts[0]);
//         String cid = tsParts[1];
//         return new Timestamp(n, cid);
//     }
// 
//     public int getNum()             { return this.num; }
//     public void setNum(int num)     { this.num = num; }
//     public String getCid()          { return this.cid; }
//     public void setCid(String cid)  { this.cid = cid; }
// 
//     public boolean isGreater(Timestamp ts) {
//         if (ts == null || this.num > ts.num ||
//                 this.num == ts.num && this.cid.compareTo(ts.cid) < 0)
//             return true;
//         return false;
//     }
// 
//     public void inc(String client) {
//         this.num = this.num + 1;
//         this.cid = client;
//     }
// 
//     public String toString() {
//         return this.num + "_" + this.cid;
//     }
// 
//     public int hashCode() {
//         final int prime = 31;
//         int result = 1;
//         result = prime * result + (this.cid == null ? 0 : this.cid.hashCode());
//         result = prime * result + this.num;
//         return result;
//     }
// 
//     public boolean equals(Object obj) {
//         if (this == obj)
//             return true;
//         if (obj == null)
//             return false;
//         if (this.getClass() != obj.getClass())
//             return false;
//         Timestamp other = (Timestamp) obj;
//         if (this.cid == null) {
//             if (other.cid != null)
//                 return false;
//         } else if (!this.cid.equals(other.cid))
//             return false;
//         if (this.num != other.num)
//             return false;
//         return true;
//     }
// 
//     public void write(Kryo kryo, Output output) {
//         output.writeShort(this.num);
//         output.writeAscii(this.cid);
//     }
//     public void read(Kryo kryo, Input input) {
//         this.num = input.readShort();
//         this.cid = input.readString();
//     }
// }
// 
// Path: src/main/java/fr/eurecom/hybris/HybrisException.java
// public class HybrisException extends Exception {
// 
//     private static final long serialVersionUID = 1L;
// 
//     public HybrisException(String message){
//         super(message);
//     }
// 
//     public HybrisException(String message, Throwable t){
//         super(message, t);
//     }
// 
//     public HybrisException(Exception e) {
//         super(e);
//     }
// }


import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.zookeeper.data.Stat;
import fr.eurecom.hybris.Hybris.HybrisWatcher;
import fr.eurecom.hybris.kvs.drivers.Kvs;
import fr.eurecom.hybris.mds.Metadata.Timestamp;
import fr.eurecom.hybris.HybrisException;
/**
 * Copyright (C) 2013 EURECOM (www.eurecom.fr)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package fr.eurecom.hybris.mds;




/**
 * Reliable Metadata Store interface.
 * @author viotti
 */
public interface Rmds {
	
	public static final String ZOOKEEPER_ID = "zk";
	public static final String CONSUL_ID = "consul";
	
	/* Conventional integer marker to tell whether a 
	 * metadata key has to be created (rather than modified).
	 * 
	 * Used as Zookeeper setData API parameter, 
	 * it forces overwriting no matter which 
	 * znode version is currently written. 
	 */
	public static final int NONODE = -1;
	
	
	/**
	 * Timestamped write on metadata storage.
	 * @param key - the key
	 * @param md - the metadata to be written
	 * @param version - the existing metadata key version we expect; -1 when the metadata key does not exist
	 * @return boolean: true if a metadata key has been modified and stale old values need to be garbage-collected
	 *                  false otherwise (i.e. a new metadata key has been created)
	 * @throws HybrisException
	 */
// Path: src/main/java/fr/eurecom/hybris/Hybris.java
// public class HybrisWatcher implements CuratorWatcher {
// 
//     private boolean changed = false;
//     public boolean isChanged() { return this.changed; }
// 
//     /**
//      * Process a notification sent by ZooKeeper
//      * @see org.apache.curator.framework.api.CuratorWatcher#process(org.apache.zookeeper.WatchedEvent)
//      */
//     public void process(WatchedEvent event) throws Exception {
//         this.changed = true;
//     }
// }
// 
// Path: src/main/java/fr/eurecom/hybris/mds/Metadata.java
// public static class Timestamp implements KryoSerializable {
// 
//     private int num;
//     private String cid;
// 
//     public Timestamp() { }
//     public Timestamp(int n, String c) {
//         this.num = n;
//         this.cid = c;
//     }
// 
//     public static Timestamp parseString(String tsStr) {
//         String[] tsParts = tsStr.split("_");
//         int n = Integer.parseInt(tsParts[0]);
//         String cid = tsParts[1];
//         return new Timestamp(n, cid);
//     }
// 
//     public int getNum()             { return this.num; }
//     public void setNum(int num)     { this.num = num; }
//     public String getCid()          { return this.cid; }
//     public void setCid(String cid)  { this.cid = cid; }
// 
//     public boolean isGreater(Timestamp ts) {
//         if (ts == null || this.num > ts.num ||
//                 this.num == ts.num && this.cid.compareTo(ts.cid) < 0)
//             return true;
//         return false;
//     }
// 
//     public void inc(String client) {
//         this.num = this.num + 1;
//         this.cid = client;
//     }
// 
//     public String toString() {
//         return this.num + "_" + this.cid;
//     }
// 
//     public int hashCode() {
//         final int prime = 31;
//         int result = 1;
//         result = prime * result + (this.cid == null ? 0 : this.cid.hashCode());
//         result = prime * result + this.num;
//         return result;
//     }
// 
//     public boolean equals(Object obj) {
//         if (this == obj)
//             return true;
//         if (obj == null)
//             return false;
//         if (this.getClass() != obj.getClass())
//             return false;
//         Timestamp other = (Timestamp) obj;
//         if (this.cid == null) {
//             if (other.cid != null)
//                 return false;
//         } else if (!this.cid.equals(other.cid))
//             return false;
//         if (this.num != other.num)
//             return false;
//         return true;
//     }
// 
//     public void write(Kryo kryo, Output output) {
//         output.writeShort(this.num);
//         output.writeAscii(this.cid);
//     }
//     public void read(Kryo kryo, Input input) {
//         this.num = input.readShort();
//         this.cid = input.readString();
//     }
// }
// 
// Path: src/main/java/fr/eurecom/hybris/HybrisException.java
// public class HybrisException extends Exception {
// 
//     private static final long serialVersionUID = 1L;
// 
//     public HybrisException(String message){
//         super(message);
//     }
// 
//     public HybrisException(String message, Throwable t){
//         super(message, t);
//     }
// 
//     public HybrisException(Exception e) {
//         super(e);
//     }
// }


// Path: src/main/java/fr/eurecom/hybris/mds/Rmds.java
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.zookeeper.data.Stat;
import fr.eurecom.hybris.Hybris.HybrisWatcher;
import fr.eurecom.hybris.kvs.drivers.Kvs;
import fr.eurecom.hybris.mds.Metadata.Timestamp;
import fr.eurecom.hybris.HybrisException;

/**
 * Copyright (C) 2013 EURECOM (www.eurecom.fr)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package fr.eurecom.hybris.mds;




/**
 * Reliable Metadata Store interface.
 * @author viotti
 */
public interface Rmds {
	
	public static final String ZOOKEEPER_ID = "zk";
	public static final String CONSUL_ID = "consul";
	
	/* Conventional integer marker to tell whether a 
	 * metadata key has to be created (rather than modified).
	 * 
	 * Used as Zookeeper setData API parameter, 
	 * it forces overwriting no matter which 
	 * znode version is currently written. 
	 */
	public static final int NONODE = -1;
	
	
	/**
	 * Timestamped write on metadata storage.
	 * @param key - the key
	 * @param md - the metadata to be written
	 * @param version - the existing metadata key version we expect; -1 when the metadata key does not exist
	 * @return boolean: true if a metadata key has been modified and stale old values need to be garbage-collected
	 *                  false otherwise (i.e. a new metadata key has been created)
	 * @throws HybrisException
	 */
	boolean tsWrite(String key, Metadata md, long version) throws HybrisException;