package fr.ippon.tatami.repository.cassandra;
import fr.ippon.tatami.repository.CounterRepository;
import me.prettyprint.cassandra.model.thrift.ThriftCounterColumnQuery;
import me.prettyprint.cassandra.serializers.StringSerializer;
import me.prettyprint.hector.api.Keyspace;
import me.prettyprint.hector.api.beans.HCounterColumn;
import me.prettyprint.hector.api.factory.HFactory;
import me.prettyprint.hector.api.mutation.Mutator;
import me.prettyprint.hector.api.query.CounterQuery;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Repository;
import fr.ippon.tatami.config.ColumnFamilyKeys;
import javax.inject.Inject;
import static me.prettyprint.hector.api.factory.HFactory.createCounterColumn;
/**
* Cassandra implementation of the Counter repository.
* <p/>
* Structure :
* - Key = login
* - Name = counterId
* - Value = count
*
* @author Julien Dubois
*/
@Repository
public class CassandraCounterRepository implements CounterRepository {
private static final String STATUS_COUNTER = "STATUS_COUNTER";
private static final String FOLLOWERS_COUNTER = "FOLLOWERS_COUNTER";
private static final String FRIENDS_COUNTER = "FRIENDS_COUNTER";
@Inject
private Keyspace keyspaceOperator;
@Override
@CacheEvict(value = "user-cache", key = "#login")
public void incrementFollowersCounter(String login) {
incrementCounter(FOLLOWERS_COUNTER, login);
}
@Override
@CacheEvict(value = {"user-cache", "suggest-users-cache"}, key = "#login")
public void incrementFriendsCounter(String login) {
incrementCounter(FRIENDS_COUNTER, login);
}
@Override
@CacheEvict(value = "user-cache", key = "#login")
public void incrementStatusCounter(String login) {
incrementCounter(STATUS_COUNTER, login);
}
@Override
@CacheEvict(value = "user-cache", key = "#login")
public void decrementFollowersCounter(String login) {
decrementCounter(FOLLOWERS_COUNTER, login);
}
@Override
@CacheEvict(value = "user-cache", key = "#login")
public void decrementFriendsCounter(String login) {
decrementCounter(FRIENDS_COUNTER, login);
}
@Override
@CacheEvict(value = "user-cache", key = "#login")
public void decrementStatusCounter(String login) {
decrementCounter(STATUS_COUNTER, login);
}
@Override
public long getFollowersCounter(String login) {
return getCounter(FOLLOWERS_COUNTER, login);
}
@Override
public long getFriendsCounter(String login) {
return getCounter(FRIENDS_COUNTER, login);
}
@Override
public long getStatusCounter(String login) {
return getCounter(STATUS_COUNTER, login);
}
@Override
public void createFollowersCounter(String login) {
createCounter(FOLLOWERS_COUNTER, login);
}
@Override
public void createFriendsCounter(String login) {
createCounter(FRIENDS_COUNTER, login);
}
@Override
public void createStatusCounter(String login) {
createCounter(STATUS_COUNTER, login);
}
@Override
public void deleteCounters(String login) {
Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());
mutator.addCounterDeletion(login, ColumnFamilyKeys.COUNTER_CF, STATUS_COUNTER, StringSerializer.get());
mutator.addCounterDeletion(login, ColumnFamilyKeys.COUNTER_CF, FOLLOWERS_COUNTER, StringSerializer.get());
mutator.addCounterDeletion(login, ColumnFamilyKeys.COUNTER_CF, FRIENDS_COUNTER, StringSerializer.get());
mutator.execute();
}
private void createCounter(String counterName, String login) {
Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());
mutator.insertCounter(login, ColumnFamilyKeys.COUNTER_CF,
createCounterColumn(counterName, 0));
}
private void incrementCounter(String counterName, String login) {
Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());
mutator.incrementCounter(login, ColumnFamilyKeys.COUNTER_CF, counterName, 1);
}
private void decrementCounter(String counterName, String login) {
Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());
mutator.decrementCounter(login, ColumnFamilyKeys.COUNTER_CF, counterName, 1);
}
private long getCounter(String counterName, String login) {
CounterQuery<String, String> counter =
new ThriftCounterColumnQuery<String, String>(keyspaceOperator,
StringSerializer.get(),
StringSerializer.get());
counter.setColumnFamily(ColumnFamilyKeys.COUNTER_CF).setKey(login).setName(counterName);
HCounterColumn<String> counterColumn = counter.execute().get();
if (counterColumn == null) {
return 0;
} else {
return counterColumn.getValue();
}
}
}