You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cassandra.apache.org by Berenguer Blasi <bb...@jblasi.com> on 2014/02/18 12:33:33 UTC
How to iterate IndexCfs
Hi all,
I am new to cassandra and I am trying to solve something I am stuck
with. It is quite easy conceptually but I am stuck with it so maybe
somebody with knowledge of the internals knows what I am doing wrong.
I want to slice the CFs of a secondary index. So you can try with
cfs.getRangeSlice(...) or access the cfs.getSequentialIterator(..). The
problem is no matter what ranges, combinations or methods I can think of
I always hit this exception:
ERROR 12:30:49,416 Exception in thread Thread[ReadStage:2,5,main]
java.lang.RuntimeException: java.lang.ClassCastException:
java.nio.HeapByteBuffer cannot be cast to java.lang.Long
at
org.apache.cassandra.service.StorageProxy$DroppableRunnable.run(StorageProxy.java:1880)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.ClassCastException: java.nio.HeapByteBuffer cannot
be cast to java.lang.Long
at org.apache.cassandra.dht.LongToken.compareTo(LongToken.java:31)
at
org.apache.cassandra.dht.Token$KeyBound.compareTo(Token.java:197)
at org.apache.cassandra.dht.Token$KeyBound.compareTo(Token.java:1)
at
org.apache.cassandra.utils.IntervalTree.comparePoints(IntervalTree.java:191)
at
org.apache.cassandra.utils.IntervalTree.access$2(IntervalTree.java:181)
at
org.apache.cassandra.utils.IntervalTree$IntervalNode.searchInternal(IntervalTree.java:293)
at
org.apache.cassandra.utils.IntervalTree.search(IntervalTree.java:140)
at
org.apache.cassandra.db.ColumnFamilyStore$AbstractViewSSTableFinder.sstablesForRowBounds(ColumnFamilyStore.java:1457)
at
org.apache.cassandra.db.ColumnFamilyStore$7.findSSTables(ColumnFamilyStore.java:1511)
at
org.apache.cassandra.db.ColumnFamilyStore.markReferenced(ColumnFamilyStore.java:1476)
at
org.apache.cassandra.db.ColumnFamilyStore.markReferenced(ColumnFamilyStore.java:1507)
at
org.apache.cassandra.db.ColumnFamilyStore.getSequentialIterator(ColumnFamilyStore.java:1594)
at
org.apache.cassandra.db.index.keys.KeysSearcher$1.computeNext(KeysSearcher.java:125)
at
org.apache.cassandra.db.index.keys.KeysSearcher$1.computeNext(KeysSearcher.java:1)
at
com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143)
at
com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138)
at
org.apache.cassandra.db.ColumnFamilyStore.filter(ColumnFamilyStore.java:1754)
at
org.apache.cassandra.db.index.keys.KeysSearcher.search(KeysSearcher.java:56)
at
org.apache.cassandra.db.index.SecondaryIndexManager.search(SecondaryIndexManager.java:537)
at
org.apache.cassandra.db.ColumnFamilyStore.search(ColumnFamilyStore.java:1742)
at
org.apache.cassandra.db.RangeSliceCommand.executeLocally(RangeSliceCommand.java:135)
at
org.apache.cassandra.service.StorageProxy$LocalRangeSliceRunnable.runMayThrow(StorageProxy.java:1363)
at
org.apache.cassandra.service.StorageProxy$DroppableRunnable.run(StorageProxy.java:1876)
... 3 more
Here he is trying to compare a Long (range is a long) to a
LocalToken(comparator=LongType, token=HeapByteBuffer(=1968)) where my
query was 'select * from users where birth_date>=1968' and birth_date is
a Long.
So it looks almost right as the LocalToken has the LongComparator etc.
but it is failing obviously.
My suspicion is that here we are trying to look for the 1968 parition of
the index, and this 1968 happens to not be a Long which is what range is
providing.
Any clues on what might actually be happening??
Thanks a lot in advance.
Re: getSequentialIterator and ranges
Posted by Jonathan Ellis <jb...@gmail.com>.
Without looking at the code I would expect EMPTY to work for open
bound on both left and right.
If that doesn't work I would set a breakpoint and have a look at what
"SELECT *" gets turned into.
On Tue, Feb 18, 2014 at 11:45 AM, Berenguer Blasi <bb...@jblasi.com> wrote:
> Hi all,
>
> when iterating CFs with getSequentialIterator you have to specify him a
> range. But what do you do when you need to:
>
> A- Scan the full range?
> B- Scan from key X to the end?
>
> Scanning between keys X,Y is easy as you just specify them in the range.
> Scanning up to Y can be done with ByteBufferUtil.EMPTY_BYTE_BUFFER as the
> left limit.
>
> The problem is how to tell him the righ limit is 'open'. An assert will
> prevent it.
>
> I was wondering what is the right way to do that. I am stuck with that and I
> am sure it will be the easiest thing but I can't get round it... This is how
> I am building the range:
>
> Range<RowPosition> myRange =
> new Range<RowPosition>(
> RowPosition.forKey(ByteBufferUtil.EMPTY_BYTE_BUFFER,
> index.getIndexCfs().partitioner),
> RowPosition.forKey(ByteBufferUtil.bytes(1975L),
> index.getIndexCfs().partitioner),
> index.getIndexCfs().partitioner);
>
> Thanks in advance.
--
Jonathan Ellis
Project Chair, Apache Cassandra
co-founder, http://www.datastax.com
@spyced
getSequentialIterator and ranges
Posted by Berenguer Blasi <bb...@jblasi.com>.
Hi all,
when iterating CFs with getSequentialIterator you have to specify him a
range. But what do you do when you need to:
A- Scan the full range?
B- Scan from key X to the end?
Scanning between keys X,Y is easy as you just specify them in the range.
Scanning up to Y can be done with ByteBufferUtil.EMPTY_BYTE_BUFFER as
the left limit.
The problem is how to tell him the righ limit is 'open'. An assert will
prevent it.
I was wondering what is the right way to do that. I am stuck with that
and I am sure it will be the easiest thing but I can't get round it...
This is how I am building the range:
Range<RowPosition> myRange =
new Range<RowPosition>(
RowPosition.forKey(ByteBufferUtil.EMPTY_BYTE_BUFFER,
index.getIndexCfs().partitioner),
RowPosition.forKey(ByteBufferUtil.bytes(1975L),
index.getIndexCfs().partitioner),
index.getIndexCfs().partitioner);
Thanks in advance.
Re: How to iterate IndexCfs
Posted by Jonathan Ellis <jb...@gmail.com>.
Where is your LongToken coming from? LongToken is used by
Murmur3Partitioner; it looks to me like you need to build a LocalToken
instead (for the LocalPartitioner used by indexes).
On Tue, Feb 18, 2014 at 5:33 AM, Berenguer Blasi <bb...@jblasi.com> wrote:
> Hi all,
>
> I am new to cassandra and I am trying to solve something I am stuck with. It
> is quite easy conceptually but I am stuck with it so maybe somebody with
> knowledge of the internals knows what I am doing wrong.
>
> I want to slice the CFs of a secondary index. So you can try with
> cfs.getRangeSlice(...) or access the cfs.getSequentialIterator(..). The
> problem is no matter what ranges, combinations or methods I can think of I
> always hit this exception:
>
> ERROR 12:30:49,416 Exception in thread Thread[ReadStage:2,5,main]
> java.lang.RuntimeException: java.lang.ClassCastException:
> java.nio.HeapByteBuffer cannot be cast to java.lang.Long
> at
> org.apache.cassandra.service.StorageProxy$DroppableRunnable.run(StorageProxy.java:1880)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
> at java.lang.Thread.run(Thread.java:744)
> Caused by: java.lang.ClassCastException: java.nio.HeapByteBuffer cannot be
> cast to java.lang.Long
> at org.apache.cassandra.dht.LongToken.compareTo(LongToken.java:31)
> at org.apache.cassandra.dht.Token$KeyBound.compareTo(Token.java:197)
> at org.apache.cassandra.dht.Token$KeyBound.compareTo(Token.java:1)
> at
> org.apache.cassandra.utils.IntervalTree.comparePoints(IntervalTree.java:191)
> at
> org.apache.cassandra.utils.IntervalTree.access$2(IntervalTree.java:181)
> at
> org.apache.cassandra.utils.IntervalTree$IntervalNode.searchInternal(IntervalTree.java:293)
> at
> org.apache.cassandra.utils.IntervalTree.search(IntervalTree.java:140)
> at
> org.apache.cassandra.db.ColumnFamilyStore$AbstractViewSSTableFinder.sstablesForRowBounds(ColumnFamilyStore.java:1457)
> at
> org.apache.cassandra.db.ColumnFamilyStore$7.findSSTables(ColumnFamilyStore.java:1511)
> at
> org.apache.cassandra.db.ColumnFamilyStore.markReferenced(ColumnFamilyStore.java:1476)
> at
> org.apache.cassandra.db.ColumnFamilyStore.markReferenced(ColumnFamilyStore.java:1507)
> at
> org.apache.cassandra.db.ColumnFamilyStore.getSequentialIterator(ColumnFamilyStore.java:1594)
> at
> org.apache.cassandra.db.index.keys.KeysSearcher$1.computeNext(KeysSearcher.java:125)
> at
> org.apache.cassandra.db.index.keys.KeysSearcher$1.computeNext(KeysSearcher.java:1)
> at
> com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143)
> at
> com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138)
> at
> org.apache.cassandra.db.ColumnFamilyStore.filter(ColumnFamilyStore.java:1754)
> at
> org.apache.cassandra.db.index.keys.KeysSearcher.search(KeysSearcher.java:56)
> at
> org.apache.cassandra.db.index.SecondaryIndexManager.search(SecondaryIndexManager.java:537)
> at
> org.apache.cassandra.db.ColumnFamilyStore.search(ColumnFamilyStore.java:1742)
> at
> org.apache.cassandra.db.RangeSliceCommand.executeLocally(RangeSliceCommand.java:135)
> at
> org.apache.cassandra.service.StorageProxy$LocalRangeSliceRunnable.runMayThrow(StorageProxy.java:1363)
> at
> org.apache.cassandra.service.StorageProxy$DroppableRunnable.run(StorageProxy.java:1876)
> ... 3 more
>
> Here he is trying to compare a Long (range is a long) to a
> LocalToken(comparator=LongType, token=HeapByteBuffer(=1968)) where my query
> was 'select * from users where birth_date>=1968' and birth_date is a Long.
>
> So it looks almost right as the LocalToken has the LongComparator etc. but
> it is failing obviously.
>
> My suspicion is that here we are trying to look for the 1968 parition of the
> index, and this 1968 happens to not be a Long which is what range is
> providing.
>
> Any clues on what might actually be happening??
>
> Thanks a lot in advance.
--
Jonathan Ellis
Project Chair, Apache Cassandra
co-founder, http://www.datastax.com
@spyced