Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Atribuição atômica e consulta de bits

Olá!

Acabo de terminar este curso e fiquei com duas dúvidas quanto ao redis.

1 - No exemplo da mega sena, tínhamos uma chave para armazenar o ultimo resultado e outra com o resultado "datado". Existe alguma maneira de atribuir o valor de uma chave a uma nova chave de maneira atômica ? Comparando com linguagens de programação, seria o mesmo que atribuir uma variável a outra.

2 - Quando estamos trabalhando com cadeias de bits, como eu posso consultar todos os bits que estão ligados? No exemplo do acesso ao site, seria uma maneira rápida de saber quais usuários acessaram a página no dia dd-mm-yyyy

4 respostas

Oi Marcus, tudo bem?

Pelas pesquisas que eu fiz, não tem solução pra nenhum dos dois casos.

  • O Redis não oferece um comando para poder atribuir o valor de uma chave a outra de maneira atômica. A solução parece ser recuperar o valor da chave com o GET e atribuir pra outra.

  • Também não há comando para recuperar apenas os bits que estão ligados.

Aparentemente a intenção de utilizar o mapa de bits é apenas saber quantos estão ligados: no nosso caso, saber quantos usuários acessaram o sistema, mas não saber especificamente quem acessou. Lembrando que também realizar as operações lógicas (AND, OR, XOR, NOT).

Abraço.

Oi Marcus,.

Sobre sua segunda pergunta, como não temos um comando específico para retornar os bits 1s, na prática acabamos pegando o bitset inteiro e varrendo ele na memória (operação O(N) no numero de bits)... Você pode pegar uma parte do bitset, com BITRANGE mas mesmo assim terá que varrer esse range para recuperar seu valor.

Att

Oi Marcus, complementando sobre a primeira pergunta, onde eu falei que você podia recuperar o valor da chave com o GET e atribuir pra outra. Você pode utilizar a transação do Redis. A transação irá garantir a atomicidade. Ou executa tudo, ou não executa.

Você pode encontrar mais sobre transações na documentação do Redis: http://redis.io/topics/transactions

No Redis, você pode utilizar o comando MULTI:

> MULTI
OK
> INCR acessos 
QUEUED
> INCR visitas
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1

Todos os comandos que você digita após chamar o MULTI só serão executados quando você chamar o EXEC, e você também tem a atomicidade garantida.

Existe também o comando WATCH, que quando aplicado a uma chave fica monitorando e, em caso o valor da chave mude antes de chamarmos o EXEC, a transação irá falhar.

Abaixo, mostro um exemplo de como poderia fazer, utilizando a biblioteca Jedis, um cliente do Redis pro Java. O Redis possui clientes para várias linguagens de programação. Você pode consultar aqui: http://redis.io/clients.

Jedis jedis = new Jedis("localhost", 6379);

jedis.set("ultimo_sorteio", "2, 15, 18, 30, 35, 42");

jedis.watch("ultimo_sorteio");

String ultimoSorteio = jedis.get("ultimo_sorteio");

Transaction multi = jedis.multi();
multi.set("resultado:17-05-2015:megasena", ultimoSorteio);
multi.exec();

System.out.println("ultimo_sorteio: " + jedis.get("ultimo_sorteio"));
System.out.println("resultado:17-05-2015:megasena: " + jedis.get("resultado:17-05-2015:megasena"));

Nesse caso, recuperamos o valor de "ultimo_sorteio" para a variavel ultimoSorteio do Java, e utilizamos o set para atribuir seu valor à chave resultado:17-05-2015:megasena.

Como utilizamos o watch em "ultimo_sorteio", caso algum outro cliente altere o valor de "ultimo_sorteio" nesse meio tempo, a transação vai falhar.

Faz sentido?

Abraço!

solução!

Oi Marcus, tudo bem?

Será que conseguimos tirar duas dúvidas? Estou encerrando este tópico, ok? Caso a dúvida persista, sinta-se à vontade para abrir uma nova discussão. :)

Abraço.