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

com.apple.foundationdb.record.provider.common.RecordSerializer Maven / Gradle / Ivy

There is a newer version: 2.8.110.0
Show newest version
/*
 * RecordSerializer.java
 *
 * This source file is part of the FoundationDB open source project
 *
 * Copyright 2015-2018 Apple Inc. and the FoundationDB project authors
 *
 * 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 com.apple.foundationdb.record.provider.common;

import com.apple.foundationdb.annotation.API;
import com.apple.foundationdb.record.RecordMetaData;
import com.apple.foundationdb.record.metadata.RecordType;
import com.apple.foundationdb.tuple.Tuple;
import com.google.protobuf.Message;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * A converter between a Protobuf record and a byte string stored in one or more values in the FDB key-value store.
 * @param  type used to represent stored records
 */
@API(API.Status.MAINTAINED)
public interface RecordSerializer {

    /**
     * Convert a Protobuf record to bytes. While Protobuf messages provide
     * their own {@link Message#toByteArray()} method for serialization,
     * record stores may elect to first wrap the raw Protobuf record in another
     * wrapping type or perform additional transformations like encrypt or
     * compress records. Implementors of this interface can control how
     * exactly which transformations are done, with the main constraint being
     * that whatever operation is done should be reversible by calling the
     * {@link #deserialize(RecordMetaData, Tuple, byte[], StoreTimer) deserialize()}
     * method on those bytes. Implementors should also be careful as they
     * evolve this method that the deserialize method is still able
     * to read older data unless they are certain that any record store that
     * used the older implementation has since been cleared out or migrated
     * to a newer format.
     *
     * @param metaData the store's meta-data
     * @param recordType the record type of the message
     * @param record the Protobuf record to serialize
     * @param timer a timer used to instrument serialization
     * @return the serialized record
     */
    @Nonnull
    byte[] serialize(@Nonnull RecordMetaData metaData, @Nonnull RecordType recordType,
                     @Nonnull M record, @Nullable StoreTimer timer);

    /**
     * Convert a byte array to a Protobuf record. This should be the inverse of the
     * {@link #serialize(RecordMetaData, RecordType, Message, StoreTimer) serialize()}
     * method.
     *
     * @param metaData the store's meta-data
     * @param primaryKey the primary key of the record
     * @param serialized the serialized bytes
     * @param timer a timer used to instrument deserialization
     * @return the deserialized record
     */
    @Nonnull
    M deserialize(@Nonnull RecordMetaData metaData, @Nonnull Tuple primaryKey,
                  @Nonnull byte[] serialized, @Nullable StoreTimer timer);

    /**
     * Convert this typed record serializer to an untyped one.
     *
     * 
    *
  • If this serializer wraps another serializer, for example, because it does compressions, then * {@code widen} that serializer and return the result wrapped equivalently.
  • *
  • If this serializer parses messages in a type-sensitive way, return the closest general purpose way.
  • *
  • If this serializer is inherently bound to its type parameter, throw an exception.
  • *
* *

* If a {@link com.apple.foundationdb.record.provider.foundationdb.FDBTypedRecordStore} is created without calling * {@link com.apple.foundationdb.record.provider.foundationdb.FDBTypedRecordStore.Builder#setUntypedSerializer}, then * in order to make the untyped record store that is paired with the typed store (used, for instance, to rebuild indexes), * the given typed serializer will be widened by calling this method. * @return a new serializer that works the same way but handles all record types. */ @Nonnull RecordSerializer widen(); /** * Instrumentation events related to record serialization. */ @API(API.Status.UNSTABLE) enum Events implements StoreTimer.DetailEvent { /** The amount of time spent serializing a Protobuf record to bytes. */ SERIALIZE_PROTOBUF_RECORD("serialize protobuf record"), /** The amount of time spent deserializing a Protobuf record from bytes. */ DESERIALIZE_PROTOBUF_RECORD("deserialize protobuf record"), /** The amount of time spent compressing serialized bytes. */ COMPRESS_SERIALIZED_RECORD("compress serialized record"), /** The amount of time spent decompressing serialized bytes. */ DECOMPRESS_SERIALIZED_RECORD("decompress serialized record"), /** The amount of time spent encrypting serialized bytes. */ ENCRYPT_SERIALIZED_RECORD("encrypt serialized record"), /** The amount of time spent decrypting serialized bytes. */ DECRYPT_SERIALIZED_RECORD("decrypt serialized record"); private final String title; private final String logKey; Events(String title, String logKey) { this.title = title; this.logKey = (logKey != null) ? logKey : StoreTimer.DetailEvent.super.logKey(); } Events(String title) { this(title, null); } @Override public String title() { return title; } @Override @Nonnull public String logKey() { return this.logKey; } } /** * Instrumentation counts related to record serialization. */ @API(API.Status.UNSTABLE) enum Counts implements StoreTimer.Count { /** The number of times that record compression was not effective and the record was kept uncompressed. */ ESCHEW_RECORD_COMPRESSION("eschew record compression"); private final String title; private final boolean isSize; private final String logKey; Counts(String title, boolean isSize, String logKey) { this.title = title; this.isSize = false; this.logKey = (logKey != null) ? logKey : StoreTimer.Count.super.logKey(); } Counts(String title, boolean isSize) { this(title, isSize, null); } Counts(String title) { this(title, false, null); } @Override public String title() { return title; } @Override @Nonnull public String logKey() { return this.logKey; } @Override public boolean isSize() { return isSize; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy