io.protostuff.runtime.HashFieldMap Maven / Gradle / Ivy
package io.protostuff.runtime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Field mapping implemented on top of hash for field lookup by number.
*
* This is the less efficient than {@code ArrayFieldMap} for almost all cases.
* But in case when field numbers are sparse and especially when max field
* number is big - this mapping should be used.
*
* @see io.protostuff.runtime.ArrayFieldMap
*
* @author Kostiantyn Shchepanovskyi
*/
final class HashFieldMap implements FieldMap
{
private static final FieldComparator FIELD_COMPARATOR = new FieldComparator();
private final List> fields;
private final Map> fieldsByNumber;
private final Map> fieldsByName;
public HashFieldMap(Collection> fields)
{
fieldsByName = new HashMap<>();
fieldsByNumber = new HashMap<>();
for (Field f : fields)
{
if (fieldsByName.containsKey(f.name))
{
Field prev = fieldsByName.get(f.name);
throw new IllegalStateException(prev + " and " + f + " cannot have the same name.");
}
if (fieldsByNumber.containsKey(f.number))
{
Field prev = fieldsByNumber.get(f.number);
throw new IllegalStateException(prev + " and " + f + " cannot have the same number.");
}
this.fieldsByNumber.put(f.number, f);
this.fieldsByName.put(f.name, f);
}
List> fieldList = new ArrayList<>(fields.size());
fieldList.addAll(fields);
Collections.sort(fieldList, FIELD_COMPARATOR);
this.fields = Collections.unmodifiableList(fieldList);
}
@Override
public Field getFieldByNumber(int n)
{
return fieldsByNumber.get(n);
}
@Override
public Field getFieldByName(String fieldName)
{
return fieldsByName.get(fieldName);
}
@Override
public int getFieldCount()
{
return fields.size();
}
@Override
public List> getFields()
{
return fields;
}
private static class FieldComparator implements Comparator>
{
@Override
public int compare(Field> o1, Field> o2)
{
return Integer.compare(o1.number, o2.number);
}
}
}