Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 322dd1d

Browse files
committed
Added GETBIT, SETBIT with doc and unit tests.
1 parent fe09260 commit 322dd1d

File tree

4 files changed

+136
-2
lines changed

4 files changed

+136
-2
lines changed

README.markdown

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,44 @@ $redis->set('key', 'value');
14271427
$redis->strlen('key'); /* 5 */
14281428
</pre>
14291429

1430+
## getBit
1431+
##### *Description*
1432+
Return a single bit out of a larger string
1433+
1434+
##### *Parameters*
1435+
*key*
1436+
*offset*
1437+
1438+
##### *Return value*
1439+
*LONG*: the bit value (0 or 1)
1440+
1441+
##### *Example*
1442+
<pre>
1443+
$redis->set('key', "\x7f"); // this is 0111 1111
1444+
$redis->getBit('key', 0); /* 0 */
1445+
$redis->getBit('key', 1); /* 1 */
1446+
</pre>
1447+
1448+
## setBit
1449+
##### *Description*
1450+
Changes a single bit of a string.
1451+
1452+
##### *Parameters*
1453+
*key*
1454+
*offset*
1455+
*value*: bool or int (1 or 0)
1456+
1457+
##### *Return value*
1458+
*LONG*: 0 or 1, the value of the bit before it was set.
1459+
1460+
##### *Example*
1461+
<pre>
1462+
$redis->set('key', "*"); // ord("*") = 42 = 0x2f = "0010 1010"
1463+
$redis->setBit('key', 5, 1); /* returns 0 */
1464+
$redis->setBit('key', 7, 1); /* returns 0 */
1465+
$redis->get('key'); /* chr(0x2f) = "/" = b("0010 1111") */
1466+
</pre>
1467+
14301468
## flushDB
14311469

14321470
##### *Description*

php_redis.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ PHP_METHOD(Redis, type);
4747
PHP_METHOD(Redis, append);
4848
PHP_METHOD(Redis, getRange);
4949
PHP_METHOD(Redis, setRange);
50+
PHP_METHOD(Redis, getBit);
51+
PHP_METHOD(Redis, setBit);
5052
PHP_METHOD(Redis, strlen);
5153
PHP_METHOD(Redis, getKeys);
5254
PHP_METHOD(Redis, sort);

redis.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ static zend_function_entry redis_functions[] = {
7171
PHP_ME(Redis, append, NULL, ZEND_ACC_PUBLIC)
7272
PHP_ME(Redis, getRange, NULL, ZEND_ACC_PUBLIC)
7373
PHP_ME(Redis, setRange, NULL, ZEND_ACC_PUBLIC)
74+
PHP_ME(Redis, getBit, NULL, ZEND_ACC_PUBLIC)
75+
PHP_ME(Redis, setBit, NULL, ZEND_ACC_PUBLIC)
7476
PHP_ME(Redis, strlen, NULL, ZEND_ACC_PUBLIC)
7577
PHP_ME(Redis, getKeys, NULL, ZEND_ACC_PUBLIC)
7678
PHP_ME(Redis, sort, NULL, ZEND_ACC_PUBLIC)
@@ -1154,6 +1156,60 @@ PHP_METHOD(Redis, setRange)
11541156
REDIS_PROCESS_RESPONSE(redis_long_response);
11551157
}
11561158

