All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.protostuff.runtime.ArrayFieldMap Maven / Gradle / Ivy

package io.protostuff.runtime;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Field mapping implemented on top of java array for lookup by number.
 *
 * This is the most efficient implementation for almost all cases. But
 * it should not be used when field numbers are sparse and especially
 * when max field number is big - as this mapping internally uses array
 * of integers with size equal to max field number. In latter case
 * {@code HashFieldMap} should be used.
 *
 * @see io.protostuff.runtime.HashFieldMap
 *
 * @author Kostiantyn Shchepanovskyi
 */
final class ArrayFieldMap implements FieldMap
{
    private final List> fields;
    private final Field[] fieldsByNumber;
    private final Map> fieldsByName;

    @SuppressWarnings("unchecked")
    public ArrayFieldMap(Collection> fields, int lastFieldNumber)
    {
        fieldsByName = new HashMap>();
        fieldsByNumber = (Field[]) new Field[lastFieldNumber + 1];
        for (Field f : fields)
        {
            Field last = this.fieldsByName.put(f.name, f);
            if (last != null)
            {
                throw new IllegalStateException(last + " and " + f
                        + " cannot have the same name.");
            }
            if (fieldsByNumber[f.number] != null)
            {
                throw new IllegalStateException(fieldsByNumber[f.number]
                        + " and " + f + " cannot have the same number.");
            }

            fieldsByNumber[f.number] = f;
        }

        List> fieldList = new ArrayList>(fields.size());
        for (Field field : fieldsByNumber)
        {
            if (field != null)
                fieldList.add(field);
        }
        this.fields = Collections.unmodifiableList(fieldList);
    }

    @Override
    public Field getFieldByNumber(int n)
    {
        return n < fieldsByNumber.length ? fieldsByNumber[n] : null;
    }

    @Override
    public Field getFieldByName(String fieldName)
    {
        return fieldsByName.get(fieldName);
    }

    /**
     * Returns the message's total number of fields.
     */
    @Override
    public int getFieldCount()
    {
        return fields.size();
    }

    @Override
    public List> getFields()
    {
        return fields;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy