/* * Copyright Terracotta, Inc. * * 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 org.ehcache.clustered.server.store.impl; import org.ehcache.clustered.common.internal.store.Chain; import org.ehcache.clustered.common.internal.store.Element; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; import java.util.List; /** * Implements {@link Chain} */ public class HeapChainImpl implements Chain { private Node first; private Node last; public HeapChainImpl(Element... elements) { createChain(elements); } @Override public Iterator<Element> reverseIterator() { return new ReverseChainIterator(); } @Override public boolean isEmpty() { return first == null; } @Override public Iterator<Element> iterator() { return new ChainIterator(); } /** * * @param element to be appended to the chain */ Chain append(Element element) { List<Element> presentElements = new LinkedList<Element>(); for (Element l : this) { presentElements.add(l); } presentElements.add(element); Element[] elementArr = new Element[presentElements.size()]; return new HeapChainImpl(presentElements.toArray(elementArr)); } private void createChain(Element... elements) { if (elements != null && elements.length != 0) { List<Element> reordered = Arrays.asList(elements); Collections.sort(reordered, new Comparator<Element>() { @Override public int compare(Element o1, Element o2) { HeapElementImpl oh1 = (HeapElementImpl)o1; HeapElementImpl oh2 = (HeapElementImpl)o2; if (oh1.getSequenceNumber() > oh2.getSequenceNumber()) { return 1; } else if (oh1.getSequenceNumber() < oh2.getSequenceNumber()) { return -1; } else { return 0; } } }); List<Element> sortedList = new ArrayList<Element>(reordered); if (!sortedList.isEmpty()) { createFirst(sortedList.remove(0)); } for (Element element : sortedList) { add(element); } } } private void createFirst(Element element) { Node newNode = new Node(element); this.first = newNode; this.last = newNode; } private void add(Element element) { Node newNode = new Node(element); this.last.nextLink = newNode; newNode.prevLink = this.last; this.last = newNode; } private class ChainIterator implements Iterator<Element> { private Node current; ChainIterator() { this.current = first; } @Override public boolean hasNext() { return current != null; } @Override public Element next() { Node temp = this.current; this.current = this.current.nextLink; return temp.element; } @Override public void remove() { throw new UnsupportedOperationException("Remove operation is not supported"); } } private class ReverseChainIterator implements Iterator<Element> { private Node current; ReverseChainIterator() { this.current = last; } @Override public boolean hasNext() { return current != null; } @Override public Element next() { Node temp = this.current; this.current = this.current.prevLink; return temp.element; } @Override public void remove() { throw new UnsupportedOperationException("Remove operation is not supported"); } } private static class Node { Element element; Node nextLink; Node prevLink; Node (Element element) { this.element = element; } } }