1159+
PHP_METHOD(Redis, getBit)
1160+
{
1161+
zval *object;
1162+
RedisSock *redis_sock;
1163+
char *key = NULL, *cmd;
1164+
int key_len, cmd_len;
1165+
long offset;
1166+
1167+
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osl",
1168+
&object, redis_ce, &key, &key_len,
1169+
&offset) == FAILURE) {
1170+
RETURN_FALSE;
1171+
}
1172+
1173+
if (redis_sock_get(object, &redis_sock TSRMLS_CC) < 0) {
1174+
RETURN_FALSE;
1175+
}
1176+
1177+
cmd_len = redis_cmd_format_static(&cmd, "GETBIT", "sd", key, key_len, (int)offset);
1178+
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
1179+
IF_ATOMIC() {
1180+
redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
1181+
}
1182+
REDIS_PROCESS_RESPONSE(redis_long_response);
1183+
}
1184+
1185+
PHP_METHOD(Redis, setBit)
1186+
{
1187+
zval *object;
1188+
RedisSock *redis_sock;
1189+
char *key = NULL, *cmd;
1190+
int key_len, cmd_len;
1191+
long offset;
1192+
zend_bool val;
1193+
1194+
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oslb",
1195+
&object, redis_ce, &key, &key_len,
1196+
&offset, &val) == FAILURE) {
1197+
RETURN_FALSE;
1198+
}
1199+
1200+
if (redis_sock_get(object, &redis_sock TSRMLS_CC) < 0) {
1201+
RETURN_FALSE;
1202+
}
1203+
1204+
cmd_len = redis_cmd_format_static(&cmd, "SETBIT", "sdd", key, key_len, (int)offset, (int)val);
1205+
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
1206+
IF_ATOMIC() {
1207+
redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
1208+
}
1209+
REDIS_PROCESS_RESPONSE(redis_long_response);
1210+
}
1211+
1212+
11571213
PHP_METHOD(Redis, strlen)
11581214
{
11591215
zval *object;

tests/TestRedis.php

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,46 @@ public function testPing()
5555

5656
}
5757

58+
public function testBitsets() {
59+
60+
$this->redis->delete('key');
61+
$this->assertTrue(0 === $this->redis->getBit('key', 0));
62+
$this->assertTrue(FALSE === $this->redis->getBit('key', -1));
63+
$this->assertTrue(0 === $this->redis->getBit('key', 100000));
64+
65+
$this->redis->set('key', "\xff");
66+
for($i = 0; $i < 8; $i++) {
67+
$this->assertTrue(1 === $this->redis->getBit('key', $i));
68+
}
69+
$this->assertTrue(0 === $this->redis->getBit('key', 8));
70+
71+
// negative offset doesn't work
72+
$this->assertTrue(FALSE === $this->redis->setBit('key', -1, 0));
73+
$this->assertTrue(1 === $this->redis->getBit('key', 0));
74+
75+
// change bit 0
76+
$this->assertTrue(1 === $this->redis->setBit('key', 0, 0));
77+
$this->assertTrue(0 === $this->redis->setBit('key', 0, 0));
78+
$this->assertTrue(0 === $this->redis->getBit('key', 0));
79+
$this->assertTrue("\x7f" === $this->redis->get('key'));
80+
81+
// change bit 1
82+
$this->assertTrue(1 === $this->redis->setBit('key', 1, 0));
83+
$this->assertTrue(0 === $this->redis->setBit('key', 1, 0));
84+
$this->assertTrue(0 === $this->redis->getBit('key', 1));
85+
$this->assertTrue("\x3f" === $this->redis->get('key'));
86+
87+
// change bit > 1
88+
$this->assertTrue(1 === $this->redis->setBit('key', 2, 0));
89+
$this->assertTrue(0 === $this->redis->setBit('key', 2, 0));
90+
$this->assertTrue(0 === $this->redis->getBit('key', 2));
91+
$this->assertTrue("\x1f" === $this->redis->get('key'));
92+
93+
// values above 1 are changed to 1 but don't overflow on bits to the right.
94+
$this->assertTrue(0 === $this->redis->setBit('key', 0, 0xff));
95+
$this->assertTrue("\x9f" === $this->redis->get('key'));
96+
}
97+
5898
public function test1000() {
5999

60100
$s = str_repeat('A', 1000);
@@ -1793,8 +1833,6 @@ public function testSetRange() {
17931833
$this->redis->delete('key');
17941834
$this->redis->setRange('key', 6, 'foo');
17951835
$this->assertTrue("\x00\x00\x00\x00\x00\x00foo" === $this->redis->get('key'));
1796-
1797-
17981836
}
17991837

18001838
public function testMultiExec() {

0 commit comments

Comments
 (0)