-
Notifications
You must be signed in to change notification settings - Fork 23.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added BITPOS command to return offsets of set bits in a key. #1295
base: unstable
Are you sure you want to change the base?
Conversation
Hey, I'm not 100% sure about this. I also attempted the standard approach of Here's a little integration benchmark I've written: https://gist.github.com/dim/6775254
|
Thank you for your benchmark. Because it requires an excess amount of memory to store the bit positions in an intermediate array, your patch only works for small bitsets, which it appears you're testing with. Our bitsets range from 10 to 100 million bits, which is where we encountered crashes caused by your patch. For example, set bit 1048576 and give it a try. You'll get:
Upon inspection, this is because res is 0x0. Your patch assumes the allocation will be successful, which it is on your smaller bitsets. But since the patch isn't checking the allocation, when it fails to allocate the array, it crashes when attempting to store the first set bit. While you should always verify an allocation was successful, the method you chose to use to dynamically allocate the array was inappropriate. This is because C99 defines variable length arrays to be deallocated automatically when the array goes out of scope. To reduce the variability in performance and simplify implementation, most compilers implement this by allocating VLAs from the stack rather than from the heap, which means the size of your array is limited to the maximum allocation from the stack. You can specifically allocate from the heap by changing line 471 from: long res[bytecount*8]; to long *res = (long *) zmalloc (sizeof(long) * bytecount); And, accordingly, freeing it on line 497: zfree(res); This works fine. But the allocation isn't without cost. On large, especially sparse, arrays, it takes more time and memory to allocate the memory for the intermediate array than it does to return the bits which are set. |
I'm wondering if anyone actually looks at these pull requests. This functionality is used quite a bit by multiple people, but no response or comment has been made. |
We have BITPOS now in Redis. I'm wondering if it has enough functionality compared to your proposed solution? |
It's not the same command we had been proposing. Whereas the proposed function returns all set bits, BITPOS, as implemented, really only returns the first bit. |
Yep, an option to pass a limit or range would make it complete.
|
FYI: I added your command (renamed to Usage example: 127.0.0.1:6379> config set module-add /Users/matt/repos/krmt/bitallpos.so
OK
127.0.0.1:6379> set abc 3
OK
127.0.0.1:6379> bitallpos abc
1) "2"
2) "3"
3) "6"
4) "7"
127.0.0.1:6379> setbit try 0 1
(integer) 0
127.0.0.1:6379> bitallpos try
1) "0"
127.0.0.1:6379> setbit try 72 1
(integer) 0
127.0.0.1:6379> bitallpos try
1) "0"
2) "72"
127.0.0.1:6379> setbit try 954 1
(integer) 0
127.0.0.1:6379> bitallpos try
1) "0"
2) "72"
3) "954"
127.0.0.1:6379> setbit try 8000001 1
(integer) 0
127.0.0.1:6379> bitallpos try
1) "0"
2) "72"
3) "954"
4) "8000001" |
I like the loadable module. I haven't played with writing one before. |
Jonah H. Harris seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
This pull request adds a command, BITPOS key [start] [end] [limit], which returns a bulk reply containing the offsets of set bits in the given key.