package com.facebook.infrastructure.db;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.DataInputStream;
import java.util.Collection;
public class ColumnFamilySerializer implements ICompactSerializer2<ColumnFamily>
{
/*
* We are going to create indexes, and write out that information as well. The format
* of the data serialized is as follows.
*
* 1) Without indexes:
* // written by the data
* <boolean false (index is not present)>
* <column family id>
* <is marked for delete>
* <total number of columns>
* <columns data>
* <boolean true (index is present)>
*
* This part is written by the column indexer
* <size of index in bytes>
* <list of column names and their offsets relative to the first column>
*
* <size of the cf in bytes>
* <column family id>
* <is marked for delete>
* <total number of columns>
* <columns data>
*/
public void serialize(ColumnFamily columnFamily, DataOutputStream dos) throws IOException
{
Collection<IColumn> columns = columnFamily.getAllColumns();
/* write the column family id */
dos.writeUTF(columnFamily.name());
/* write if this cf is marked for delete */
dos.writeLong(columnFamily.getMarkedForDeleteAt());
/* write the size is the number of columns */
dos.writeInt(columns.size());
/* write the column data */
for ( IColumn column : columns )
{
columnFamily.getColumnSerializer().serialize(column, dos);
}
}
/*
* Use this method to create a bare bones Column Family. This column family
* does not have any of the Column information.
*/
private ColumnFamily defreezeColumnFamily(DataInputStream dis) throws IOException
{
String name = dis.readUTF();
ColumnFamily cf = new ColumnFamily(name);
cf.delete(dis.readLong());
return cf;
}
public ColumnFamily deserialize(DataInputStream dis) throws IOException
{
if ( dis.available() == 0 )
return null;
ColumnFamily cf = defreezeColumnFamily(dis);
int size = dis.readInt();
IColumn column = null;
for ( int i = 0; i < size; ++i )
{
column = cf.getColumnSerializer().deserialize(dis);
if(column != null)
{
cf.addColumn(column);
}
}
return cf;
}
/*
* This version of deserialize is used when we need a specific set if columns for
* a column family specified in the name cfName parameter.
*/
public ColumnFamily deserialize(DataInputStream dis, IFilter filter) throws IOException
{
if ( dis.available() == 0 )
return null;
ColumnFamily cf = defreezeColumnFamily(dis);
int size = dis.readInt();
IColumn column = null;
for ( int i = 0; i < size; ++i )
{
column = cf.getColumnSerializer().deserialize(dis, filter);
if(column != null)
{
cf.addColumn(column);
column = null;
if(filter.isDone())
{
break;
}
}
}
return cf;
}
/*
* Deserialize a particular column or super column or the entire columnfamily given a : seprated name
* name could be of the form cf:superColumn:column or cf:column or cf
*/
public ColumnFamily deserialize(DataInputStream dis, String name, IFilter filter) throws IOException
{
if ( dis.available() == 0 )
return null;
String[] names = RowMutation.getColumnAndColumnFamily(name);
String columnName = "";
if ( names.length == 1 )
return deserialize(dis, filter);
if( names.length == 2 )
columnName = names[1];
if( names.length == 3 )
columnName = names[1]+ ":" + names[2];
ColumnFamily cf = defreezeColumnFamily(dis);
/* read the number of columns */
int size = dis.readInt();
for ( int i = 0; i < size; ++i )
{
IColumn column = cf.getColumnSerializer().deserialize(dis, columnName, filter);
if ( column != null )
{
cf.addColumn(column);
break;
}
}
return cf;
}
public void skip(DataInputStream dis) throws IOException
{
throw new UnsupportedOperationException("This operation is not yet supported.");
}
}