mirror of https://github.com/apache/cassandra
merge from 0.6
git-svn-id: https://svn.apache.org/repos/asf/cassandra/trunk@942217 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ff59b8ebda
commit
14bdc6570d
|
|
@ -35,6 +35,7 @@ dev
|
|||
* make concurrent_reads, concurrent_writes configurable at runtime via JMX
|
||||
(CASSANDRA-1060)
|
||||
* disable GCInspector on non-Sun JVMs (CASSANDRA-1061)
|
||||
* fix tombstone handling in sstable rows with no other data (CASSANDRA-1063)
|
||||
|
||||
|
||||
0.6.1
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ and the data model from Google's BigTable. Like Dynamo, Cassandra is
|
|||
eventually consistent. Like BigTable, Cassandra provides a ColumnFamily-based
|
||||
data model richer than typical key/value systems.
|
||||
|
||||
For more information see http://incubator.apache.org/cassandra
|
||||
For more information see http://cassandra.apache.org/
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
|
@ -22,8 +22,8 @@ Getting started
|
|||
This short guide will walk you through getting a basic one node cluster up
|
||||
and running, and demonstrate some simple reads and writes.
|
||||
|
||||
* tar -zxvf cassandra-$VERSION.tgz
|
||||
* cd cassandra-$VERSION
|
||||
* tar -zxvf apache-cassandra-$VERSION.tar.gz
|
||||
* cd apache-cassandra-$VERSION
|
||||
* sudo mkdir -p /var/log/cassandra
|
||||
* sudo chown -R `whoami` /var/log/cassandra
|
||||
* sudo mkdir -p /var/lib/cassandra
|
||||
|
|
@ -94,7 +94,7 @@ Wondering where to go from here?
|
|||
best source for additional information.
|
||||
* Join us in #cassandra on irc.freenode.net and ask questions.
|
||||
* Subscribe to the Users mailing list by sending a mail to
|
||||
cassandra-user-subscribe@incubator.apache.org
|
||||
user-subscribe@cassandra.apache.org
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -808,18 +808,15 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean
|
|||
for (SSTableReader sstable : ssTables_)
|
||||
{
|
||||
iter = filter.getSSTableColumnIterator(sstable);
|
||||
if (iter.hasNext()) // initializes iter.CF
|
||||
if (iter.getColumnFamily() != null)
|
||||
{
|
||||
returnCF.delete(iter.getColumnFamily());
|
||||
iterators.add(iter);
|
||||
}
|
||||
iterators.add(iter);
|
||||
}
|
||||
|
||||
Comparator<IColumn> comparator = QueryFilter.getColumnComparator(getComparator());
|
||||
Iterator collated = IteratorUtils.collatedIterator(comparator, iterators);
|
||||
if (!collated.hasNext())
|
||||
return null;
|
||||
|
||||
filter.collectCollatedColumns(returnCF, collated, gcBefore);
|
||||
return returnCF; // caller is responsible for final removeDeleted
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ public class SSTableNamesIterator extends SimpleAbstractColumnIterator implement
|
|||
this.columns = columnNames;
|
||||
this.decoratedKey = key;
|
||||
|
||||
// open the sstable file, if we don't have one passed to use from range scan
|
||||
if (file == null)
|
||||
{
|
||||
try
|
||||
|
|
@ -78,19 +79,69 @@ public class SSTableNamesIterator extends SimpleAbstractColumnIterator implement
|
|||
}
|
||||
}
|
||||
|
||||
// read the requested columns into `cf`
|
||||
try
|
||||
{
|
||||
List<byte[]> filteredColumnNames = getFilteredColumns(file, columnNames);
|
||||
/* Read the bloom filter summarizing the columns */
|
||||
BloomFilter bf = IndexHelper.defreezeBloomFilter(file);
|
||||
List<IndexHelper.IndexInfo> indexList = IndexHelper.deserializeIndex(file);
|
||||
|
||||
// we can stop early if bloom filter says none of the columns actually exist -- but,
|
||||
// we can't stop before initializing the cf above, in case there's a relevant tombstone
|
||||
cf = ColumnFamily.serializer().deserializeFromSSTableNoColumns(ssTable.makeColumnFamily(), file);
|
||||
|
||||
List<byte[]> filteredColumnNames1 = new ArrayList<byte[]>(columnNames.size());
|
||||
for (byte[] name : columnNames)
|
||||
{
|
||||
if (bf.isPresent(name))
|
||||
{
|
||||
filteredColumnNames1.add(name);
|
||||
}
|
||||
}
|
||||
List<byte[]> filteredColumnNames = filteredColumnNames1;
|
||||
if (filteredColumnNames.isEmpty())
|
||||
return;
|
||||
|
||||
getColumns(ssTable, file, columnNames, filteredColumnNames);
|
||||
file.readInt(); // column count
|
||||
|
||||
/* get the various column ranges we have to read */
|
||||
AbstractType comparator = ssTable.getColumnComparator();
|
||||
SortedSet<IndexHelper.IndexInfo> ranges = new TreeSet<IndexHelper.IndexInfo>(IndexHelper.getComparator(comparator));
|
||||
for (byte[] name : filteredColumnNames)
|
||||
{
|
||||
int index = IndexHelper.indexFor(name, indexList, comparator, false);
|
||||
if (index == indexList.size())
|
||||
continue;
|
||||
IndexHelper.IndexInfo indexInfo = indexList.get(index);
|
||||
if (comparator.compare(name, indexInfo.firstName) < 0)
|
||||
continue;
|
||||
ranges.add(indexInfo);
|
||||
}
|
||||
|
||||
file.mark();
|
||||
for (IndexHelper.IndexInfo indexInfo : ranges)
|
||||
{
|
||||
file.reset();
|
||||
long curOffsert = file.skipBytes((int)indexInfo.offset);
|
||||
assert curOffsert == indexInfo.offset;
|
||||
// TODO only completely deserialize columns we are interested in
|
||||
while (file.bytesPastMark() < indexInfo.offset + indexInfo.width)
|
||||
{
|
||||
final IColumn column = cf.getColumnSerializer().deserialize(file);
|
||||
// we check vs the original Set, not the filtered List, for efficiency
|
||||
if (columnNames.contains(column.name()))
|
||||
{
|
||||
cf.addColumn(column);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IOError(e);
|
||||
}
|
||||
|
||||
|
||||
// create an iterator view of the columns we read
|
||||
iter = cf.getSortedColumns().iterator();
|
||||
}
|
||||
|
||||
|
|
@ -99,76 +150,6 @@ public class SSTableNamesIterator extends SimpleAbstractColumnIterator implement
|
|||
return decoratedKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read in the columns we are looking for
|
||||
* @param ssTable Table to read from
|
||||
* @param file Read from this file
|
||||
* @param columnNames Names of all columns we are looking for
|
||||
* @param filteredColumnNames Names of columns that are thought to exist
|
||||
* @throws IOException
|
||||
*/
|
||||
private void getColumns(SSTableReader ssTable, FileDataInput file, SortedSet<byte[]> columnNames, List<byte[]> filteredColumnNames) throws IOException
|
||||
{
|
||||
List<IndexHelper.IndexInfo> indexList = IndexHelper.deserializeIndex(file);
|
||||
|
||||
cf = ColumnFamily.serializer().deserializeFromSSTableNoColumns(ssTable.makeColumnFamily(), file);
|
||||
file.readInt(); // column count
|
||||
|
||||
/* get the various column ranges we have to read */
|
||||
AbstractType comparator = ssTable.getColumnComparator();
|
||||
SortedSet<IndexHelper.IndexInfo> ranges = new TreeSet<IndexHelper.IndexInfo>(IndexHelper.getComparator(comparator));
|
||||
for (byte[] name : filteredColumnNames)
|
||||
{
|
||||
int index = IndexHelper.indexFor(name, indexList, comparator, false);
|
||||
if (index == indexList.size())
|
||||
continue;
|
||||
IndexHelper.IndexInfo indexInfo = indexList.get(index);
|
||||
if (comparator.compare(name, indexInfo.firstName) < 0)
|
||||
continue;
|
||||
ranges.add(indexInfo);
|
||||
}
|
||||
|
||||
file.mark();
|
||||
for (IndexHelper.IndexInfo indexInfo : ranges)
|
||||
{
|
||||
file.reset();
|
||||
long curOffsert = file.skipBytes((int)indexInfo.offset);
|
||||
assert curOffsert == indexInfo.offset;
|
||||
// TODO only completely deserialize columns we are interested in
|
||||
while (file.bytesPastMark() < indexInfo.offset + indexInfo.width)
|
||||
{
|
||||
final IColumn column = cf.getColumnSerializer().deserialize(file);
|
||||
// we check vs the original Set, not the filtered List, for efficiency
|
||||
if (columnNames.contains(column.name()))
|
||||
{
|
||||
cf.addColumn(column);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the list of column names against the bloom filter
|
||||
* @param file File to read bloom filter from
|
||||
* @param columnNames Column names to filter
|
||||
* @return List of columns that exist in the bloom filter
|
||||
* @throws IOException
|
||||
*/
|
||||
private List<byte[]> getFilteredColumns(FileDataInput file, SortedSet<byte[]> columnNames) throws IOException
|
||||
{
|
||||
/* Read the bloom filter summarizing the columns */
|
||||
BloomFilter bf = IndexHelper.defreezeBloomFilter(file);
|
||||
List<byte[]> filteredColumnNames = new ArrayList<byte[]>(columnNames.size());
|
||||
for (byte[] name : columnNames)
|
||||
{
|
||||
if (bf.isPresent(name))
|
||||
{
|
||||
filteredColumnNames.add(name);
|
||||
}
|
||||
}
|
||||
return filteredColumnNames;
|
||||
}
|
||||
|
||||
public ColumnFamily getColumnFamily()
|
||||
{
|
||||
return cf;
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ class SSTableSliceIterator extends AbstractIterator<IColumn> implements IColumnI
|
|||
|
||||
public ColumnFamily getColumnFamily()
|
||||
{
|
||||
return reader.getEmptyColumnFamily();
|
||||
return reader == null ? null : reader.getEmptyColumnFamily();
|
||||
}
|
||||
|
||||
protected IColumn computeNext()
|
||||
|
|
|
|||
|
|
@ -87,9 +87,14 @@ public class ColumnFamilyStoreTest extends CleanupHelper
|
|||
public void runMayThrow() throws IOException
|
||||
{
|
||||
QueryFilter sliceFilter = QueryFilter.getSliceFilter(Util.dk("key1"), new QueryPath("Standard2", null, null), ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.EMPTY_BYTE_ARRAY, null, false, 1);
|
||||
assertNull(store.getColumnFamily(sliceFilter));
|
||||
ColumnFamily cf = store.getColumnFamily(sliceFilter);
|
||||
assert cf.isMarkedForDelete();
|
||||
assert cf.getColumnsMap().isEmpty();
|
||||
|
||||
QueryFilter namesFilter = QueryFilter.getNamesFilter(Util.dk("key1"), new QueryPath("Standard2", null, null), "a".getBytes());
|
||||
assertNull(store.getColumnFamily(namesFilter));
|
||||
cf = store.getColumnFamily(namesFilter);
|
||||
assert cf.isMarkedForDelete();
|
||||
assert cf.getColumnsMap().isEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue