| /* |
| * 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.cassandra.db; |
| |
| import java.io.DataInput; |
| import java.io.DataOutput; |
| import java.io.IOException; |
| import java.util.UUID; |
| |
| import org.apache.cassandra.config.Schema; |
| import org.apache.cassandra.io.ISSTableSerializer; |
| import org.apache.cassandra.io.IVersionedSerializer; |
| import org.apache.cassandra.io.sstable.Descriptor; |
| import org.apache.cassandra.io.util.DataOutputPlus; |
| import org.apache.cassandra.net.MessagingService; |
| import org.apache.cassandra.utils.UUIDSerializer; |
| |
| public class ColumnFamilySerializer implements IVersionedSerializer<ColumnFamily>, ISSTableSerializer<ColumnFamily> |
| { |
| /* |
| * Serialized ColumnFamily format: |
| * |
| * [serialized for intra-node writes only, e.g. returning a query result] |
| * <cf nullability boolean: false if the cf is null> |
| * <cf id> |
| * |
| * [in sstable only] |
| * <column bloom filter> |
| * <sparse column index, start/finish columns every ColumnIndexSizeInKB of data> |
| * |
| * [always present] |
| * <local deletion time> |
| * <client-provided deletion time> |
| * <column count> |
| * <columns, serialized individually> |
| */ |
| public void serialize(ColumnFamily cf, DataOutputPlus out, int version) |
| { |
| try |
| { |
| if (cf == null) |
| { |
| out.writeBoolean(false); |
| return; |
| } |
| |
| out.writeBoolean(true); |
| serializeCfId(cf.id(), out, version); |
| cf.getComparator().deletionInfoSerializer().serialize(cf.deletionInfo(), out, version); |
| ColumnSerializer columnSerializer = cf.getComparator().columnSerializer(); |
| int count = cf.getColumnCount(); |
| out.writeInt(count); |
| int written = 0; |
| for (Cell cell : cf) |
| { |
| columnSerializer.serialize(cell, out); |
| written++; |
| } |
| assert count == written: "Column family had " + count + " columns, but " + written + " written"; |
| } |
| catch (IOException e) |
| { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| public ColumnFamily deserialize(DataInput in, int version) throws IOException |
| { |
| return deserialize(in, ColumnSerializer.Flag.LOCAL, version); |
| } |
| |
| public ColumnFamily deserialize(DataInput in, ColumnSerializer.Flag flag, int version) throws IOException |
| { |
| return deserialize(in, ArrayBackedSortedColumns.factory, flag, version); |
| } |
| |
| public ColumnFamily deserialize(DataInput in, ColumnFamily.Factory factory, ColumnSerializer.Flag flag, int version) throws IOException |
| { |
| if (!in.readBoolean()) |
| return null; |
| |
| ColumnFamily cf = factory.create(Schema.instance.getCFMetaData(deserializeCfId(in, version))); |
| |
| if (cf.metadata().isSuper() && version < MessagingService.VERSION_20) |
| { |
| SuperColumns.deserializerSuperColumnFamily(in, cf, flag, version); |
| } |
| else |
| { |
| cf.delete(cf.getComparator().deletionInfoSerializer().deserialize(in, version)); |
| |
| ColumnSerializer columnSerializer = cf.getComparator().columnSerializer(); |
| int size = in.readInt(); |
| for (int i = 0; i < size; ++i) |
| cf.addColumn(columnSerializer.deserialize(in, flag)); |
| } |
| return cf; |
| } |
| |
| public long contentSerializedSize(ColumnFamily cf, TypeSizes typeSizes, int version) |
| { |
| long size = cf.getComparator().deletionInfoSerializer().serializedSize(cf.deletionInfo(), typeSizes, version); |
| size += typeSizes.sizeof(cf.getColumnCount()); |
| ColumnSerializer columnSerializer = cf.getComparator().columnSerializer(); |
| for (Cell cell : cf) |
| size += columnSerializer.serializedSize(cell, typeSizes); |
| return size; |
| } |
| |
| public long serializedSize(ColumnFamily cf, TypeSizes typeSizes, int version) |
| { |
| if (cf == null) |
| { |
| return typeSizes.sizeof(false); |
| } |
| else |
| { |
| return typeSizes.sizeof(true) /* nullness bool */ |
| + cfIdSerializedSize(cf.id(), typeSizes, version) /* id */ |
| + contentSerializedSize(cf, typeSizes, version); |
| } |
| } |
| |
| public long serializedSize(ColumnFamily cf, int version) |
| { |
| return serializedSize(cf, TypeSizes.NATIVE, version); |
| } |
| |
| public void serializeForSSTable(ColumnFamily cf, DataOutputPlus out) |
| { |
| // Column families shouldn't be written directly to disk, use ColumnIndex.Builder instead |
| throw new UnsupportedOperationException(); |
| } |
| |
| public ColumnFamily deserializeFromSSTable(DataInput in, Descriptor.Version version) |
| { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void serializeCfId(UUID cfId, DataOutputPlus out, int version) throws IOException |
| { |
| UUIDSerializer.serializer.serialize(cfId, out, version); |
| } |
| |
| public UUID deserializeCfId(DataInput in, int version) throws IOException |
| { |
| UUID cfId = UUIDSerializer.serializer.deserialize(in, version); |
| if (Schema.instance.getCF(cfId) == null) |
| throw new UnknownColumnFamilyException("Couldn't find cfId=" + cfId, cfId); |
| |
| return cfId; |
| } |
| |
| public int cfIdSerializedSize(UUID cfId, TypeSizes typeSizes, int version) |
| { |
| return typeSizes.sizeof(cfId); |
| } |
| } |