blob: 0e9c987b970fccdf8adb205cb593a94aca29d946 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.apache.hugegraph.backend.serializer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.hugegraph.backend.id.Id;
import org.apache.hugegraph.backend.store.BackendEntry;
import org.apache.hugegraph.type.HugeType;
import org.apache.hugegraph.type.define.Cardinality;
import org.apache.hugegraph.type.define.HugeKeys;
public class TableBackendEntry implements BackendEntry {
public static class Row {
private HugeType type;
private Id id;
private Id subId;
private final Map<HugeKeys, Object> columns;
private long ttl;
public Row(HugeType type) {
this(type, null);
}
public Row(HugeType type, Id id) {
this.type = type;
this.id = id;
this.subId = null;
this.columns = new ConcurrentHashMap<>();
this.ttl = 0L;
}
public HugeType type() {
return this.type;
}
public Id id() {
return this.id;
}
public Map<HugeKeys, Object> columns() {
return this.columns;
}
@SuppressWarnings("unchecked")
public <T> T column(HugeKeys key) {
// The T must be primitive type, or list/set/map of primitive type
return (T) this.columns.get(key);
}
public <T> void column(HugeKeys key, T value) {
this.columns.put(key, value);
}
public <T> void column(HugeKeys key, T value, Cardinality c) {
switch (c) {
case SINGLE:
this.column(key, value);
break;
case SET:
// Avoid creating new Set when the key exists
if (!this.columns.containsKey(key)) {
this.columns.putIfAbsent(key, new LinkedHashSet<>());
}
this.<Set<T>>column(key).add(value);
break;
case LIST:
// Avoid creating new List when the key exists
if (!this.columns.containsKey(key)) {
this.columns.putIfAbsent(key, new LinkedList<>());
}
this.<List<T>>column(key).add(value);
break;
default:
throw new AssertionError("Unsupported cardinality: " + c);
}
}
public <T> void column(HugeKeys key, Object name, T value) {
if (!this.columns.containsKey(key)) {
this.columns.putIfAbsent(key, new ConcurrentHashMap<>());
}
this.<Map<Object, T>>column(key).put(name, value);
}
public void ttl(long ttl) {
this.ttl = ttl;
}
public long ttl() {
return this.ttl;
}
@Override
public String toString() {
return String.format("Row{type=%s, id=%s, columns=%s}",
this.type, this.id, this.columns);
}
}
private final Row row;
private final List<Row> subRows;
// NOTE: selfChanged is false when the row has not changed but subRows has.
private boolean selfChanged;
private boolean olap;
public TableBackendEntry(Id id) {
this(null, id);
}
public TableBackendEntry(HugeType type) {
this(type, null);
}
public TableBackendEntry(HugeType type, Id id) {
this(new Row(type, id));
}
public TableBackendEntry(Row row) {
this.row = row;
this.subRows = new ArrayList<>();
this.selfChanged = true;
this.olap = false;
}
@Override
public HugeType type() {
return this.row.type;
}
public void type(HugeType type) {
this.row.type = type;
}
@Override
public Id id() {
return this.row.id;
}
@Override
public Id originId() {
return this.row.id;
}
public void id(Id id) {
this.row.id = id;
}
@Override
public Id subId() {
return this.row.subId;
}
public void subId(Id subId) {
this.row.subId = subId;
}
public void selfChanged(boolean changed) {
this.selfChanged = changed;
}
public boolean selfChanged() {
return this.selfChanged;
}
public void olap(boolean olap) {
this.olap = olap;
}
@Override
public boolean olap() {
return this.olap;
}
public Row row() {
return this.row;
}
public Map<HugeKeys, Object> columnsMap() {
return this.row.columns();
}
public <T> void column(HugeKeys key, T value) {
this.row.column(key, value);
}
public <T> void column(HugeKeys key, Object name, T value) {
this.row.column(key, name, value);
}
public <T> void column(HugeKeys key, T value, Cardinality c) {
this.row.column(key, value, c);
}
public <T> T column(HugeKeys key) {
return this.row.column(key);
}
public void subRow(Row row) {
this.subRows.add(row);
}
public List<Row> subRows() {
return this.subRows;
}
public void ttl(long ttl) {
this.row.ttl(ttl);
}
@Override
public long ttl() {
return this.row.ttl();
}
@Override
public String toString() {
return String.format("TableBackendEntry{%s, sub-rows: %s}",
this.row.toString(),
this.subRows.toString());
}
@Override
public int columnsSize() {
throw new NotImplementedException("Not supported by table backend");
}
@Override
public Collection<BackendEntry.BackendColumn> columns() {
throw new NotImplementedException("Not supported by table backend");
}
@Override
public void columns(Collection<BackendEntry.BackendColumn> bytesColumns) {
throw new NotImplementedException("Not supported by table backend");
}
@Override
public void columns(BackendEntry.BackendColumn bytesColumn) {
throw new NotImplementedException("Not supported by table backend");
}
@Override
public void merge(BackendEntry other) {
throw new NotImplementedException("Not supported by table backend");
}
@Override
public boolean mergeable(BackendEntry other) {
if (!(other instanceof TableBackendEntry)) {
return false;
}
TableBackendEntry tableEntry = (TableBackendEntry) other;
Object selfId = this.column(HugeKeys.ID);
Object otherId = tableEntry.column(HugeKeys.ID);
if (!selfId.equals(otherId)) {
return false;
}
Id key = tableEntry.subId();
Object value = tableEntry.row().column(HugeKeys.PROPERTY_VALUE);
this.row().column(HugeKeys.PROPERTIES, key.asLong(), value);
return true;
}
@Override
public void clear() {
throw new NotImplementedException("Not supported by table backend");
}
}