/* * ToroDB * Copyright © 2014 8Kdata Technology (www.8kdata.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.torodb.core.transaction.metainf; import com.google.common.base.Preconditions; import com.google.common.collect.HashBasedTable; import com.google.common.collect.Maps; import com.google.common.collect.Table; import com.torodb.core.TableRef; import com.torodb.core.annotations.DoNotChange; import java.util.Collections; import java.util.EnumMap; import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; /** * */ public class ImmutableMetaDocPart implements MetaDocPart { private final TableRef tableRef; private final String identifier; private final Table<String, FieldType, ImmutableMetaField> fieldsByNameAndType; private final Map<String, ImmutableMetaField> fieldsByIdentifier; private final EnumMap<FieldType, ImmutableMetaScalar> scalars; private final Map<String, ImmutableMetaIdentifiedDocPartIndex> indexesByIdentifier; public ImmutableMetaDocPart(TableRef tableRef, String dbName) { this(tableRef, dbName, Collections.emptyMap(), Maps.newEnumMap(FieldType.class), Collections .emptyMap()); } public ImmutableMetaDocPart(TableRef tableRef, String dbName, @DoNotChange Map<String, ImmutableMetaField> columns, @DoNotChange EnumMap<FieldType, ImmutableMetaScalar> scalars, @DoNotChange Map<String, ImmutableMetaIdentifiedDocPartIndex> indexes) { this.tableRef = tableRef; this.identifier = dbName; this.fieldsByIdentifier = columns; this.fieldsByNameAndType = HashBasedTable.create(columns.size(), 10); columns.values().forEach((column) -> fieldsByNameAndType.put(column.getName(), column .getType(), column)); this.scalars = scalars; this.indexesByIdentifier = indexes; } @Override public TableRef getTableRef() { return tableRef; } @Override public String getIdentifier() { return identifier; } @Override public Stream<ImmutableMetaField> streamFields() { return fieldsByIdentifier.values().stream(); } @Override public ImmutableMetaField getMetaFieldByIdentifier(String columnDbName) { return fieldsByIdentifier.get(columnDbName); } @Override public Stream<ImmutableMetaField> streamMetaFieldByName(String columnDocName) { return fieldsByNameAndType.row(columnDocName).values().stream(); } @Override public ImmutableMetaField getMetaFieldByNameAndType(String columnDocName, FieldType type) { return fieldsByNameAndType.get(columnDocName, type); } @Override public Stream<ImmutableMetaScalar> streamScalars() { return scalars.values().stream(); } @Override public ImmutableMetaScalar getScalar(FieldType type) { return scalars.get(type); } @Override public Stream<ImmutableMetaIdentifiedDocPartIndex> streamIndexes() { return indexesByIdentifier.values().stream(); } @Override public ImmutableMetaIdentifiedDocPartIndex getMetaDocPartIndexByIdentifier(String indexName) { return indexesByIdentifier.get(indexName); } @Override public String toString() { return defautToString(); } public static class Builder { private boolean built = false; private final TableRef tableRef; private final String identifier; private final HashMap<String, ImmutableMetaField> fields; private final EnumMap<FieldType, ImmutableMetaScalar> scalars; private final HashMap<String, ImmutableMetaIdentifiedDocPartIndex> indexes; public Builder(TableRef tableRef, String identifier) { this.tableRef = tableRef; this.identifier = identifier; this.fields = new HashMap<>(); this.scalars = new EnumMap<>(FieldType.class); this.indexes = new HashMap<>(); } public Builder(ImmutableMetaDocPart other) { this.tableRef = other.getTableRef(); this.identifier = other.getIdentifier(); this.fields = new HashMap<>(other.fieldsByIdentifier); this.scalars = new EnumMap<>(other.scalars); this.indexes = new HashMap<>(other.indexesByIdentifier); } public Builder(TableRef tableRef, String identifier, int expectedColumns, int expectedIndexes) { this.tableRef = tableRef; this.identifier = identifier; this.fields = new HashMap<>(expectedColumns); this.scalars = new EnumMap<>(FieldType.class); this.indexes = new HashMap<>(expectedIndexes); } public Builder put(ImmutableMetaField column) { Preconditions.checkState(!built, "This builder has already been built"); fields.put(column.getIdentifier(), column); return this; } public Builder put(ImmutableMetaScalar scalar) { scalars.put(scalar.getType(), scalar); return this; } public Builder put(ImmutableMetaIdentifiedDocPartIndex.Builder indexBuilder) { return put(indexBuilder.build()); } public Builder put(ImmutableMetaIdentifiedDocPartIndex index) { Preconditions.checkState(!built, "This builder has already been built"); indexes.put(index.getIdentifier(), index); return this; } public Builder putField(String name, String identifier, FieldType type) { return put(new ImmutableMetaField(name, identifier, type)); } public Builder putScalar(FieldType type, String identifier) { scalars.put(type, new ImmutableMetaScalar(identifier, type)); return this; } public Builder remove(MetaIdentifiedDocPartIndex index) { Preconditions.checkState(!built, "This builder has already been built"); indexes.remove(index.getIdentifier()); return this; } public ImmutableMetaDocPart build() { Preconditions.checkState(!built, "This builder has already been built"); built = true; return new ImmutableMetaDocPart(tableRef, identifier, fields, scalars, indexes); } } }