blob: 47bb0cf2acaae06fe397a65d354c811676a6aae6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.usergrid.persistence.cassandra;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import static java.lang.Integer.parseInt;
import static org.apache.commons.codec.binary.Base64.decodeBase64;
import static org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString;
import static org.apache.commons.lang.StringUtils.split;
import static org.apache.usergrid.utils.ConversionUtils.bytes;
/**
* Internal cursor parsing
*
* @author tnine
*/
public class CursorCache {
private Map<Integer, ByteBuffer> cursors = new HashMap<Integer, ByteBuffer>();
public CursorCache() {
}
/** Create a new cursor cache from the string if passed */
public CursorCache( String cursorString ) {
if ( cursorString == null ) {
return;
}
String decoded = new String( decodeBase64( cursorString ) );
// nothing to do
if ( decoded.indexOf( ':' ) < 0 ) {
return;
}
String[] cursorTokens = split( decoded, '|' );
for ( String c : cursorTokens ) {
String[] parts = split( c, ':' );
if ( parts.length >= 1 ) {
int hashCode = parseInt( parts[0] );
ByteBuffer cursorBytes = null;
if ( parts.length == 2 ) {
cursorBytes = ByteBuffer.wrap( decodeBase64( parts[1] ) );
}
else {
cursorBytes = ByteBuffer.allocate( 0 );
}
cursors.put( hashCode, cursorBytes );
}
}
}
/** Set the cursor with the given hash and the new byte buffer */
public void setNextCursor( int sliceHash, ByteBuffer newCursor ) {
cursors.put( sliceHash, newCursor );
}
/** Get the cursor by the hashcode of the slice */
public ByteBuffer getCursorBytes( int sliceHash ) {
return cursors.get( sliceHash );
}
/** Turn the cursor cache into a string */
public String asString() {
/**
* No cursors to return
*/
if ( cursors.size() == 0 ) {
return null;
}
StringBuffer buff = new StringBuffer();
int nullCount = 0;
ByteBuffer value = null;
for ( Entry<Integer, ByteBuffer> entry : cursors.entrySet() ) {
value = entry.getValue();
buff.append( entry.getKey() );
buff.append( ":" );
buff.append( encodeBase64URLSafeString( bytes( value ) ) );
buff.append( "|" );
// this range was empty, mark it as a null
if ( value == null || value.remaining() == 0 ) {
nullCount++;
}
}
// all cursors are complete, return null
if ( nullCount == cursors.size() ) {
return null;
}
// trim off the last pipe
buff.setLength( buff.length() - 1 );
return encodeBase64URLSafeString( buff.toString().getBytes() );
}
}