Presumo que o armazenamento do valor-chave seja muito grande para percorrer todos os pares de kv para descobrir qual pode ser expirado. Suponho também que cada acesso de leitura atualize o carimbo de data / hora de expiração, portanto, apenas os itens que não foram acessados por algum tempo expiraram.
O desafio é encontrar com eficiência todos os registros que podem expirar (sempre que a limpeza terminar), mas também atualizar com eficiência o carimbo de data / hora de expiração em todos os acessos de leitura (portanto, precisamos encontrar a chave na estrutura usada para a expiração).
Minha proposta: agrupar expiry_timestamps em buckets; por exemplo, se os itens durarem 8 horas, faça um balde por hora. Esses baldes são mantidos em uma lista vinculada; quando a expiração ocorre, o primeiro intervalo é esvaziado e a lista reduzida. O número de buckets é o tempo de vida útil / intervalo de limpeza. Cada bloco contém um hashSet de todas as chaves que devem expirar. A iteração sobre todas as chaves em um hashset é eficiente o suficiente.
Durante o acesso de leitura, o programa verifica em qual depósito a chave está atualmente e em qual depósito pertence agora. Na maioria dos casos, é o mesmo depósito, portanto, nenhuma ação adicional é necessária. Caso contrário, remova a chave do balde antigo (a remoção de um conjunto de hash é eficiente) e insira-a no novo balde.
+--------------+ +--------------+ +--------------+
-->+ Expiry 08:00 +-->+ Expiry 09:00 +-->+ Expiry 10:00 +
| KeySet | | KeySet | | KeySet |
+--------------+ +--------------+ +--------------+