package gdsc.foci;
import java.util.Arrays;
import java.util.Comparator;
/*-----------------------------------------------------------------------------
* GDSC Plugins for ImageJ
*
* Copyright (C) 2016 Alex Herbert
* Genome Damage and Stability Centre
* University of Sussex, UK
*
* 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 2 of the License, or
* (at your option) any later version.
*---------------------------------------------------------------------------*/
/**
* Contains the foci saddle results of the FindFoci algorithm.
*/
public class FindFociSaddleList implements Cloneable
{
private static class IdSaddleComparator implements Comparator<FindFociSaddle>
{
public int compare(FindFociSaddle o1, FindFociSaddle o2)
{
final int result = o1.id - o2.id;
if (result != 0)
return result;
return o1.order - o2.order;
}
}
private static class OrderSaddleComparator implements Comparator<FindFociSaddle>
{
public int compare(FindFociSaddle o1, FindFociSaddle o2)
{
return o1.order - o2.order;
}
}
private static IdSaddleComparator idSaddleComparator;
private static OrderSaddleComparator orderSaddleComparator;
static
{
idSaddleComparator = new IdSaddleComparator();
orderSaddleComparator = new OrderSaddleComparator();
}
int size;
FindFociSaddle[] list;
/**
* Instantiates a new find foci saddle.
*/
public FindFociSaddleList()
{
this.list = new FindFociSaddle[0];
this.size = 0;
}
/**
* Instantiates a new find foci saddle.
*/
public FindFociSaddleList(FindFociSaddle[] list)
{
this.list = list;
if (list != null)
this.size = list.length;
}
/**
* get the size of the list
*
* @return The size
*/
public int getSize()
{
return size;
}
/**
* Get the saddle for the index
*
* @param i
* The index
* @return The saddle
*/
public FindFociSaddle get(final int i)
{
return list[i];
}
/**
* Add a new saddle. Does not check there is capacity to do this. Call {@link #ensureExtraCapacity(int)} first.
*
* @param saddle
* The saddle
*/
public void add(FindFociSaddle saddle)
{
list[size++] = saddle;
}
/**
* Clear the list but do not reduce the capacity
*/
public void clear()
{
clear(0);
}
/**
* Free memory (Set size to zero and the list to null)
*/
void free()
{
size = 0;
list = null;
}
/**
* Clear the list from the given position but do not reduce the capacity
*
* @param position
* The position
*/
public void clear(int position)
{
if (position == size)
return;
final int oldSize = size;
size = position;
while (position < oldSize)
list[position++] = null;
}
/**
* Clear the list and set capacity to zero. This should be called to allow the garbage collector to work on freeing
* memory.
*/
public void erase()
{
clear();
list = null;
}
/**
* Ensure that n extra elements can be added to the list.
* <p>
* Note this is different from the ensureCapacity() method of ArrayList which checks total capacity.
*
* @param n
* The number of extra elements (this should not be negative)
*/
public void ensureExtraCapacity(int n)
{
if (list.length - size >= n)
return;
// Increase size
list = Arrays.copyOf(list, size + n);
// On the assumption that any list which needs extra capacity will be from a large peak
// This does not appear to affect speed so it is left commented out.
//list = Arrays.copyOf(list, Math.max(size + n, (int) (list.length * 3)));
}
/**
* Get the total capacity of the list
*
* @return The total capacity
*/
public int getCapacity()
{
return list.length;
}
/**
* Returns a hard copy of this saddle.
*
* @return the find foci saddle
* @see java.lang.Object#clone()
*/
@Override
public FindFociSaddleList clone()
{
// Make same length so that add operations behave exactly the same
if (size == 0)
{
if (list == null)
// This is a list that has had the free() method called
return new FindFociSaddleList(null);
else
// This list is just empty
return new FindFociSaddleList();
}
final FindFociSaddle[] list = new FindFociSaddle[this.list.length];
for (int i = 0; i < size; i++)
list[i] = this.list[i].clone();
final FindFociSaddleList newList = new FindFociSaddleList(list);
newList.size = this.size;
return newList;
}
/**
* Sort the list
*/
public void sort()
{
if (size < 0)
return;
Arrays.sort(list, 0, size);
}
/**
* Sort the list using the comparator
*
* @param saddleComparator
*/
public void sort(Comparator<FindFociSaddle> saddleComparator)
{
if (size < 0)
return;
Arrays.sort(list, 0, size, saddleComparator);
}
/**
* Remove duplicate Ids from the list and maintain the current order, or else do a default sort
*
* @param maintain
* Maintain the current order, otherwise do default sort
*/
public void removeDuplicates(boolean maintain)
{
if (size < 2)
return;
for (int i = 0; i < size; i++)
list[i].order = i;
sort(idSaddleComparator);
int lastId = 0;
int newSize = 0;
for (int i = 0; i < size; i++)
{
if (lastId != list[i].id)
{
list[newSize++] = list[i];
lastId = list[i].id;
}
}
clear(newSize);
if (maintain)
sort(orderSaddleComparator);
else
sort();
}
/**
* Sort the list by Id but otherwise maintain the current order
*/
public void sortById()
{
if (size < 2)
return;
for (int i = 0; i < size; i++)
list[i].order = i;
sort(idSaddleComparator);
}
}