/* * Copyright © 2015 Cask Data, Inc. * * Licensed 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 co.cask.cdap.data2.metadata.dataset; import co.cask.cdap.data2.dataset2.lib.table.MDSKey; import co.cask.cdap.proto.Id; import java.util.Arrays; import javax.annotation.Nullable; /** * Key used to store metadata values and indexes. */ final class MdsKey { private static final byte[] VALUE_ROW_PREFIX = {'v'}; // value row prefix to store metadata value private static final byte[] INDEX_ROW_PREFIX = {'i'}; // index row prefix used for metadata search static String getMetadataKey(String type, byte[] rowKey) { MDSKey.Splitter keySplitter = new MDSKey(rowKey).split(); // The rowkey is // [rowPrefix][targetType][targetId][key] for value rows and // [rowPrefix][targetType][targetId][key][index] for value index rows // so skip the first few strings. // Skip rowType keySplitter.skipBytes(); // Skip targetType keySplitter.skipString(); // Skip targetId if (type.equals(Id.Program.class.getSimpleName())) { keySplitter.skipString(); keySplitter.skipString(); keySplitter.skipString(); keySplitter.skipString(); } else if (type.equals(Id.Application.class.getSimpleName())) { keySplitter.skipString(); keySplitter.skipString(); } else if (type.equals(Id.DatasetInstance.class.getSimpleName())) { keySplitter.skipString(); keySplitter.skipString(); } else if (type.equals(Id.Stream.class.getSimpleName())) { keySplitter.skipString(); keySplitter.skipString(); } else if (type.equals(Id.Stream.View.class.getSimpleName())) { // skip namespace, stream, view keySplitter.skipString(); keySplitter.skipString(); keySplitter.skipString(); } else if (type.equals(Id.Artifact.class.getSimpleName())) { // skip namespace, name, version keySplitter.skipString(); keySplitter.skipString(); keySplitter.skipString(); } else { throw new IllegalArgumentException("Illegal Type " + type + " of metadata source."); } return keySplitter.getString(); } static String getTargetType(byte[] rowKey) { MDSKey.Splitter keySplitter = new MDSKey(rowKey).split(); // The rowkey is // [rowPrefix][targetType][targetId][key] for value rows and // [rowPrefix][targetType][targetId][key][index] for value index rows keySplitter.getBytes(); return keySplitter.getString(); } /** * Creates a key for metadata value row in the format: * [{@link #VALUE_ROW_PREFIX}][targetType][targetId][key] for value index rows */ static MDSKey getMDSValueKey(Id.NamespacedId targetId, @Nullable String key) { MDSKey.Builder builder = getMDSKeyPrefix(targetId, VALUE_ROW_PREFIX); if (key != null) { builder.add(key); } return builder.build(); } /** * Creates a key for metadata index row in the format: * [{@link #INDEX_ROW_PREFIX}][targetType][targetId][key][index] for value index rows */ static MDSKey getMDSIndexKey(Id.NamespacedId targetId, String key, @Nullable String index) { MDSKey.Builder builder = getMDSKeyPrefix(targetId, INDEX_ROW_PREFIX); builder.add(key); if (index != null) { builder.add(index); } return builder.build(); } static Id.NamespacedId getNamespacedIdFromKey(String type, byte[] rowKey) { MDSKey.Splitter keySplitter = new MDSKey(rowKey).split(); // The rowkey is // [rowPrefix][targetType][targetId][key] for value rows and // [rowPrefix][targetType][targetId][key][index] for value index rows // so skip the first two. keySplitter.skipBytes(); keySplitter.skipString(); return KeyHelper.getTargetIdIdFromKey(keySplitter, type); } static String getNamespaceId(MDSKey key) { MDSKey.Splitter keySplitter = key.split(); // The rowkey is // [rowPrefix][targetType][targetId][key] for value rows and // [rowPrefix][targetType][targetId][key][index] for value index rows // so skip the first two. keySplitter.skipBytes(); keySplitter.skipString(); // We are getting the first part of [targetId] which always be the namespace id. return keySplitter.getString(); } static byte[] getValueRowPrefix() { MDSKey key = new MDSKey.Builder().add(MdsKey.VALUE_ROW_PREFIX).build(); return key.getKey(); } static byte[] getIndexRowPrefix() { MDSKey key = new MDSKey.Builder().add(MdsKey.INDEX_ROW_PREFIX).build(); return key.getKey(); } private static MDSKey.Builder getMDSKeyPrefix(Id.NamespacedId targetId, byte[] rowPrefix) { String targetType = KeyHelper.getTargetType(targetId); MDSKey.Builder builder = new MDSKey.Builder(); builder.add(rowPrefix); builder.add(targetType); KeyHelper.addTargetIdToKey(builder, targetId); return builder; } private MdsKey() { } }