net.sf.fmj.media.rtp.util.SSRCTable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fmj Show documentation
Show all versions of fmj Show documentation
Freedom for Media in Java
package net.sf.fmj.media.rtp.util;
import java.lang.reflect.*;
import java.util.*;
/**
*
* @author Lyubomir Marinov
*/
public class SSRCTable
{
static final int INCR = 16;
Object[] objList;
int[] ssrcList;
int total;
public SSRCTable()
{
ssrcList = new int[16];
objList = new Object[ssrcList.length];
total = 0;
}
public Enumeration elements()
{
// The method does not access any state of this instance. Consequently,
// it does not need to be synchronized. The synchronized keyword was
// removed because the method was seen to participate in a deadlock and
// because the presence or absence of the synchronized keyword will not
// make a difference if this SSRCTable is modified while iterating over
// the returned Enumeration anyway.
return
new Enumeration()
{
private int next = 0;
@Override
public boolean hasMoreElements()
{
return next < total;
}
@Override
public T nextElement()
{
synchronized (SSRCTable.this)
{
if (next < total)
{
@SuppressWarnings("unchecked")
T t = (T) objList[next++];
return t;
}
}
throw new NoSuchElementException("SSRCTable Enumeration");
}
};
}
public synchronized T get(int ssrc)
{
int i = indexOf(ssrc);
if (i < 0)
{
return null;
}
else
{
@SuppressWarnings("unchecked")
T t = (T) objList[i];
return t;
}
}
public synchronized int getSSRC(T obj)
{
for (int i = 0; i < total; i++)
{
if (objList[i] == obj)
return ssrcList[i];
}
return 0;
}
private int indexOf(int ssrc)
{
if (total <= 3)
{
if (total > 0 && ssrcList[0] == ssrc)
return 0;
if (total > 1 && ssrcList[1] == ssrc)
return 1;
return total <= 2 || ssrcList[2] != ssrc ? -1 : 2;
}
if (ssrcList[0] == ssrc)
return 0;
if (ssrcList[total - 1] == ssrc)
return total - 1;
int i = 0;
int j = total - 1;
do
{
int x = (j - i) / 2 + i;
if (ssrcList[x] == ssrc)
return x;
if (ssrc > ssrcList[x])
i = x + 1;
else if (ssrc < ssrcList[x])
j = x;
} while (i < j);
return -1;
}
public boolean isEmpty()
{
return size() == 0;
}
/**
* Gets the synchronization source identifiers (SSRCs) which are the keys
* associated with values in this SSRCTable.
*
* The method name is inspired by {@link Map#keys()} and
* {@link Collection#toArray(Object[])}.
*
*
* @param array the array into which the SSRCs associated with
* Objects in this SSRCTable are to be returned if the
* length of array is greater than or equal to the number
* of the SSRCs in question
* @return the SSRCs associated with Objects in this
* SSRCTable. If the number of SSRCs is less than or equal to the
* length of array, the SSRCs are written into
* array and array is returned. Otherwise, a new array is
* allocated.
*/
public synchronized int[] keysToArray(int[] array)
{
int length = size();
if (array == null || array.length < length)
array = new int[length];
System.arraycopy(ssrcList, 0, array, 0, length);
if (length < array.length)
Arrays.fill(array, length, array.length, 0);
return array;
}
public synchronized void put(int ssrc, T obj)
{
if (total == 0)
{
ssrcList[0] = ssrc;
objList[0] = obj;
total = 1;
return;
}
int i;
for (i = 0; i < total; i++)
{
if (ssrcList[i] < ssrc)
continue;
if (ssrcList[i] == ssrc)
{
objList[i] = obj;
return;
}
break;
}
int[] sl = ssrcList;
Object[] ol = objList;
if (total == ssrcList.length)
{
sl = new int[ssrcList.length + INCR];
ol = new Object[objList.length + INCR];
}
if (ssrcList != sl && i > 0)
{
System.arraycopy(ssrcList, 0, sl, 0, i);
System.arraycopy(objList, 0, ol, 0, i);
}
if (i < total)
{
System.arraycopy(ssrcList, i, sl, i+1, total-i);
System.arraycopy(objList, i, ol, i+1, total-i);
}
ssrcList = sl;
objList = ol;
ssrcList[i] = ssrc;
objList[i] = obj;
total++;
}
public synchronized T remove(int ssrc)
{
int i;
if ((i = indexOf(ssrc)) < 0)
return null;
@SuppressWarnings("unchecked")
T res = (T) objList[i];
for (; i < total - 1; i++)
{
ssrcList[i] = ssrcList[i + 1];
objList[i] = objList[i + 1];
}
ssrcList[total - 1] = 0;
objList[total - 1] = null;
total--;
return res;
}
public synchronized void removeAll()
{
for (int i = 0; i < total; i++)
{
ssrcList[i] = 0;
objList[i] = null;
}
total = 0;
}
public synchronized void removeObj(T obj)
{
if (obj == null)
return;
int i;
for (i = 0; i < total; i++)
if (objList[i] == obj)
break;
if (i >= total)
return;
for (; i < total - 1; i++)
{
ssrcList[i] = ssrcList[i + 1];
objList[i] = objList[i + 1];
}
ssrcList[total - 1] = 0;
objList[total - 1] = null;
total--;
}
public int size()
{
return total;
}
/**
* Gets the Objects which are the values associated with
* synchronization source identifiers (SSRCs) in this SSRCTable.
*
* The method name is inspired by {@link Map#values()} and
* {@link Collection#toArray(Object[])}.
*
*
* @param array the array into which the Objects associated with
* SSRCs in this SSRCTable are to be returned if the length
* of array is greater than or equal to the number of the
* Objects in question
* @return the Objects associated with SSRCs in this
* SSRCTable. If the number of Objects is less than or
* equal to the length of array, the Objects are
* written into array and array is returned. Otherwise, a
* new array is allocated.
*/
@SuppressWarnings("unchecked")
public synchronized T[] valuesToArray(T[] array)
{
Class componentType;
int length = size();
if (array == null)
componentType = Object.class;
else if (array.length < length)
componentType = array.getClass().getComponentType();
else
componentType = null;
if (componentType != null)
array = (T[]) Array.newInstance(componentType, length);
System.arraycopy(objList, 0, array, 0, length);
if (length < array.length)
Arrays.fill(array, length, array.length, null);
return array;
}
}