fix CF.digest NPE. patch by jbellis; reviewed by Eric Evans for CASSANDRA-149

git-svn-id: https://svn.apache.org/repos/asf/incubator/cassandra/trunk@772690 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jonathan Ellis 2009-05-07 16:03:32 +00:00
parent 3395efdb30
commit fb347bd3d1
6 changed files with 66 additions and 51 deletions

View File

@ -32,6 +32,7 @@ import java.util.SortedSet;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Logger;
import org.apache.cassandra.config.DatabaseDescriptor;
@ -399,10 +400,10 @@ public final class ColumnFamily
public byte[] digest()
{
Set<IColumn> columns = columns_.getSortedColumns();
byte[] xorHash = null;
for(IColumn column : columns)
byte[] xorHash = ArrayUtils.EMPTY_BYTE_ARRAY;
for(IColumn column : columns)
{
if(xorHash == null)
if(xorHash.length == 0)
{
xorHash = column.digest();
}

View File

@ -27,6 +27,7 @@ import org.apache.cassandra.io.ICompactSerializer;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.net.MessagingService;
import org.apache.cassandra.service.StorageService;
import org.apache.commons.lang.ArrayUtils;
/*
@ -60,11 +61,12 @@ private static ICompactSerializer<ReadResponse> serializer_;
private String table_;
private Row row_;
private byte[] digest_ = new byte[0];
private byte[] digest_ = ArrayUtils.EMPTY_BYTE_ARRAY;
private boolean isDigestQuery_ = false;
public ReadResponse(String table, byte[] digest )
{
assert digest != null;
table_ = table;
digest_= digest;
}

View File

@ -77,7 +77,7 @@ public class ReadVerbHandler implements IVerbHandler
Row row = null;
row = readCommand.getRow(table);
ReadResponse readResponse = null;
if(readCommand.isDigestQuery())
if (readCommand.isDigestQuery())
{
readResponse = new ReadResponse(table.getTableName(), row.digest());
}

View File

@ -178,12 +178,10 @@ public class Row
}
else
{
byte[] tmpHash = columnFamilies_.get(cFamily).digest();
xorHash = FBUtilities.xor(xorHash, tmpHash);
xorHash = FBUtilities.xor(xorHash, columnFamilies_.get(cFamily).digest());
}
}
logger_.info("DIGEST TIME: " + (System.currentTimeMillis() - start)
+ " ms.");
logger_.info("DIGEST TIME: " + (System.currentTimeMillis() - start) + " ms.");
return xorHash;
}

View File

@ -331,8 +331,10 @@ public class FBUtilities
public static byte[] xor(byte[] b1, byte[] b2)
{
byte[] bLess = null;
byte[] bMore = null;
assert b1 != null;
assert b2 != null;
byte[] bLess;
byte[] bMore;
if(b1.length > b2.length)
{

View File

@ -15,7 +15,8 @@ public class ColumnFamilyTest
// TODO test SuperColumns
@Test
public void testSingleColumn() throws IOException {
public void testSingleColumn() throws IOException
{
Random random = new Random();
byte[] bytes = new byte[1024];
random.nextBytes(bytes);
@ -35,11 +36,12 @@ public class ColumnFamilyTest
}
@Test
public void testManyColumns() throws IOException {
public void testManyColumns() throws IOException
{
ColumnFamily cf;
TreeMap<String, byte[]> map = new TreeMap<String,byte[]>();
for ( int i = 100; i < 1000; ++i )
TreeMap<String, byte[]> map = new TreeMap<String, byte[]>();
for (int i = 100; i < 1000; ++i)
{
map.put(Integer.toString(i), ("Avinash Lakshman is a good man: " + i).getBytes());
}
@ -47,7 +49,7 @@ public class ColumnFamilyTest
// write
cf = new ColumnFamily("Standard1", "Standard");
DataOutputBuffer bufOut = new DataOutputBuffer();
for (String cName: map.navigableKeySet())
for (String cName : map.navigableKeySet())
{
cf.addColumn(cName, map.get(cName), 314);
}
@ -57,60 +59,70 @@ public class ColumnFamilyTest
DataInputBuffer bufIn = new DataInputBuffer();
bufIn.reset(bufOut.getData(), bufOut.getLength());
cf = ColumnFamily.serializer().deserialize(bufIn);
for (String cName: map.navigableKeySet())
for (String cName : map.navigableKeySet())
{
assert Arrays.equals(cf.getColumn(cName).value(), map.get(cName));
}
assert new HashSet<String>(cf.getColumns().keySet()).equals(map.keySet());
}
@Test
public void testGetColumnCount() {
ColumnFamily cf = new ColumnFamily("Standard1", "Standard");
byte val[] = "sample value".getBytes();
cf.addColumn("col1", val, 1);
cf.addColumn("col2", val, 2);
cf.addColumn("col1", val, 3);
assert 2 == cf.getColumnCount();
assert 2 == cf.getAllColumns().size();
}
@Test
public void testTimestamp() {
ColumnFamily cf = new ColumnFamily("Standard1", "Standard");
byte val1[] = "sample 1".getBytes();
public void testGetColumnCount()
{
ColumnFamily cf = new ColumnFamily("Standard1", "Standard");
byte val[] = "sample value".getBytes();
cf.addColumn("col1", val, 1);
cf.addColumn("col2", val, 2);
cf.addColumn("col1", val, 3);
assert 2 == cf.getColumnCount();
assert 2 == cf.getAllColumns().size();
}
@Test
public void testTimestamp()
{
ColumnFamily cf = new ColumnFamily("Standard1", "Standard");
byte val1[] = "sample 1".getBytes();
byte val2[] = "sample 2".getBytes();
byte val3[] = "sample 3".getBytes();
cf.addColumn("col1", val1, 2);
cf.addColumn("col1", val1, 2);
cf.addColumn("col1", val2, 2); // same timestamp, new value
cf.addColumn("col1", val3, 1); // older timestamp -- should be ignored
assert Arrays.equals(val2, cf.getColumn("col1").value());
}
@Test
public void testMergeAndAdd(){
ColumnFamily cf_new = new ColumnFamily("Standard1", "Standard");
ColumnFamily cf_old = new ColumnFamily("Standard1", "Standard");
ColumnFamily cf_result = new ColumnFamily("Standard1", "Standard");
byte val[] = "sample value".getBytes();
byte val2[] = "x value ".getBytes();
cf_new.addColumn("col1", val, 3);
cf_new.addColumn("col2", val, 4);
public void testMergeAndAdd()
{
ColumnFamily cf_new = new ColumnFamily("Standard1", "Standard");
ColumnFamily cf_old = new ColumnFamily("Standard1", "Standard");
ColumnFamily cf_result = new ColumnFamily("Standard1", "Standard");
byte val[] = "sample value".getBytes();
byte val2[] = "x value ".getBytes();
cf_old.addColumn("col2", val2, 1);
cf_old.addColumn("col3", val2, 2);
cf_new.addColumn("col1", val, 3);
cf_new.addColumn("col2", val, 4);
cf_result.addColumns(cf_new);
cf_result.addColumns(cf_old);
assert 3 == cf_result.getColumnCount() : "Count is " + cf_new.getColumnCount();
//addcolumns will only add if timestamp >= old timestamp
cf_old.addColumn("col2", val2, 1);
cf_old.addColumn("col3", val2, 2);
cf_result.addColumns(cf_new);
cf_result.addColumns(cf_old);
assert 3 == cf_result.getColumnCount() : "Count is " + cf_new.getColumnCount();
//addcolumns will only add if timestamp >= old timestamp
assert Arrays.equals(val, cf_result.getColumn("col2").value());
}
@Test
public void testEmptyDigest()
{
ColumnFamily cf = new ColumnFamily("Standard1", "Standard");
assert cf.digest().length == 0;
}
}