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

Skip to content

Commit e74ffe0

Browse files
Implemented BITPOS command
This commit introduces the new BITPOS redis command http://redis.io/commands/bitpos
1 parent 8f006cb commit e74ffe0

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

php_redis.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ PHP_METHOD(Redis, slaveof);
129129
PHP_METHOD(Redis, object);
130130
PHP_METHOD(Redis, bitop);
131131
PHP_METHOD(Redis, bitcount);
132+
PHP_METHOD(Redis, bitpos);
132133

133134
PHP_METHOD(Redis, eval);
134135
PHP_METHOD(Redis, evalsha);

redis.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ static zend_function_entry redis_functions[] = {
177177
PHP_ME(Redis, object, NULL, ZEND_ACC_PUBLIC)
178178
PHP_ME(Redis, bitop, NULL, ZEND_ACC_PUBLIC)
179179
PHP_ME(Redis, bitcount, NULL, ZEND_ACC_PUBLIC)
180+
PHP_ME(Redis, bitpos, NULL, ZEND_ACC_PUBLIC)
180181

181182
/* 1.1 */
182183
PHP_ME(Redis, mset, NULL, ZEND_ACC_PUBLIC)
@@ -820,6 +821,59 @@ PHP_METHOD(Redis, bitcount)
820821
}
821822
/* }}} */
822823

824+
/* {{{ proto integer Redis::bitpos(string key, int bit, [int start], [int end]) */
825+
PHP_METHOD(Redis, bitpos)
826+
{
827+
zval *object;
828+
RedisSock *redis_sock;
829+
char *key, *cmd;
830+
int key_len, cmd_len, argc, key_free=0;
831+
long bit, start, end;
832+
833+
argc = ZEND_NUM_ARGS();
834+
835+
if(zend_parse_method_parameters(argc TSRMLS_CC, getThis(), "Osl|ll",
836+
&object, redis_ce, &key, &key_len, &bit,
837+
&start, &end)==FAILURE)
838+
{
839+
RETURN_FALSE;
840+
}
841+
842+
if(redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
843+
RETURN_FALSE;
844+
}
845+
846+
// We can prevalidate the first argument
847+
if(bit != 0 && bit != 1) {
848+
RETURN_FALSE;
849+
}
850+
851+
// Prefix our key
852+
key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
853+
854+
// Various command semantics
855+
if(argc == 2) {
856+
cmd_len = redis_cmd_format_static(&cmd, "BITPOS", "sd", key, key_len,
857+
bit);
858+
} else if(argc == 3) {
859+
cmd_len = redis_cmd_format_static(&cmd, "BITPOS", "sdd", key, key_len,
860+
bit, start);
861+
} else {
862+
cmd_len = redis_cmd_format_static(&cmd, "BITPOS", "sddd", key, key_len,
863+
bit, start, end);
864+
}
865+
866+
// Free our key if it was prefixed
867+
if(key_free) efree(key);
868+
869+
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
870+
IF_ATOMIC() {
871+
redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
872+
}
873+
REDIS_PROCESS_RESPONSE(redis_long_response);
874+
}
875+
/* }}} */
876+
823877
/* {{{ proto boolean Redis::close()
824878
*/
825879
PHP_METHOD(Redis, close)

tests/TestRedis.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,25 @@ public function testBitsets() {
118118
$this->assertFalse($this->redis->setBit('key', 4294967296, 1));
119119
}
120120

121+
public function testBitPos() {
122+
if(version_compare($this->version, "2.8.7", "lt")) {
123+
$this->MarkTestSkipped();
124+
return;
125+
}
126+
127+
$this->redis->del('bpkey');
128+
129+
$this->redis->set('bpkey', "\xff\xf0\x00");
130+
$this->assertEquals($this->redis->bitpos('bpkey', 0), 12);
131+
132+
$this->redis->set('bpkey', "\x00\xff\xf0");
133+
$this->assertEquals($this->redis->bitpos('bpkey', 1, 0), 8);
134+
$this->assertEquals($this->redis->bitpos('bpkey', 1, 1), 8);
135+
136+
$this->redis->set('bpkey', "\x00\x00\x00");
137+
$this->assertEquals($this->redis->bitpos('bpkey', 1), -1);
138+
}
139+
121140
public function test1000() {
122141

123142
$s = str_repeat('A', 1000);

0 commit comments

Comments
 (0)