package io.datakernel.cube;
import com.carrotsearch.hppc.ObjectIntOpenHashMap;
import java.lang.reflect.Type;
import java.util.*;
import static com.google.common.base.Preconditions.checkNotNull;
public final class RecordScheme {
private final LinkedHashMap<String, Type> fieldTypes = new LinkedHashMap<>();
protected int objects;
protected int ints;
protected int doubles;
protected int longs;
protected int floats;
protected ObjectIntOpenHashMap<String> fieldIndices = new ObjectIntOpenHashMap<>();
protected ObjectIntOpenHashMap<String> fieldRawIndices = new ObjectIntOpenHashMap<>();
protected String[] fields = new String[]{};
protected int[] rawIndices = new int[]{};
private RecordScheme() {
}
public static RecordScheme create() {
return new RecordScheme();
}
public RecordScheme withField(String field, Type type) {
checkNotNull(type);
fieldTypes.put(field, type);
fields = Arrays.copyOf(fields, fields.length + 1);
fields[fields.length - 1] = field;
int rawIndex;
if (type == int.class) {
rawIndex = (1 << 16) + ints;
ints++;
} else if (type == double.class) {
rawIndex = (2 << 16) + doubles;
doubles++;
} else if (type == long.class) {
rawIndex = (3 << 16) + longs;
longs++;
} else if (type == float.class) {
rawIndex = (4 << 16) + floats;
floats++;
} else {
rawIndex = (0 << 16) + objects;
objects++;
}
fieldIndices.put(field, fieldIndices.size());
fieldRawIndices.put(field, rawIndex);
rawIndices = Arrays.copyOf(rawIndices, rawIndices.length + 1);
rawIndices[rawIndices.length - 1] = rawIndex;
return this;
}
public RecordScheme withFields(Map<String, Class<?>> types) {
for (String field : types.keySet()) {
withField(field, types.get(field));
}
return this;
}
public List<String> getFields() {
return new ArrayList<>(fieldTypes.keySet());
}
public String getField(int index) {
return fields[index];
}
public Type getFieldType(String field) {
return fieldTypes.get(field);
}
public int getFieldIndex(String field) {
return fieldIndices.get(field);
}
}