1

Тема: Redis + boolean

Як я зрозумів, redis для збереження boolean значень використовує, щось окрім такого, що привик бачити у всіх мовах/СУБД.
Мені треба значення True/False/nil і потім конвертувати в python bool type.

Варіанти, які я можуть підійти:

1. integer 0/1/expire
2. string True/False/expire - хрінь, здається
3. bit - не розібрався, насправді. Ідеально, щоб зберігати 0/1, але там ще є offset, що це таке?
Погугливши, виходить, що це - місце конкретного біта в послідовності. Але:

GET k
(nil)
127.0.0.1:6379> SETBIT k 0 0
(integer) 0
127.0.0.1:6379>
127.0.0.1:6379> GET k
"\x00" # ok == False
127.0.0.1:6379> SETBIT k 0 1
(integer) 0
127.0.0.1:6379> GET k
"\x80" # WTF? хіба не має бути \x01
127.0.0.1:6379>

Що не підкажете?

Навчаюсь вчитись, щоб навчатись.

2 Востаннє редагувалося /KIT\ (02.04.2019 19:28:30)

Re: Redis + boolean

Redis не знаю, але спробуйте

SETBIT k 7 1
...
Подякували: Q-bart1

3

Re: Redis + boolean

https://redis.io/commands/SETBIT

Sets or clears the bit at offset in the string value stored at key.

Тобто SETBIT зберігає стрічку, а не число. Логічно використовувати для цього big-endian.
Ну і вам треба читати GETBIT-ом:

> GETBIT k 0
1
Подякували: Q-bart1

4

Re: Redis + boolean

koala написав:

https://redis.io/commands/SETBIT

Sets or clears the bit at offset in the string value stored at key.

Тобто SETBIT зберігає стрічку, а не число. Логічно використовувати для цього big-endian.
Ну і вам треба читати GETBIT-ом:

> GETBIT k 0
1

Те, що треба! Дякую

Навчаюсь вчитись, щоб навчатись.

5

Re: Redis + boolean

/KIT\ написав:

Redis не знаю, але спробуйте

SETBIT k 7 1

Ось, теж щось таке бачив в неті. Але не зрозумів в чому логіка? Чому 7?

Можна просто тицьнути в якусь статтю чи запит в гуглі

Навчаюсь вчитись, щоб навчатись.

6

Re: Redis + boolean

Q-bart написав:

Чому 7?

Бо у байті 8 біт, логічно?

Подякували: Q-bart1

7 Востаннє редагувалося Q-bart (02.04.2019 20:02:28)

Re: Redis + boolean

Тобто для кодування одного символу REDIS використовує один байт. Відповідно, щоб отримати:
- '0' треба 0 байт == 0 bit
- '1' треба 1 байт == 8 bit == 1000 (2nd base)

Вірно?

Навчаюсь вчитись, щоб навчатись.

8

Re: Redis + boolean

Залежить від того, що ви маєте на увазі під '0'. Зазвичай так позначають символи, а в ASCII '0' - це 48=0b110000.

>SETBIT n 2 1
>SETBIT n 3 1
>GET n
"0"
Подякували: Q-bart, leofun012

9

Re: Redis + boolean

Е, так. Ок, тоді в чому різниця між цим:

SETBIT n 2 1
(integer) 0
127.0.0.1:6379> SETBIT n 3 1
(integer) 0
127.0.0.1:6379> GET n
"0"

i

127.0.0.1:6379> setbit kk 0 0
(integer) 0
127.0.0.1:6379> GET kk
"\x00"

"\x00" !== "0" - це очевидно, але що таке "\x00"?

Навчаюсь вчитись, щоб навчатись.

10

Re: Redis + boolean

>що таке "\x00"?
нульовий байт

...
Подякували: Q-bart1

11

Re: Redis + boolean

"\x00" - очевидно, стрічка з одного символу із шістнадцятковим кодом 00.

Подякували: Q-bart1

12

Re: Redis + boolean

Ще таке:

Якщо в мене є якась послідовність, стан кожного конкретного біта (1/0) можу читати з GETBIT, але якщо мені треба прочитати всю посідовність, і в коді вже далі її опрацьовувати:

>>> setbit k 1 1
 0
>>> setbit k 3 1
 0
>>> get k
"P"

Але ж сама послідовність зараз виглядає: "1010" - і мені це треба отримати. В циклі отримувати GETBIT - не варіант. Що повертає GET k === "P" - як мені з цього отримати "1010"?

Символ "P" в ascii == '0101 0000', a очікуваний '1010' == 10 (base 10), в ascii == '[LF]'  - якийсь спецсимвол.

Завдання: отримати всі індекси позитивних бітів (які == 1)

Навчаюсь вчитись, щоб навчатись.

13

Re: Redis + boolean

Ви не з того боку дивитеся. Біти йдуть з лівого боку:

Початковий стан: 
#біта:0123 4567
 дані:0000 0000
>>> setbit k 1 1
#біта:0123 4567
 дані:0100 0000
>>> setbit k 3 1
#біта:0123 4567
 дані:0101 0000
Подякували: Q-bart1

14

Re: Redis + boolean

О, фак, серйозно? Чому так?

Але ж біти починають рахувати справа.

Навчаюсь вчитись, щоб навчатись.

15

Re: Redis + boolean

Q-bart написав:

О, фак, серйозно? Чому так?

Бо це - стрічка бітів.

Q-bart написав:

Але ж біти починають рахувати справа.

Це лише форма запису.

Подякували: Q-bart1

16

Re: Redis + boolean

ok-ok.

Тепер залишилось лише правильно прочитати.
1. Якщо значення є в таблиці ascii, то повертається символ
2. Якщо нема (<= 31) || (>=128), то повертаєтсья hex (16 base).

Як мені читати це? Використовую python. Якби завжди поверталось hex - ok, а так - як?

Навчаюсь вчитись, щоб навчатись.

17

Re: Redis + boolean

А чим саме ви підключаєтеся? Не через os.system, сподіваюся?

Подякували: Q-bart1

18 Востаннє редагувалося koala (10.04.2019 14:37:07)

Re: Redis + boolean

Перевірте type того, що там повертається в різних випадках.

Подякували: Q-bart1

19 Востаннє редагувалося Q-bart (10.04.2019 15:09:38)

Re: Redis + boolean

aioredis.
В результаті на get отримую b''

await self.connector.set_bit(name, 2, 1)
await self.connector.set_bit(name, 7, 1)
await self.connector.set_bit(name, 258, 1)

b'!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 '

Воно правильно показало, що перший символ = '!', але це при print('') ОС спробувала розкодувати (я думаю). Якщо в циклі пройтись по всіх значеннях, то:

33 i
0
...
0
32

- вочевидь, python приймає це, як стрічку, розбиває послідовність на байти і пробує друкувати. А як мені це перевести в список з бітів? Тип я думаю можна залишити int: [1,1,1,0,0,0]?

Навчаюсь вчитись, щоб навчатись.

20 Востаннє редагувалося koala (10.04.2019 15:15:09)

Re: Redis + boolean

b - байтова стрічка. В принципі, так і має бути.
Як розбити? На байти воно вже розбите, вам треба лише біти вишкребти.

r = як_ви_там_його_getаєте()
bits = []
for byte in r:
    bits += [(ord(byte)>>i) & 1 for i in range(7,-1,-1)]

якось так

Подякували: Q-bart1