/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.engine.value.properties;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
/**
* An immutable set of property name strings, backed by the property hash array.
*/
public final class PropertyNameSet implements Set<String> {
private final AbstractValueProperty[] _properties;
private volatile int _size = -1;
/**
* Creates a new instance.
*
* @param properties the values backing the set. This class will use this object but not modify it.
*/
public PropertyNameSet(final AbstractValueProperty[] properties) {
_properties = properties;
}
@Override
public int size() {
if (_size < 0) {
int size = 0;
for (AbstractValueProperty property : _properties) {
for (; property != null; property = property.getNext()) {
size++;
}
}
_size = size;
}
return _size;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean contains(final Object o) {
if ((o == null) || !(o instanceof String)) {
return false;
}
final int hc = o.hashCode() & 0x7FFFFFFF;
AbstractValueProperty property = _properties[hc % _properties.length];
while (property != null) {
if (property.getKey().equals(o)) {
return true;
}
property = property.getNext();
}
return false;
}
@Override
public Iterator<String> iterator() {
return new Iterator<String>() {
private int _index;
private AbstractValueProperty _property;
@Override
public boolean hasNext() {
while (_property == null) {
if (_index < _properties.length) {
_property = _properties[_index++];
} else {
return false;
}
}
return true;
}
@Override
public String next() {
AbstractValueProperty property = _property;
if (property == null) {
while (property == null) {
if (_index < _properties.length) {
property = _properties[_index++];
} else {
throw new NoSuchElementException();
}
}
}
_property = property.getNext();
return property.getKey();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public Object[] toArray() {
final int size = size();
final Object[] result = new Object[size];
int i = 0;
for (AbstractValueProperty property : _properties) {
for (; property != null; property = property.getNext()) {
result[i++] = property.getKey();
}
}
return result;
}
@SuppressWarnings("unchecked")
@Override
public <T> T[] toArray(T[] a) {
final int size = size();
if (a.length < size) {
a = (T[]) Array.newInstance(a.getClass().getComponentType(), size);
}
int i = 0;
for (AbstractValueProperty property : _properties) {
for (; property != null; property = property.getNext()) {
a[i++] = (T) property.getKey();
}
}
return a;
}
@Override
public boolean add(final String e) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(final Object o) {
throw new UnsupportedOperationException();
}
@Override
public boolean containsAll(final Collection<?> c) {
for (Object o : c) {
if (!contains(o)) {
return false;
}
}
return true;
}
@Override
public boolean addAll(final Collection<? extends String> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(final Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
}