Writing Composite Columns with from Java
Posted on August 29th, 2011
Composite columns allow a list of types to be packed into single column. One of the benefits of composites is they also sort properly with respect to multiple components. While higher level clients like Hector and Pycasa already have support for composite columns, support may not yet be in place for the particular client you are using. This recipe shows a simple way to write a Composite Column from java. Since this program uses only simple byte arrays it should be easy to port this program to another programming language.
The best source of documentation for Composite Columns sits directly in the Cassandra code at ./src/java/org/apache/cassandra/db/marshal/CompositeType.java
/*
* The encoding of a CompositeType column name should be:
* <component><component><component> …
* where <component> is:
* <length of value><value><’end-of-component’ byte>
* where <length of value> is a 2 bytes unsigned short the and the
* ‘end-of-component’ byte should always be 0 for actual column name.
*/
How to do it…
Create a file CompositeTool.java.
import java.io.ByteArrayOutputStream; import java.util.List;
public class CompositeTool {
public static byte [] makeComposite(List<byte []> b){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int i=0;i<b.size() ;i++){
bos.write( (byte) ((b.get(i).length >> (7+1) ) & 0xFF)) ;
bos.write( (byte) (b.get(i).length & 0xFF)) ;
for (int j=0;j<b.get(i).length;j++){
bos.write( b.get(i)[j] & 0xFF) ;
}
bos.write((byte)0);
}
return bos.toByteArray();
}
}
Also create CompositeToolTest.java.
package casbase;
import org.apache.cassandra.thrift.Column; import org.apache.cassandra.thrift.ColumnParent; import java.util.List; import java.util.ArrayList; import org.apache.cassandra.thrift.Compression; import java.nio.ByteBuffer; import org.apache.cassandra.thrift.ConsistencyLevel; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*;
public class CompositeToolTest {
public CompositeToolTest() {
}
/* We uesd CQL to create the required keyspaces and column families for this test */
@BeforeClass
public static void setUpClass() throws Exception {
ConnWrapper cw = dbTest.getClient();
cw.getClient().execute_cql_query(
ByteBuffer.wrap(("create keyspace composite_test with strategy_class "
+ "= 'org.apache.cassandra.locator.SimpleStrategy' and strategy_options:replication_factor=1").getBytes()), Compression.NONE);
cw.getClient().execute_cql_query(
ByteBuffer.wrap("USE composite_test".getBytes()), Compression.NONE);
cw.getClient().execute_cql_query(
ByteBuffer.wrap(("create columnfamily composite_test (key bytea primary key) "
+ "with comparator = 'CompositeType(AsciiType,AsciiType)'").getBytes()), Compression.NONE);
}
@AfterClass
public static void tearDownClass() throws Exception {
ConnWrapper cw = dbTest.getClient();
/*
* comments are in place so the CLI can be used to view the column
* remove to make unit tests repeatable
try {
cw.getClient().execute_cql_query(ByteBuffer.wrap
("drop keyspace composite_test".getBytes()), Compression.NONE);
} catch (Exception ex) {
}
*
*/
}
@Test
public void testAgain() throws Exception {
List<byte[]> b = new ArrayList<byte[]>();
b.add("hello".getBytes());
b.add("goodbye".getBytes());
byte[] x = CompositeTool.makeComposite(b);
ConnWrapper cw = dbTest.getClient();
cw.getClient().set_keyspace("composite_test");
ColumnParent cp = new ColumnParent("composite_test");
Column c = new Column();
c.setName(x);
c.setValue("again".getBytes());
c.setTimestamp(System.currentTimeMillis());
cw.getClient().insert(ByteBuffer.wrap("data".getBytes()), cp, c, ConsistencyLevel.ONE);
}
}
Use the cli to ensure the composite column is set correctly.
[default@composite_test] use composite_test;
[default@composite_test] list composite_test;
Using default limit of 100
——————-
RowKey: 64617461
=> (column=hello:goodbye, value=again, timestamp=1314636481883)
1 Row Returned.
How it works…
Compsite columns have a simple format however many of the higher level clients deceptively wrap code in abstraction. As our example shows writing to a composite column is relatively easy.
There is more…
thanks thobbs and pcmanus
Filed under Chapter 9 Coding and Internals, Uncategorized |
Leave a Reply
You must be logged in to post a comment.