Os evictors estão associados às instâncias do BackingMap.
import com.ibm.websphere.objectgrid.ObjectGridManagerFactory;
import com.ibm.websphere.objectgrid.ObjectGridManager;
import com.ibm.websphere.objectgrid.ObjectGrid;
import com.ibm.websphere.objectgrid.BackingMap;
import com.ibm.websphere.objectgrid.TTLType;
ObjectGridManager ogManager = ObjectGridManagerFactory.getObjectGridManager();
ObjectGrid og = ogManager.createObjectGrid("grid");
BackingMap bm = og.defineMap( "myMap" );
bm.setTtlEvictorType( TTLType.CREATION_TIME );
bm.setTimeToLive( 600 );
O argumento do método setTimeToLive é 600 porque isso indica que o valor de time-to-live está em segundos. O código anterior deve ser executado antes de o método initialize ser chamado na instância do ObjectGrid. Estes atributos de BackingMap não podem ser alterados após a inicialização da instância do ObjectGrid. Após a execução do código, qualquer entrada inserida no BackingMap myMap tem um tempo de expiração. Ao final do tempo de expiração, o evictor de TTL remove a entrada.
Para configurar o prazo de expiração para o horário do último acesso mais 10 minutos, altere o argumento que é transmitido para o método setTtlEvictorType de TTLType.CREATION_TIME para TTLType.LAST_ACCESS_TIME. Com este valor, o tempo de expiração é calculado como a hora do último acesso mais 10 minutos. Quando uma entrada é criada pela primeira vez, a hora do último acesso é a hora de criação. Para basear o prazo de expiração na última atualização, em vez de simplesmente no último acesso (se ele envolveu ou não uma atualização), substitua a configuração TTLType.LAST_UPDATE_TIME pela configuração TTLType.LAST_ACCESS_TIME.
Ao usar a configuração TTLType.LAST_ACCESS_TIME ou TTLType.LAST_UPDATE_TIME, é possível usar as interfaces ObjectMap e JavaMap para substituir o valor time-to-live de BackingMap. Esse mecanismo permite que um aplicativo utilize um valor de time-to-live diferente para cada entrada criada. Suponha que o fragmento de conjunto de códigos precedente configure o atributo ttlType como LAST_ACCESS_TIME e configure o valor de time-to-live como 10 minutos. Qualquer aplicativo pode substituir o valor de time-to-live para cada entrada executando o seguinte código antes de criar ou modificar uma entrada:
import com.ibm.websphere.objectgrid.Session;
import com.ibm.websphere.objectgrid.ObjectMap;
Session session = og.getSession();
ObjectMap om = session.getMap( "myMap" );
int oldTimeToLive1 = om.setTimeToLive( 1800 );
om.insert("key1", "value1" );
int oldTimeToLive2 = om.setTimeToLive( 1200 );
om.insert("key2", "value2" );
No fragmento de código anterior, a entrada com a chave key1 tem um prazo de expiração composto pelo tempo de inserção mais 30 minutos como resultado da solicitação de método setTimeToLive( 1800 ) na instância de ObjectMap. A variável oldTimeToLive1 é configurada como 600 porque o valor de time-to-live de BackingMap é utilizado como um valor padrão se o método setTimeToLive não foi chamado anteriormente na instância de ObjectMap.
A entrada com a chave key2 tem um prazo de expiração composto pelo tempo de inserção mais 20 minutos como resultado da chamada de método setTimeToLive( 1200 ) na instância de ObjectMap. A variável oldTimeToLive2 é configurada como 1800 porque o valor de time-to-live da solicitação de método ObjectMap.setTimeToLive anterior configura o valor de time-to-live como 1800.
O exemplo anterior mostra duas entradas de mapa sendo inseridas no mapa myMap para as chaves key1 e key2. Posteriormente, o aplicativo ainda pode atualizar essas entradas de mapa enquanto retém os valores de time-to-live que são utilizados no tempo de inserção para cada entrada de mapa. O exemplo a seguir ilustra como reter os valores de TTL (Time-to-Live), utilizando uma constante definida na interface ObjectMap:
Session session = og.getSession();
ObjectMap om = session.getMap( "myMap" );
om.setTimeToLive( ObjectMap.USE_DEFAULT );
session.begin();
om.update("key1", "updated value1" );
om.update("key2", "updated value2" );
om.insert("key3", "value3" );
session.commit();
Como o valor especial de ObjectMap.USE_DEFAULT é utilizado na chamada de método setTimeToLive, a chave key1 retém seu valor de time-to-live de 1800 segundos e a chave key2 retém seu valor de time-to-live de 1200 segundos, pois esses valores foram utilizados quando essas entradas de mapa foram inseridas pela transação anterior.
O exemplo anterior também mostra uma nova entrada de mapa para a inserção da chave key3. Neste caso, o valor especial USE_DEFAULT indica a utilização da configuração padrão do valor time-to-live para este mapa. O valor padrão é definido pelo atributo time-to-live de BackingMap. Consulte atributos da interface BackingMap para obter informações sobre como o atributo time-to-live é definido na instância do BackingMap.
Consulte a documentação da API para o método setTimeToLive nas interfaces ObjectMap e JavaMap. A documentação explica que o resultado será uma exceção IllegalStateException se o método BackingMap.getTtlEvictorType retornar qualquer coisa diferente do valor TTLType.LAST_ACCESS_TIME ou TTLType.LAST_UPDATE_TIME. As interfaces ObjectMap e JavaMap podem substituir o valor time-to-live apenas quando você está usando a configuração LAST_ACCESS_TIME ou TTLType.LAST_UPDATE_TIME para o tipo de evictor TTL. O método setTimeToLive não pode ser utilizado para substituir o valor de time-to-live quando você estiver utilizando a configuração de tipo de evictor CREATION_TIME ou NONE.
Como os evictors estão associados aos BackingMaps, use a interface BackingMap para especificar o evictor conectável. O trecho de código a seguir é um exemplo de especificação de um evictor LRUEvictor para o BackingMap map1 e um evictor LFUEvictor para a instância do BackingMap map2:
import com.ibm.websphere.objectgrid.ObjectGridManagerFactory;
import com.ibm.websphere.objectgrid.ObjectGridManager;
import com.ibm.websphere.objectgrid.ObjectGrid;
import com.ibm.websphere.objectgrid.BackingMap;
import com.ibm.websphere.objectgrid.plugins.builtins.LRUEvictor;
import com.ibm.websphere.objectgrid.plugins.builtins.LFUEvictor;
ObjectGridManager ogManager = ObjectGridManagerFactory.getObjectGridManager();
ObjectGrid og = ogManager.createObjectGrid("grid");
BackingMap bm = og.defineMap( "map1" );
LRUEvictor evictor = new LRUEvictor();
evictor.setMaxSize(1000);
evictor.setSleepTime( 15 );
evictor.setNumberOfLRUQueues( 53 );
bm.setEvictor(evictor);
bm = og.defineMap( "map2" );
LFUEvictor evictor2 = new LFUEvictor();
evictor2.setMaxSize(2000);
evictor2.setSleepTime( 15 );
evictor2.setNumberOfHeaps( 211 );
bm.setEvictor(evictor2);
O snippet anterior mostra um evictor LRUEvictor sendo utilizado para o map1 BackingMap com um número aproximado de entradas de 53.000 (53 * 1000). O evictor LFUEvictor é utilizado para o map2 BackingMap com um número máximo aproximado de entradas de 422.000 (211 * 2000). Os evictores LRU e LFU têm uma propriedade de tempo de suspensão que indica por quanto tempo o evictor fica suspenso antes de ser ativado e verificar se as entradas precisam ser liberadas. O tempo de suspensão é especificado em segundos. Um valor de 15 segundos é uma boa garantia entre o impacto no desempenho e a prevenção para que o BackingMap não se torne muito grande. A meta é utilizar o maior tempo de suspensão possível sem fazer o BackingMap crescer a um tamanho excessivo.
O método setNumberOfLRUQueues configura a propriedade LRUEvictor que indica quantas filas de LRU o evictor utiliza para gerenciar informações de LRU. Uma coleta de filas é utilizada para que cada entrada não mantenha informações de LRU na mesma fila. Esta abordagem pode melhorar o desempenho minimizando o número de entradas do mapa que precisam ser sincronizadas no mesmo objeto de fila. Aumentar o número de filas é uma boa maneira de minimizar o impacto que o evictor LRU pode causar no desempenho. Um bom ponto de partida é utilizar dez por cento do número máximo de entradas como o número de filas. A utilização de um número primo geralmente é melhor do que utilizar um número que não seja primo. O método setMaxSize indica quantas entradas são permitidas em cada fila. Quando uma fila alcança seu número máximo entradas, a entrada ou as entradas utilizadas menos recentemente nesta fila são despejadas na próxima vez que o evictor verifica se há alguma entrada que precisa ser despejada.
O método setNumberOfHeaps configura a propriedade LFUEvictor para determinar quantos objetos de heap binários o LFUEvictor utiliza para gerenciar informações de LFU. Mais uma vez é utilizada uma coleta para melhorar o desempenho. A utilização de dez por cento do número máximo de entrada é um bom ponto de partida e utilizar um número primo geralmente é melhor do que utilizar um número que não seja primo. O método setMaxSize indica quantas entradas são permitidas em cada heap. Quando um heap alcança seu número máximo entradas, a entrada ou as entradas utilizadas menos recentemente neste heap são despejadas na próxima vez que o evictor verifica se há alguma entrada que precisa ser despejada.