blob: 186aafab6599fb516397bacd8a003543824babc9 [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.collection.cache;
import java.util.Collection;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.apache.usergrid.persistence.collection.EntityCollectionManager;
import org.apache.usergrid.persistence.collection.EntitySet;
import org.apache.usergrid.persistence.collection.VersionSet;
import org.apache.usergrid.persistence.core.util.Health;
import org.apache.usergrid.persistence.model.entity.Entity;
import org.apache.usergrid.persistence.model.entity.Id;
import org.apache.usergrid.persistence.model.field.Field;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import rx.Observable;
import rx.functions.Action1;
@Singleton
public class CachedEntityCollectionManager implements EntityCollectionManager {
/**
* The collection manager we perform real i/o from
*/
private EntityCollectionManager targetEntityCollectionManager;
/** Short-term cache to keep us from reloading same Entity during single request. */
private Cache<Id, Entity> entityCache;
private Action1<Entity> cacheAdd = new Action1<Entity>() {
@Override
public void call( final Entity entity ) {
entityCache.put( entity.getId(), entity );
}
};
@Inject
public CachedEntityCollectionManager( final EntityCacheFig entityCacheFig,
final EntityCollectionManager targetEntityCollectionManager ) {
this.targetEntityCollectionManager = targetEntityCollectionManager;
entityCache = CacheBuilder.newBuilder().maximumSize( entityCacheFig.getCacheSize() )
.expireAfterWrite( entityCacheFig.getCacheTimeout(), TimeUnit.SECONDS )
.build();
}
@Override
public Observable<Entity> write( final Entity entity ) {
return targetEntityCollectionManager.write( entity ).doOnNext( cacheAdd );
}
@Override
public Observable<Id> delete( final Id entityId ) {
return targetEntityCollectionManager.delete( entityId ).doOnNext( new Action1<Id>() {
@Override
public void call( final Id id ) {
entityCache.invalidate( id );
}
} );
}
@Override
public Observable<Entity> load( final Id entityId ) {
final Entity entity = entityCache.getIfPresent( entityId );
if ( entity != null ) {
return Observable.just( entity );
}
return targetEntityCollectionManager.load( entityId ).doOnNext( cacheAdd );
}
@Override
public Observable<VersionSet> getLatestVersion( final Collection<Id> entityId ) {
return targetEntityCollectionManager.getLatestVersion( entityId );
}
@Override
public Observable<Id> getIdField( final Field field ) {
return targetEntityCollectionManager.getIdField( field );
}
@Override
public Observable<EntitySet> load( final Collection<Id> entityIds ) {
return targetEntityCollectionManager.load( entityIds );
}
@Override
public Observable<Entity> update( final Entity entity ) {
return targetEntityCollectionManager.update( entity ).doOnNext( cacheAdd );
}
@Override
public Health getHealth() {
return targetEntityCollectionManager.getHealth();
}
}