/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.activemq.store.kahadb.disk.util; import java.util.ArrayList; /** * Provides a list of LinkedNode objects. * * @author chirino */ public class LinkedNodeList<T extends LinkedNode<T>> { T head; int size; public LinkedNodeList() { } public boolean isEmpty() { return head == null; } public void addLast(T node) { node.linkToTail(this); } public void addFirst(T node) { node.linkToHead(this); } public T getHead() { return head; } public T getTail() { return head != null ? head.prev : null; } public void clear() { while (head != null) { head.unlink(); } } public void addLast(LinkedNodeList<T> list) { if (list.isEmpty()) { return; } if (head == null) { head = list.head; reparent(list); } else { getTail().linkAfter(list); } } public void addFirst(LinkedNodeList<T> list) { if (list.isEmpty()) { return; } if (head == null) { reparent(list); head = list.head; list.head = null; } else { getHead().linkBefore(list); } } public T reparent(LinkedNodeList<T> list) { size += list.size; T n = list.head; do { n.list = this; n = n.next; } while (n != list.head); list.head = null; list.size = 0; return n; } /** * Move the head to the tail and returns the new head node. * * @return */ public T rotate() { if( head ==null ) return null; return head = head.getNextCircular(); } /** * Move the head to the tail and returns the new head node. * * @return */ public void rotateTo(T head) { assert head!=null: "Cannot rotate to a null head"; assert head.list == this : "Cannot rotate to a node not linked to this list"; this.head = head; } public int size() { return size; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("["); boolean first=true; T cur = getHead(); while( cur!=null ) { if( !first ) { sb.append(", "); } sb.append(cur); first=false; cur = cur.getNext(); } sb.append("]"); return sb.toString(); } /** * Copies the nodes of the LinkedNodeList to an ArrayList. * @return */ public ArrayList<T> toArrayList() { ArrayList<T> rc = new ArrayList<T>(size); T cur = head; while( cur!=null ) { rc.add(cur); cur = cur.getNext(); } return rc; } }