/** * Replication Benchmarker * https://github.com/score-team/replication-benchmarker/ * Copyright (C) 2016 LORIA / Inria / SCORE Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package jbenchmarker.logoot.tree; import crdt.Factory; import crdt.Operation; import java.util.List; import jbenchmarker.core.Document; import jbenchmarker.core.SequenceOperation.OpType; import collect.TreeList; import java.util.LinkedList; import jbenchmarker.logoot.ListIdentifier; import jbenchmarker.logoot.LogootOperation; import jbenchmarker.logoot.LogootStrategy; import jbenchmarker.logoot.TimestampedDocument; /** * A Logoot Tree document. Contains a TreeList of <LogootIndentitifer,character> * @author urso mehdi */ public class LogootTreeDocument<T> implements Document, Factory<LogootTreeDocument<T>>, TimestampedDocument { final private TreeList<LogootTreeElement<T>> document; final protected LogootStrategy strategy; protected int replicaNumber; private int myClock; public LogootTreeDocument(int r, LogootStrategy strategy) { super(); document = new TreeList<LogootTreeElement<T>>(); this.strategy = strategy; this.replicaNumber = r; myClock = 0; LogootTreeElement Begin = new LogootTreeElement(strategy.begin()); LogootTreeElement End = new LogootTreeElement(strategy.end()); document.add(Begin); document.add(End); } @Override public String view() { StringBuilder s = new StringBuilder(); for (int i=1; i< document.size()-1; ++i) { s.append(document.get(i).getElement()); } return s.toString(); } // SUB-OPTIMAL @Override public void apply(Operation op) { LogootOperation<T> lg = (LogootOperation) op; int pos = document.locate(new LogootTreeElement<T>(lg.getPosition(), lg.getContent())); //Insertion et Delete if (lg.getType() == OpType.insert) { document.add(pos, new LogootTreeElement<T>(lg.getPosition(), lg.getContent())); } else if (pos < document.size() && document.get(pos).getDigit().equals(lg.getPosition())) { document.remove(pos); } } List<ListIdentifier> generateIdentifiers(int position, int N) { return strategy.generateLineIdentifiers(this, document.get(position).getDigit(), document.get(position + 1).getDigit(), N); } public void insert(int position, List<LogootOperation<T>> patch) { List<LogootTreeElement<T>> l = new LinkedList<LogootTreeElement<T>>(); for (LogootOperation<T> e : patch) { l.add(new LogootTreeElement<T>(e.getPosition(), e.getContent())); } document.addAll(position + 1, l); // SUB-OPTIMAL } public void remove(int position, int offset) { for (int i = 0; i < offset; ++i) { // SUB-OPTIMAL document.remove(position + 1); } } public LogootTreeElement getId(int pos) { return document.get(pos); } @Override public int viewLength() { return document.size()-2; } @Override public LogootTreeDocument<T> create() { throw new UnsupportedOperationException("Not supported yet."); } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final LogootTreeDocument<T> other = (LogootTreeDocument<T>) obj; if (this.document != other.document && (this.document == null || !this.document.equals(other.document))) { return false; } return true; } protected int getClock() { return this.myClock; } void setClock(int c) { this.myClock = c; } @Override public int getReplicaNumber() { return replicaNumber; } public void setReplicaNumber(int replicaNumber) { this.replicaNumber = replicaNumber; } @Override public int hashCode() { int hash = 7; hash = 97 * hash + (this.document != null ? this.document.hashCode() : 0); return hash; } @Override public int nextClock() { return this.myClock++; } }