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