Make IndexLinkedList and interface with two implementations - one for in-memory

iteration of the indexes, one for disk based iteration

git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@423919 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Davies 2006-07-20 12:50:15 +00:00
parent ea35563b49
commit 6f4c286d66
15 changed files with 1114 additions and 216 deletions

View File

@ -28,24 +28,60 @@ public abstract class BaseContainerImpl{
private static final Log log=LogFactory.getLog(BaseContainerImpl.class);
protected IndexItem root;
protected IndexLinkedList list;
protected IndexManager rootIndexManager; // IndexManager that contains the root
protected IndexManager indexManager;
protected DataManager dataManager;
protected ContainerId containerId;
protected boolean loaded=false;
protected boolean closed=false;
protected boolean initialized = false;
protected final Object mutex=new Object();
protected BaseContainerImpl(ContainerId id,IndexItem root,IndexManager indexManager,DataManager dataManager){
protected BaseContainerImpl(ContainerId id,IndexItem root,IndexManager rootIndexManager,IndexManager indexManager,DataManager dataManager){
this.containerId=id;
this.root=root;
this.rootIndexManager = rootIndexManager;
this.indexManager=indexManager;
this.dataManager=dataManager;
this.list=new IndexLinkedList(root);
}
ContainerId getContainerId(){
return containerId;
}
public void init(){
if (!initialized){
synchronized(mutex){
if (!initialized){
initialized= true;
if (this.list == null){
this.list=new DiskIndexLinkedList(indexManager,root);
}
}
}
}
}
protected void clear(){
if (list != null){
list.clear();
}
}
/**
* @return the list
*/
public IndexLinkedList getList(){
return list;
}
/**
* @param list the list to set
*/
public void setList(IndexLinkedList list){
this.list=list;
}
public abstract void unload();
@ -53,7 +89,6 @@ public abstract class BaseContainerImpl{
public abstract int size();
public abstract void clear();
protected abstract Object getValue(IndexItem currentItem);
@ -114,7 +149,7 @@ public abstract class BaseContainerImpl{
nextItem=item.getNextItem();
}
root.setNextItem(Item.POSITION_NOT_SET);
indexManager.updateIndex(root);
updateIndex(root);
for(int i=0;i<list.size();i++){
IndexItem item=(IndexItem) list.get(i);
dataManager.removeInterestInFile(item.getKeyFile());
@ -139,11 +174,11 @@ public abstract class BaseContainerImpl{
if(next!=null){
prev.setNextItem(next.getOffset());
next.setPreviousItem(prev.getOffset());
indexManager.updateIndex(next);
updateIndex(next);
}else{
prev.setNextItem(Item.POSITION_NOT_SET);
}
indexManager.updateIndex(prev);
updateIndex(prev);
indexManager.freeIndex(key);
}catch(IOException e){
log.error("Failed to delete "+key,e);
@ -156,4 +191,18 @@ public abstract class BaseContainerImpl{
throw new RuntimeStoreException("The store is closed");
}
}
protected void updateIndex(IndexItem item) throws IOException{
IndexManager im = isRoot(item) ? rootIndexManager : indexManager;
im.updateIndex(item);
}
protected final boolean isRoot(IndexItem item){
// return item != null && root != null && (root == item || root.getOffset() == item.getOffset());
return item != null && root != null && root == item;
}
}

View File

@ -77,4 +77,8 @@ public class ContainerId implements Externalizable{
dataContainerName=in.readUTF();
key=in.readObject();
}
public String toString(){
return "CID{"+dataContainerName + ":" + key + "}";
}
}

View File

@ -36,7 +36,7 @@ public class ContainerListIterator extends ContainerValueCollectionIterator impl
* @see java.util.ListIterator#hasPrevious()
*/
public boolean hasPrevious(){
return list.getPrevEntry(currentItem) != null;
return list.getPrevEntry(nextItem) != null;
}
/*
@ -45,8 +45,8 @@ public class ContainerListIterator extends ContainerValueCollectionIterator impl
* @see java.util.ListIterator#previous()
*/
public Object previous(){
currentItem = list.getPrevEntry(currentItem);
return currentItem != null ? container.getValue(currentItem) : null;
nextItem = list.getPrevEntry(nextItem);
return nextItem != null ? container.getValue(nextItem) : null;
}
/*
@ -56,8 +56,8 @@ public class ContainerListIterator extends ContainerValueCollectionIterator impl
*/
public int nextIndex(){
int result = -1;
if (currentItem != null){
IndexItem next = list.getNextEntry(currentItem);
if (nextItem != null){
IndexItem next = list.getNextEntry(nextItem);
if (next != null){
result = container.getInternalList().indexOf(next);
}
@ -74,8 +74,8 @@ public class ContainerListIterator extends ContainerValueCollectionIterator impl
*/
public int previousIndex(){
int result = -1;
if (currentItem != null){
IndexItem prev = list.getPrevEntry(currentItem);
if (nextItem != null){
IndexItem prev = list.getPrevEntry(nextItem);
if (prev != null){
result = container.getInternalList().indexOf(prev);
}
@ -93,7 +93,7 @@ public class ContainerListIterator extends ContainerValueCollectionIterator impl
*/
public void set(Object o){
IndexItem item=((ListContainerImpl) container).internalSet(previousIndex()+1,o);
currentItem=item;
nextItem=item;
}
/*
@ -103,6 +103,6 @@ public class ContainerListIterator extends ContainerValueCollectionIterator impl
*/
public void add(Object o){
IndexItem item=((ListContainerImpl) container).internalSet(previousIndex()+1,o);
currentItem=item;
nextItem=item;
}
}

View File

@ -1,51 +1,51 @@
/**
*
*
* Copyright 2005-2006 The Apache Software Foundation
*
* 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.
*
* 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.apache.activemq.kaha.impl;
import java.util.Iterator;
/**
* Values collection iterator for the MapContainer
*
* @version $Revision: 1.2 $
*/
* Values collection iterator for the MapContainer
*
* @version $Revision: 1.2 $
*/
public class ContainerValueCollectionIterator implements Iterator{
protected BaseContainerImpl container;
protected IndexLinkedList list;
protected IndexItem nextItem;
protected IndexItem currentItem;
ContainerValueCollectionIterator(BaseContainerImpl container,IndexLinkedList list,IndexItem start){
this.container = container;
this.list = list;
this.currentItem = start;
this.container=container;
this.list=list;
this.currentItem=start;
this.nextItem=list.getNextEntry(start);
}
public boolean hasNext(){
return currentItem != null && list.getNextEntry(currentItem) != null;
return nextItem!=null;
}
public Object next(){
currentItem = list.getNextEntry(currentItem);
return container.getValue(currentItem);
currentItem=nextItem;
Object result=container.getValue(nextItem);
nextItem=list.getNextEntry(nextItem);
return result;
}
public void remove(){
if (currentItem != null){
container.remove(currentItem);
}
if(currentItem!=null){
container.remove(currentItem);
}
}
}

View File

@ -0,0 +1,309 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* 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.apache.activemq.kaha.impl;
import java.io.IOException;
/**
* A linked list used by IndexItems
*
* @version $Revision$
*/
class DiskIndexLinkedList implements IndexLinkedList{
private IndexManager indexManager;
private transient IndexItem root;
private transient IndexItem last;
private transient int size=0;
/**
* Constructs an empty list.
*/
DiskIndexLinkedList(IndexManager im,IndexItem header){
this.indexManager=im;
this.root=header;
}
public IndexItem getRoot(){
return root;
}
void setRoot(IndexItem e){
this.root=e;
System.err.println("SET ROOT = "+e);
}
/**
* Returns the first element in this list.
*
* @return the first element in this list.
*/
public IndexItem getFirst(){
if(size==0)
return null;
return getNextEntry(root);
}
/**
* Returns the last element in this list.
*
* @return the last element in this list.
*/
public IndexItem getLast(){
if(size==0)
return null;
return last;
}
/**
* Removes and returns the first element from this list.
*
* @return the first element from this list.
*/
public IndexItem removeFirst(){
if(size==0){
return null;
}
IndexItem result=getNextEntry(root);
remove(result);
return result;
}
/**
* Removes and returns the last element from this list.
*
* @return the last element from this list.
*/
public Object removeLast(){
if(size==0)
return null;
IndexItem result=last;
remove(last);
return result;
}
/**
* Inserts the given element at the beginning of this list.
*
* @param o the element to be inserted at the beginning of this list.
*/
public void addFirst(IndexItem item){
if(size==0){
last=item;
}
size++;
}
/**
* Appends the given element to the end of this list. (Identical in function to the <tt>add</tt> method; included
* only for consistency.)
*
* @param o the element to be inserted at the end of this list.
*/
public void addLast(IndexItem item){
size++;
last=item;
}
/**
* Returns the number of elements in this list.
*
* @return the number of elements in this list.
*/
public int size(){
return size;
}
/**
* is the list empty?
*
* @return true if there are no elements in the list
*/
public boolean isEmpty(){
return size==0;
}
/**
* Appends the specified element to the end of this list.
*
* @param o element to be appended to this list.
* @return <tt>true</tt> (as per the general contract of <tt>Collection.add</tt>).
*/
public boolean add(IndexItem item){
size++;
return true;
}
/**
* Removes all of the elements from this list.
*/
public void clear(){
last=null;
size=0;
}
// Positional Access Operations
/**
* Returns the element at the specified position in this list.
*
* @param index index of element to return.
* @return the element at the specified position in this list.
*
* @throws IndexOutOfBoundsException if the specified index is is out of range (<tt>index &lt; 0 || index &gt;= size()</tt>).
*/
public IndexItem get(int index){
return entry(index);
}
/**
* Inserts the specified element at the specified position in this list. Shifts the element currently at that
* position (if any) and any subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted.
* @param element element to be inserted.
*
* @throws IndexOutOfBoundsException if the specified index is out of range (<tt>index &lt; 0 || index &gt; size()</tt>).
*/
public void add(int index,IndexItem element){
if(index==size-1){
last=element;
}
size++;
}
/**
* Removes the element at the specified position in this list. Shifts any subsequent elements to the left (subtracts
* one from their indices). Returns the element that was removed from the list.
*
* @param index the index of the element to removed.
* @return the element previously at the specified position.
*
* @throws IndexOutOfBoundsException if the specified index is out of range (<tt>index &lt; 0 || index &gt;= size()</tt>).
*/
public Object remove(int index){
IndexItem e=entry(index);
remove(e);
return e;
}
/**
* Return the indexed entry.
*/
private IndexItem entry(int index){
if(index<0||index>=size)
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
IndexItem e=root;
for(int i=0;i<=index;i++)
e=getNextEntry(e);
if(e != null &&last!=null && last.equals(e)){
last = e;
}
return e;
}
// Search Operations
/**
* Returns the index in this list of the first occurrence of the specified element, or -1 if the List does not
* contain this element. More formally, returns the lowest index i such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, or -1 if there is no such index.
*
* @param o element to search for.
* @return the index in this list of the first occurrence of the specified element, or -1 if the list does not
* contain this element.
*/
public int indexOf(IndexItem o){
int index=0;
if(size>0){
for(IndexItem e=getNextEntry(root);e!=null;e=getNextEntry(e)){
if(o.equals(e)){
return index;
}
index++;
}
}
return -1;
}
/**
* Retrieve the next entry after this entry
*
* @param entry
* @return next entry
*/
public IndexItem getNextEntry(IndexItem current){
IndexItem result=null;
if(current!=null&&current.getNextItem()>=0){
try{
result=indexManager.getIndex(current.getNextItem());
}catch(IOException e){
throw new RuntimeException("Failed to get next index from " + indexManager + " for " + current,e);
}
}
// essential last get's updated consistently
if(result != null &&last!=null && last.equals(result)){
result = last;
}
return result;
}
/**
* Retrive the prev entry after this entry
*
* @param entry
* @return prev entry
*/
public IndexItem getPrevEntry(IndexItem current){
IndexItem result=null;
if(current!=null&&current.getPreviousItem()>=0){
try{
result=indexManager.getIndex(current.getPreviousItem());
}catch(IOException e){
throw new RuntimeException("Failed to index",e);
}
}
//essential root get's updated consistently
if(result != null &&root!=null && root.equals(result)){
return root;
}
return result;
}
public IndexItem getEntry(IndexItem current){
IndexItem result=null;
if(current!=null&&current.getOffset()>=0){
try{
result=indexManager.getIndex(current.getOffset());
}catch(IOException e){
throw new RuntimeException("Failed to index",e);
}
}
//essential root get's updated consistently
if(result != null &&root!=null && root.equals(result)){
return root;
}
return result;
}
public void remove(IndexItem e){
if(e==root||e.equals(root))
return;
if(e==last||e.equals(last)){
if(size>1){
last=getPrevEntry(last);
}else{
last=null;
}
}
size--;
}
}

View File

@ -21,14 +21,14 @@ import java.io.IOException;
*
* @version $Revision: 1.2 $
*/
final class IndexItem implements Item{
class IndexItem implements Item{
static final int INDEX_SIZE=51;
//used by linked list
IndexItem next;
IndexItem prev;
private long offset=POSITION_NOT_SET;
protected long offset=POSITION_NOT_SET;
private long previousItem=POSITION_NOT_SET;
private long nextItem=POSITION_NOT_SET;
private boolean active=true;
@ -262,4 +262,17 @@ final class IndexItem implements Item{
;
return result;
}
public boolean equals(Object obj){
boolean result = false;
if (obj != null && obj instanceof IndexItem){
IndexItem other = (IndexItem)obj;
result = other.offset == this.offset;
}
return result;
}
public int hashCode(){
return (int)offset;
}
}

View File

@ -17,7 +17,6 @@ import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.LinkedList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
@ -25,8 +24,9 @@ import org.apache.commons.logging.LogFactory;
*
* @version $Revision: 1.1.1.1 $
*/
final class IndexManager {
final class IndexManager{
private static final Log log=LogFactory.getLog(IndexManager.class);
private static final String NAME_PREFIX="index-";
private final String name;
private File file;
private RandomAccessFile indexFile;
@ -35,12 +35,12 @@ final class IndexManager {
private LinkedList freeList=new LinkedList();
private long length=0;
IndexManager(File directory, String name, String mode, DataManager redoLog ) throws IOException{
this.name = name;
file=new File(directory,"index-"+name);
; indexFile=new RandomAccessFile(file,mode);
IndexManager(File directory,String name,String mode,DataManager redoLog) throws IOException{
this.name=name;
file=new File(directory,NAME_PREFIX+name);
indexFile=new RandomAccessFile(file,mode);
reader=new StoreIndexReader(indexFile);
writer=new StoreIndexWriter(indexFile, name, redoLog);
writer=new StoreIndexWriter(indexFile,name,redoLog);
long offset=0;
while((offset+IndexItem.INDEX_SIZE)<=indexFile.length()){
IndexItem index=reader.readItem(offset);
@ -53,7 +53,7 @@ final class IndexManager {
length=offset;
}
synchronized boolean isEmpty() throws IOException{
synchronized boolean isEmpty(){
return freeList.isEmpty()&&length==0;
}
@ -71,12 +71,12 @@ final class IndexManager {
synchronized void updateIndex(IndexItem index) throws IOException{
writer.storeItem(index);
}
public void redo(RedoStoreIndexItem redo) throws IOException {
public void redo(final RedoStoreIndexItem redo) throws IOException{
writer.redoStoreItem(redo);
}
synchronized IndexItem createNewIndex() throws IOException{
synchronized IndexItem createNewIndex(){
IndexItem result=getNextFreeIndex();
if(result==null){
// allocate one
@ -109,7 +109,7 @@ final class IndexManager {
return file.delete();
}
private IndexItem getNextFreeIndex() throws IOException{
private IndexItem getNextFreeIndex(){
IndexItem result=null;
if(!freeList.isEmpty()){
result=(IndexItem) freeList.removeLast();
@ -126,8 +126,8 @@ final class IndexManager {
this.length=value;
}
public String getName() {
return name;
public String toString(){
return "IndexManager:("+NAME_PREFIX+name+")";
}
}

View File

@ -23,12 +23,12 @@ import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.kaha.ListContainer;
import org.apache.activemq.kaha.MapContainer;
import org.apache.activemq.kaha.RuntimeStoreException;
import org.apache.activemq.kaha.Store;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
/**
* Optimized Store writer
@ -38,7 +38,7 @@ import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
public class KahaStore implements Store{
private static final String DEFAULT_CONTAINER_NAME = "kaha";
private static final Log log=LogFactory.getLog(KahaStore.class);
private File directory;
private IndexRootContainer mapsContainer;
@ -48,6 +48,7 @@ public class KahaStore implements Store{
private Map dataManagers = new ConcurrentHashMap();
private Map indexManagers = new ConcurrentHashMap();
private IndexManager rootIndexManager; //contains all the root indexes
private boolean closed=false;
private String name;
@ -115,19 +116,30 @@ public class KahaStore implements Store{
initialize();
clear();
boolean result=true;
for (Iterator iter = indexManagers.values().iterator(); iter.hasNext();) {
IndexManager im = (IndexManager) iter.next();
result &= im.delete();
for(Iterator iter=indexManagers.values().iterator();iter.hasNext();){
IndexManager im=(IndexManager) iter.next();
result&=im.delete();
iter.remove();
}
for (Iterator iter = dataManagers.values().iterator(); iter.hasNext();) {
DataManager dm = (DataManager) iter.next();
result &= dm.delete();
for(Iterator iter=dataManagers.values().iterator();iter.hasNext();){
DataManager dm=(DataManager) iter.next();
result&=dm.delete();
iter.remove();
}
// now delete all the files - containers that don't use the standard DataManager
// and IndexManager will not have initialized the files - so these will be left around
// unless we do this
if(directory!=null&&directory.isDirectory()){
File[] files=directory.listFiles();
if(files!=null){
for(int i=0;i<files.length;i++){
File file=files[i];
if(!file.isDirectory()){
result&=file.delete();
}
}
}
}
initialized=false;
return result;
}
@ -158,7 +170,7 @@ public class KahaStore implements Store{
if( root == null ) {
root=mapsContainer.addRoot(containerId);
}
result=new MapContainerImpl(containerId,root,im,dm);
result=new MapContainerImpl(containerId,root,rootIndexManager,im,dm);
result.expressDataInterest();
maps.put(containerId.getKey(),result);
@ -203,7 +215,7 @@ public class KahaStore implements Store{
if( root == null ) {
root=listsContainer.addRoot(containerId);
}
result=new ListContainerImpl(containerId,root,im,dm);
result=new ListContainerImpl(containerId,root,rootIndexManager,im,dm);
result.expressDataInterest();
lists.put(containerId.getKey(),result);
}
@ -237,24 +249,25 @@ public class KahaStore implements Store{
initialized=true;
directory=new File(name);
directory.mkdirs();
log.info("Kaha Store using data directory " + directory);
DataManager defaultDM = getDataManager(DEFAULT_CONTAINER_NAME);
IndexManager defaultIM = getIndexManager(defaultDM, DEFAULT_CONTAINER_NAME);
rootIndexManager = getIndexManager(defaultDM, DEFAULT_CONTAINER_NAME);
IndexItem mapRoot=new IndexItem();
IndexItem listRoot=new IndexItem();
if(defaultIM.isEmpty()){
if(rootIndexManager.isEmpty()){
mapRoot.setOffset(0);
defaultIM.updateIndex(mapRoot);
rootIndexManager.updateIndex(mapRoot);
listRoot.setOffset(IndexItem.INDEX_SIZE);
defaultIM.updateIndex(listRoot);
defaultIM.setLength(IndexItem.INDEX_SIZE*2);
rootIndexManager.updateIndex(listRoot);
rootIndexManager.setLength(IndexItem.INDEX_SIZE*2);
}else{
mapRoot=defaultIM.getIndex(0);
listRoot=defaultIM.getIndex(IndexItem.INDEX_SIZE);
mapRoot=rootIndexManager.getIndex(0);
listRoot=rootIndexManager.getIndex(IndexItem.INDEX_SIZE);
}
mapsContainer=new IndexRootContainer(mapRoot,defaultIM,defaultDM);
listsContainer=new IndexRootContainer(listRoot,defaultIM,defaultDM);
mapsContainer=new IndexRootContainer(mapRoot,rootIndexManager,defaultDM);
listsContainer=new IndexRootContainer(listRoot,rootIndexManager,defaultDM);
for (Iterator i = dataManagers.values().iterator(); i.hasNext();){
DataManager dm = (DataManager) i.next();

View File

@ -30,13 +30,13 @@ import org.apache.commons.logging.LogFactory;
*
* @version $Revision: 1.2 $
*/
final class ListContainerImpl extends BaseContainerImpl implements ListContainer{
public final class ListContainerImpl extends BaseContainerImpl implements ListContainer{
private static final Log log=LogFactory.getLog(ListContainerImpl.class);
protected Marshaller marshaller=new ObjectMarshaller();
protected ListContainerImpl(ContainerId id,IndexItem root,IndexManager indexManager,DataManager dataManager)
protected ListContainerImpl(ContainerId id,IndexItem root,IndexManager rootIndexManager,IndexManager indexManager,DataManager dataManager)
throws IOException{
super(id,root,indexManager,dataManager);
super(id,root,rootIndexManager,indexManager,dataManager);
}
/*
@ -50,6 +50,7 @@ final class ListContainerImpl extends BaseContainerImpl implements ListContainer
synchronized(mutex){
if(!loaded){
loaded=true;
init();
try{
long nextItem=root.getNextItem();
while(nextItem!=Item.POSITION_NOT_SET){
@ -101,8 +102,9 @@ final class ListContainerImpl extends BaseContainerImpl implements ListContainer
Object o1=other.get(i);
Object o2=get(i);
result=o1==o2||(o1!=null&&o2!=null&&o1.equals(o2));
if(!result)
if(!result){
break;
}
}
}
}
@ -178,15 +180,13 @@ final class ListContainerImpl extends BaseContainerImpl implements ListContainer
load();
Object result=null;
synchronized(mutex){
IndexItem item=(IndexItem) list.getLast();
if(item!=null){
result=getValue(item);
int index=list.indexOf(item);
IndexItem prev=index>0?(IndexItem) list.get(index-1):root;
IndexItem last=list.getLast();
if(last!=null){
result=getValue(last);
IndexItem prev=list.getPrevEntry(last);
IndexItem next=null;
list.removeLast();
delete(item,prev,next);
item=null;
delete(last,prev,next);
}
}
return result;
@ -310,10 +310,9 @@ final class ListContainerImpl extends BaseContainerImpl implements ListContainer
protected void remove(IndexItem item){
synchronized(mutex){
int index=list.indexOf(item);
IndexItem prev=index>0?(IndexItem) list.get(index-1):root;
IndexItem next=index<(list.size()-1)?(IndexItem) list.get(index+1):null;
list.remove(index);
IndexItem prev = list.getPrevEntry(item);
IndexItem next = list.getNextEntry(item);
list.remove(item);
delete(item,prev,next);
}
}
@ -416,7 +415,7 @@ final class ListContainerImpl extends BaseContainerImpl implements ListContainer
public void clear(){
checkClosed();
synchronized(mutex){
list.clear();
super.clear();
doClear();
}
}
@ -533,7 +532,7 @@ final class ListContainerImpl extends BaseContainerImpl implements ListContainer
result=getValue(item);
IndexItem prev=list.getPrevEntry(item);
prev=prev!=null?prev:root;
IndexItem next=list.getNextEntry(prev);
IndexItem next=list.getNextEntry(item);
list.remove(index);
delete(item,prev,next);
}
@ -649,13 +648,13 @@ final class ListContainerImpl extends BaseContainerImpl implements ListContainer
IndexItem next=list.getNextEntry(prev);
prev.setNextItem(index.getOffset());
index.setPreviousItem(prev.getOffset());
indexManager.updateIndex(prev);
updateIndex(prev);
if(next!=null){
next.setPreviousItem(index.getOffset());
index.setNextItem(next.getOffset());
indexManager.updateIndex(next);
updateIndex(next);
}
indexManager.updateIndex(index);
updateIndex(index);
}
}catch(IOException e){
log.error("Failed to write "+value,e);
@ -675,13 +674,13 @@ final class ListContainerImpl extends BaseContainerImpl implements ListContainer
IndexItem next=list.getNextEntry(prev);
prev.setNextItem(index.getOffset());
index.setPreviousItem(prev.getOffset());
indexManager.updateIndex(prev);
updateIndex(prev);
if(next!=null){
next.setPreviousItem(index.getOffset());
index.setNextItem(next.getOffset());
indexManager.updateIndex(next);
updateIndex(next);
}
indexManager.updateIndex(index);
updateIndex(index);
}
}catch(IOException e){
log.error("Failed to write "+value,e);
@ -713,13 +712,13 @@ final class ListContainerImpl extends BaseContainerImpl implements ListContainer
}
prev.setNextItem(index.getOffset());
index.setPreviousItem(prev.getOffset());
indexManager.updateIndex(prev);
updateIndex(prev);
if(next!=null){
next.setPreviousItem(index.getOffset());
index.setNextItem(next.getOffset());
indexManager.updateIndex(next);
updateIndex(next);
}
indexManager.updateIndex(index);
updateIndex(index);
}
}catch(IOException e){
log.error("Failed to insert "+value,e);
@ -741,4 +740,23 @@ final class ListContainerImpl extends BaseContainerImpl implements ListContainer
}
return result;
}
/**
* @return a string representation of this collection.
*/
public String toString(){
StringBuffer result=new StringBuffer();
result.append("[");
Iterator i=iterator();
boolean hasNext=i.hasNext();
while(hasNext){
Object o=i.next();
result.append(String.valueOf(o));
hasNext=i.hasNext();
if(hasNext)
result.append(", ");
}
result.append("]");
return result.toString();
}
}

View File

@ -18,7 +18,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.kaha.MapContainer;
@ -39,8 +38,8 @@ final class MapContainerImpl extends BaseContainerImpl implements MapContainer{
protected Marshaller keyMarshaller=new ObjectMarshaller();
protected Marshaller valueMarshaller=new ObjectMarshaller();
protected MapContainerImpl(ContainerId id,IndexItem root,IndexManager indexManager,DataManager dataManager){
super(id,root,indexManager,dataManager);
protected MapContainerImpl(ContainerId id,IndexItem root,IndexManager rootIndexManager,IndexManager indexManager,DataManager dataManager){
super(id,root,rootIndexManager,indexManager,dataManager);
}
/*
@ -53,6 +52,7 @@ final class MapContainerImpl extends BaseContainerImpl implements MapContainer{
if(!loaded){
synchronized(mutex){
if(!loaded){
init();
loaded=true;
try{
long nextItem=root.getNextItem();
@ -72,6 +72,7 @@ final class MapContainerImpl extends BaseContainerImpl implements MapContainer{
}
}
}
}
/*
@ -255,9 +256,10 @@ final class MapContainerImpl extends BaseContainerImpl implements MapContainer{
if(item!=null){
map.remove(key);
valueToKeyMap.remove(item);
// ensure we have the upto date item
item=list.getEntry(item);
result=getValue(item);
IndexItem prev=list.getPrevEntry(item);
prev=prev!=null?prev:root;
IndexItem next=list.getNextEntry(item);
list.remove(item);
delete(item,prev,next);
@ -309,7 +311,7 @@ final class MapContainerImpl extends BaseContainerImpl implements MapContainer{
synchronized(mutex){
map.clear();
valueToKeyMap.clear();
list.clear();// going to re-use this
super.clear();
doClear();
}
}
@ -349,13 +351,18 @@ final class MapContainerImpl extends BaseContainerImpl implements MapContainer{
DataItem data=dataManager.storeDataItem(valueMarshaller,value);
index.setValueData(data);
}
IndexItem last=list.isEmpty()?null:(IndexItem) list.getLast();
last=last==null?root:last;
long prev=last.getOffset();
index.setPreviousItem(prev);
indexManager.updateIndex(index);
last.setNextItem(index.getOffset());
indexManager.updateIndex(last);
IndexItem prev=list.getLast();
prev=prev!=null?prev:list.getRoot();
IndexItem next=list.getNextEntry(prev);
prev.setNextItem(index.getOffset());
index.setPreviousItem(prev.getOffset());
updateIndex(prev);
if(next!=null){
next.setPreviousItem(index.getOffset());
index.setNextItem(next.getOffset());
updateIndex(next);
}
updateIndex(index);
}catch(IOException e){
log.error("Failed to write "+key+" , "+value,e);
throw new RuntimeStoreException(e);

View File

@ -0,0 +1,230 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* 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.apache.activemq.kaha.impl;
/**
* A linked list used by IndexItems
*
* @version $Revision: 1.2 $
*/
final class VMIndexLinkedList implements Cloneable, IndexLinkedList{
private transient IndexItem root;
private transient int size=0;
/**
* Constructs an empty list.
*/
VMIndexLinkedList(IndexItem header){
this.root = header;
this.root.next=root.prev=root;
}
public IndexItem getRoot(){
return root;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#getFirst()
*/
public IndexItem getFirst(){
if(size==0)
return null;
return root.next;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#getLast()
*/
public IndexItem getLast(){
if(size==0)
return null;
return root.prev;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#removeFirst()
*/
public IndexItem removeFirst(){
if(size==0){
return null;
}
IndexItem result=root.next;
remove(root.next);
return result;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#removeLast()
*/
public Object removeLast(){
if(size==0)
return null;
IndexItem result=root.prev;
remove(root.prev);
return result;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#addFirst(org.apache.activemq.kaha.impl.IndexItem)
*/
public void addFirst(IndexItem item){
addBefore(item,root.next);
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#addLast(org.apache.activemq.kaha.impl.IndexItem)
*/
public void addLast(IndexItem item){
addBefore(item,root);
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#size()
*/
public int size(){
return size;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#isEmpty()
*/
public boolean isEmpty(){
return size==0;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#add(org.apache.activemq.kaha.impl.IndexItem)
*/
public boolean add(IndexItem item){
addBefore(item,root);
return true;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#clear()
*/
public void clear(){
root.next=root.prev=root;
size=0;
}
// Positional Access Operations
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#get(int)
*/
public IndexItem get(int index){
return entry(index);
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#add(int, org.apache.activemq.kaha.impl.IndexItem)
*/
public void add(int index,IndexItem element){
addBefore(element,(index==size?root:entry(index)));
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#remove(int)
*/
public Object remove(int index){
IndexItem e=entry(index);
remove(e);
return e;
}
/**
* Return the indexed entry.
*/
private IndexItem entry(int index){
if(index<0||index>=size)
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
IndexItem e=root;
if(index<size/2){
for(int i=0;i<=index;i++)
e=e.next;
}else{
for(int i=size;i>index;i--)
e=e.prev;
}
return e;
}
// Search Operations
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#indexOf(org.apache.activemq.kaha.impl.IndexItem)
*/
public int indexOf(IndexItem o){
int index=0;
for(IndexItem e=root.next;e!=root;e=e.next){
if(o==e){
return index;
}
index++;
}
return -1;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#getNextEntry(org.apache.activemq.kaha.impl.IndexItem)
*/
public IndexItem getNextEntry(IndexItem entry){
return entry.next != root ? entry.next : null;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#getPrevEntry(org.apache.activemq.kaha.impl.IndexItem)
*/
public IndexItem getPrevEntry(IndexItem entry){
return entry.prev != root ? entry.prev : null;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#addBefore(org.apache.activemq.kaha.impl.IndexItem, org.apache.activemq.kaha.impl.IndexItem)
*/
public void addBefore(IndexItem insert,IndexItem e){
insert.next=e;
insert.prev=e.prev;
insert.prev.next=insert;
insert.next.prev=insert;
size++;
}
/* (non-Javadoc)
* @see org.apache.activemq.kaha.impl.IndexLinkedList#remove(org.apache.activemq.kaha.impl.IndexItem)
*/
public void remove(IndexItem e){
if(e==root)
return;
e.prev.next=e.next;
e.next.prev=e.prev;
size--;
}
/**
*@return clone
*/
public Object clone(){
IndexLinkedList clone=new VMIndexLinkedList(this.root);
for(IndexItem e=root.next;e!=root;e=e.next)
clone.add(e);
return clone;
}
public IndexItem getEntry(IndexItem current){
return current;
}
}

View File

@ -5,20 +5,18 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import junit.framework.TestCase;
public class ListContainerTest extends TestCase{
protected String name;
protected String name="test";
protected Store store;
protected ListContainer container;
protected LinkedList testList;
protected static final int COUNT = 10;
protected static final int COUNT=10;
/*
* Test method for 'org.apache.activemq.kaha.ListContainer.size()'
*/
public void testSize()throws Exception {
public void testSize() throws Exception{
container.addAll(testList);
assertEquals(container.size(),testList.size());
}
@ -26,10 +24,10 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'org.apache.activemq.kaha.ListContainer.addFirst(Object)'
*/
public void testAddFirst()throws Exception {
public void testAddFirst() throws Exception{
container.addAll(testList);
assertEquals(container.size(),testList.size());
String first = "first";
String first="first";
container.addFirst(first);
assertEquals(first,container.get(0));
assertEquals(container.size(),testList.size()+1);
@ -38,10 +36,10 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'org.apache.activemq.kaha.ListContainer.addLast(Object)'
*/
public void testAddLast()throws Exception {
public void testAddLast() throws Exception{
container.addAll(testList);
assertEquals(container.size(),testList.size());
String last = "last";
String last="last";
container.addLast(last);
assertEquals(last,container.get(testList.size()));
assertEquals(container.size(),testList.size()+1);
@ -50,12 +48,12 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'org.apache.activemq.kaha.ListContainer.removeFirst()'
*/
public void testRemoveFirst()throws Exception {
public void testRemoveFirst() throws Exception{
container.addAll(testList);
assertEquals(container.size(),testList.size());
assertEquals(testList.get(0),container.removeFirst());
assertEquals(container.size(),testList.size()-1);
for (int i =1; i < testList.size(); i++){
for(int i=1;i<testList.size();i++){
assertEquals(testList.get(i),container.get(i-1));
}
}
@ -63,45 +61,44 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'org.apache.activemq.kaha.ListContainer.removeLast()'
*/
public void testRemoveLast()throws Exception {
public void testRemoveLast() throws Exception{
container.addAll(testList);
assertEquals(container.size(),testList.size());
assertEquals(testList.get(testList.size()-1),container.removeLast());
assertEquals(container.size(),testList.size()-1);
for (int i =0; i < testList.size()-1; i++){
for(int i=0;i<testList.size()-1;i++){
assertEquals(testList.get(i),container.get(i));
}
}
/*
* Test method for 'java.util.List.iterator()'
*/
public void testIterator()throws Exception {
public void testIterator() throws Exception{
container.addAll(testList);
for (Iterator i = testList.iterator(), j = container.iterator(); i.hasNext();){
for(Iterator i=testList.iterator(),j=container.iterator();i.hasNext();){
assertEquals(i.next(),j.next());
}
for (Iterator i = container.iterator(); i.hasNext();){
for(Iterator i=container.iterator();i.hasNext();){
i.next();
i.remove();
}
assert(container.isEmpty());
assert (container.isEmpty());
}
/*
* Test method for 'java.util.List.isEmpty()'
*/
public void testIsEmpty()throws Exception {
public void testIsEmpty() throws Exception{
assertTrue(container.isEmpty());
}
/*
* Test method for 'java.util.List.contains(Object)'
*/
public void testContains()throws Exception {
public void testContains() throws Exception{
container.addAll(testList);
for (Iterator i = testList.iterator(), j = container.iterator(); i.hasNext();){
for(Iterator i=testList.iterator(),j=container.iterator();i.hasNext();){
assertTrue(container.contains(i.next()));
}
}
@ -109,24 +106,23 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'java.util.List.toArray()'
*/
public void testToArray()throws Exception {
public void testToArray() throws Exception{
container.addAll(testList);
Object[] a = testList.toArray();
Object[] b = container.toArray();
Object[] a=testList.toArray();
Object[] b=container.toArray();
assertEquals(a.length,b.length);
for (int i = 0 ; i < a.length; i++){
for(int i=0;i<a.length;i++){
assertEquals(a[i],b[i]);
}
}
/*
* Test method for 'java.util.List.remove(Object)'
*/
public void testRemoveObject()throws Exception {
public void testRemoveObject() throws Exception{
container.addAll(testList);
assertEquals(container.size(),testList.size());
for (int i =0; i < testList.size(); i++){
for(int i=0;i<testList.size();i++){
container.remove(testList.get(i));
}
assertTrue(container.isEmpty());
@ -135,16 +131,15 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'java.util.List.containsAll(Collection<?>)'
*/
public void testContainsAll()throws Exception {
public void testContainsAll() throws Exception{
container.addAll(testList);
assertTrue(container.containsAll(testList));
}
/*
* Test method for 'java.util.List.removeAll(Collection<?>)'
*/
public void testRemoveAll()throws Exception {
public void testRemoveAll() throws Exception{
container.addAll(testList);
assertEquals(testList.size(),container.size());
container.removeAll(testList);
@ -154,7 +149,7 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'java.util.List.retainAll(Collection<?>)'
*/
public void testRetainAll()throws Exception {
public void testRetainAll() throws Exception{
container.addAll(testList);
assertEquals(testList.size(),container.size());
testList.remove(0);
@ -165,20 +160,19 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'java.util.List.clear()'
*/
public void testClear()throws Exception {
public void testClear() throws Exception{
container.addAll(testList);
assertEquals(testList.size(),container.size());
container.clear();
assertTrue(container.isEmpty());
}
/*
* Test method for 'java.util.List.get(int)'
*/
public void testGet()throws Exception {
public void testGet() throws Exception{
container.addAll(testList);
for (int i =0; i < testList.size();i++){
for(int i=0;i<testList.size();i++){
assertEquals(container.get(i),testList.get(i));
}
}
@ -186,38 +180,37 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'java.util.List.set(int, E)'
*/
public void testSet()throws Exception {
public void testSet() throws Exception{
container.addAll(testList);
}
/*
* Test method for 'java.util.List.add(int, E)'
*/
public void testAddIntE()throws Exception {
public void testAddIntE() throws Exception{
container.addAll(testList);
assertTrue(container.equals(testList));
Object testObj = "testObj";
int index = 0;
testList.set(index, testObj);
container.set(index, testObj);
Object testObj="testObj";
int index=0;
testList.set(index,testObj);
container.set(index,testObj);
assertTrue(container.equals(testList));
index = testList.size()-1;
testList.set(index, testObj);
container.set(index, testObj);
index=testList.size()-1;
testList.set(index,testObj);
container.set(index,testObj);
assertTrue(container.equals(testList));
}
/*
* Test method for 'java.util.List.remove(int)'
*/
public void testRemoveInt()throws Exception {
public void testRemoveInt() throws Exception{
container.addAll(testList);
assertTrue(container.equals(testList));
testList.remove(0);
container.remove(0);
assertTrue(container.equals(testList));
int pos = testList.size()-1;
int pos=testList.size()-1;
testList.remove(pos);
container.remove(pos);
assertTrue(container.equals(testList));
@ -226,28 +219,27 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'java.util.List.indexOf(Object)'
*/
public void testIndexOf()throws Exception {
public void testIndexOf() throws Exception{
container.addAll(testList);
assertTrue(container.equals(testList));
for (int i =0; i < testList.size(); i++){
Object o = testList.get(i);
assertEquals(i,container.indexOf(o));
for(int i=0;i<testList.size();i++){
Object o=testList.get(i);
assertEquals(i,container.indexOf(o));
}
}
/*
* Test method for 'java.util.List.listIterator()'
*/
public void testListIterator()throws Exception {
public void testListIterator() throws Exception{
container.addAll(testList);
ListIterator containerIter = container.listIterator();
ListIterator testIter = testList.listIterator();
ListIterator containerIter=container.listIterator();
ListIterator testIter=testList.listIterator();
assertTrue(testIter.hasNext());
assertTrue(containerIter.hasNext());
while (testIter.hasNext()){
Object o1 = testIter.next();
Object o2 = containerIter.next();
while(testIter.hasNext()){
Object o1=testIter.next();
Object o2=containerIter.next();
assertEquals(o1,o2);
testIter.remove();
containerIter.remove();
@ -259,16 +251,16 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'java.util.List.listIterator(int)'
*/
public void testListIteratorInt()throws Exception {
public void testListIteratorInt() throws Exception{
container.addAll(testList);
int start = testList.size()/2;
ListIterator containerIter = container.listIterator(start);
ListIterator testIter = testList.listIterator(start);
int start=testList.size()/2;
ListIterator containerIter=container.listIterator(start);
ListIterator testIter=testList.listIterator(start);
assertTrue(testIter.hasNext());
assertTrue(containerIter.hasNext());
while (testIter.hasNext()){
Object o1 = testIter.next();
Object o2 = containerIter.next();
while(testIter.hasNext()){
Object o1=testIter.next();
Object o2=containerIter.next();
assertEquals(o1,o2);
}
}
@ -276,39 +268,38 @@ public class ListContainerTest extends TestCase{
/*
* Test method for 'java.util.List.subList(int, int)'
*/
public void testSubList()throws Exception {
public void testSubList() throws Exception{
container.addAll(testList);
int start = testList.size()/2;
List l1 = testList.subList(start, testList.size());
List l2 = container.subList(start, testList.size());
int start=testList.size()/2;
List l1=testList.subList(start,testList.size());
List l2=container.subList(start,testList.size());
assertEquals(l1.size(),l2.size());
assertEquals(l1,l2);
}
protected Store getStore() throws IOException{
return StoreFactory.open(name, "rw");
return StoreFactory.open(name,"rw");
}
protected void setUp() throws Exception{
super.setUp();
name = System.getProperty("basedir", ".")+"/target/activemq-data/list-container.db";
StoreFactory.delete(name);
store = getStore();
store=getStore();
store.deleteListContainer(name);
container = store.getListContainer(name);
container=store.getListContainer(name);
container.load();
testList = new LinkedList();
for (int i =0; i < COUNT; i++){
String value = "value:"+i;
testList=new LinkedList();
for(int i=0;i<COUNT;i++){
String value="value:"+i;
testList.add(value);
}
}
protected void tearDown() throws Exception{
super.tearDown();
if( store!= null ) {
store.close();
if(store!=null){
store.close();
}
assertTrue(StoreFactory.delete(name));
}

View File

@ -15,7 +15,7 @@ import junit.framework.TestCase;
public class MapContainerTest extends TestCase{
protected String name;
protected String name = "test";
protected Store store;
protected MapContainer container;
protected Map testMap;

View File

@ -162,24 +162,39 @@ public class StoreTest extends TestCase{
testList.add("value:"+i);
}
String listId = "testList";
String mapId = "testMap";
MapContainer mapContainer = store.getMapContainer(mapId);
mapContainer.load();
String mapId1 = "testMap";
String mapId2 = "testMap2";
MapContainer mapContainer1 = store.getMapContainer(mapId1);
mapContainer1.load();
mapContainer1.putAll(testMap);
MapContainer mapContainer2 = store.getMapContainer(mapId2,mapId2);
mapContainer2.load();
mapContainer2.putAll(testMap);
ListContainer listContainer = store.getListContainer(listId);
listContainer.load();
mapContainer.putAll(testMap);
listContainer.addAll(testList);
store.close();
store = getStore();
mapContainer = store.getMapContainer(mapId);
mapContainer.load();
mapContainer1 = store.getMapContainer(mapId1);
mapContainer1.load();
mapContainer2 = store.getMapContainer(mapId2,mapId2);
mapContainer2.load();
listContainer = store.getListContainer(listId);
listContainer.load();
for (Iterator i = testMap.keySet().iterator(); i.hasNext();){
Object key = i.next();
Object value = testMap.get(key);
assertTrue(mapContainer.containsKey(key));
assertEquals(value,mapContainer.get(key));
assertTrue(mapContainer1.containsKey(key));
assertEquals(value,mapContainer1.get(key));
}
for (Iterator i = testMap.keySet().iterator(); i.hasNext();){
Object key = i.next();
Object value = testMap.get(key);
assertTrue(mapContainer2.containsKey(key));
assertEquals(value,mapContainer2.get(key));
}
assertEquals(testList.size(),listContainer.size());
for (Iterator i = testList.iterator(), j = listContainer.iterator(); i.hasNext();){
@ -195,8 +210,7 @@ public class StoreTest extends TestCase{
protected void setUp() throws Exception{
super.setUp();
name = System.getProperty("basedir", ".")+"/target/activemq-data/store-test.db";
store = getStore();
store = getStore();
}
protected void tearDown() throws Exception{

View File

@ -0,0 +1,250 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* 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.apache.activemq.kaha.impl;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
/**
* @version $Revision: 1.2 $
*/
public class VMIndexLinkedListTest extends TestCase{
static final int NUMBER = 10;
private IndexItem root;
private List testData = new ArrayList();
private IndexLinkedList list;
protected void setUp() throws Exception{
super.setUp();
for (int i =0; i < NUMBER; i++){
testData.add(new IndexItem());
}
root = new IndexItem();
list = new VMIndexLinkedList(root);
}
protected void tearDown() throws Exception{
super.tearDown();
testData.clear();
list = null;
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.getFirst()'
*/
public void testGetFirst(){
for (int i =0; i < testData.size(); i++){
list.add((IndexItem) testData.get(i));
}
assertTrue(list.getFirst()==testData.get(0));
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.getLast()'
*/
public void testGetLast(){
for (int i =0; i < testData.size(); i++){
list.add((IndexItem) testData.get(i));
}
assertTrue(list.getLast()==testData.get(testData.size()-1));
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.removeFirst()'
*/
public void testRemoveFirst(){
for (int i =0; i < testData.size(); i++){
list.add((IndexItem) testData.get(i));
}
assertTrue(list.removeFirst()==testData.get(0));
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.removeLast()'
*/
public void testRemoveLast(){
for (int i =0; i < testData.size(); i++){
list.add((IndexItem) testData.get(i));
}
assertTrue(list.removeLast()==testData.get(testData.size()-1));
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.addFirst(IndexItem)'
*/
public void testAddFirst(){
for (int i =0; i < testData.size(); i++){
list.addFirst((IndexItem) testData.get(i));
}
int count = 0;
for (int i =testData.size()-1; i>=0; i--){
assertTrue(testData.get(i)==list.get(count++));
}
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.addLast(IndexItem)'
*/
public void testAddLast(){
for (int i =0; i < testData.size(); i++){
list.addLast((IndexItem) testData.get(i));
}
for (int i =0; i < testData.size(); i++){
assertTrue(testData.get(i)==list.get(i));
}
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.size()'
*/
public void testSize(){
for (int i =0; i < testData.size(); i++){
list.addLast((IndexItem) testData.get(i));
assertTrue(list.size()==i+1);
}
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.isEmpty()'
*/
public void testIsEmpty(){
for (int i =0; i < testData.size(); i++){
list.addLast((IndexItem) testData.get(i));
assertTrue(list.size()==i+1);
}
list.clear();
assertTrue(list.isEmpty());
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.add(IndexItem)'
*/
public void testAddIndexItem(){
for (int i =0; i < testData.size(); i++){
list.add((IndexItem) testData.get(i));
}
for (int i =0; i < testData.size(); i++){
assertTrue(testData.get(i)==list.get(i));
}
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.clear()'
*/
public void testClear(){
for (int i =0; i < testData.size(); i++){
list.addLast((IndexItem) testData.get(i));
assertTrue(list.size()==i+1);
}
list.clear();
assertTrue(list.isEmpty());
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.add(int, IndexItem)'
*/
public void testAddIntIndexItem(){
for (int i =0; i < testData.size(); i++){
list.add(i,(IndexItem) testData.get(i));
}
for (int i =0; i < testData.size(); i++){
assertTrue(testData.get(i)==list.get(i));
}
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.remove(int)'
*/
public void testRemoveInt(){
for (int i =0; i < testData.size(); i++){
list.add(i,(IndexItem) testData.get(i));
}
for (int i =0; i < testData.size(); i++){
list.remove(0);
}
assertTrue(list.isEmpty());
for (int i =0; i < testData.size(); i++){
list.add(i,(IndexItem) testData.get(i));
}
for (int i =0; i < testData.size(); i++){
list.remove(list.size()-1);
}
assertTrue(list.isEmpty());
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.indexOf(IndexItem)'
*/
public void testIndexOf(){
for (int i =0; i < testData.size(); i++){
list.add(i,(IndexItem) testData.get(i));
}
for (int i =0; i < testData.size(); i++){
assertTrue(list.indexOf((IndexItem) testData.get(i))==i);
}
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.getNextEntry(IndexItem)'
*/
public void testGetNextEntry(){
for (int i =0; i < testData.size(); i++){
list.add(i,(IndexItem) testData.get(i));
}
IndexItem next = list.getFirst();
int count = 0;
while (next != null){
assertTrue(next==testData.get(count++));
next = list.getNextEntry(next);
assertTrue(next != root);
}
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.getPrevEntry(IndexItem)'
*/
public void testGetPrevEntry(){
for (int i =0; i < testData.size(); i++){
list.add(i,(IndexItem) testData.get(i));
}
IndexItem next = list.getLast();
int count = testData.size()-1;
while (next != null){
assertTrue(next==testData.get(count--));
next = list.getPrevEntry(next);
assertTrue(next != root);
}
}
/*
* Test method for 'org.apache.activemq.kaha.impl.VMIndexLinkedList.remove(IndexItem)'
*/
public void testRemoveIndexItem(){
for (int i =0; i < testData.size(); i++){
list.add(i,(IndexItem) testData.get(i));
}
for (int i =0; i < testData.size(); i++){
list.remove((IndexItem)testData.get(i));
assertTrue(list.size()==testData.size()-i-1);
}
}
}