Skip to content

Instantly share code, notes, and snippets.

@lbe
Last active August 14, 2022 07:54
Show Gist options
  • Save lbe/6b43e3d35ffb090fec2fe281e5573cae to your computer and use it in GitHub Desktop.
Save lbe/6b43e3d35ffb090fec2fe281e5573cae to your computer and use it in GitHub Desktop.
sqlite3 extension to calculate the bit population - not working!
/* compile osx
* gcc -bundle -fPIC -O3 -o popcount.dylib popcount.c
* */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sqlite3ext.h>
SQLITE_EXTENSION_INIT1
int calculate_popcount(uint64_t value){
value -= (value >> 1) & 0x5555555555555555;
value = (value & 0x3333333333333333) + ((value >> 2) & 0x3333333333333333);
value = (value + (value >> 4)) & 0x0f0f0f0f0f0f0f0f;
return (value * 0x0101010101010101) >> 56;
}
static void popcount(sqlite3_context *context, int argc, sqlite3_value **argv){
if( argc<1 ) return;
uint64_t rVal;
//int result;
int datatype_arg1, datatype_arg2;
if (argc >= 1){
datatype_arg1 = sqlite3_value_type(argv[0]);
}
if (argc >= 2) {
datatype_arg2 = sqlite3_value_type(argv[1]);
}
if (argc == 1 && (datatype_arg1 == SQLITE_INTEGER || datatype_arg1 == SQLITE_FLOAT)) {
rVal = sqlite3_value_int64(argv[0]);
rVal = calculate_popcount(rVal);
sqlite3_result_int(context, rVal);
}
else if (
argc >= 2 &&
(datatype_arg1 == SQLITE_INTEGER || datatype_arg1 == SQLITE_FLOAT) &&
(datatype_arg2 == SQLITE_INTEGER || datatype_arg2 == SQLITE_FLOAT)) {
rVal = sqlite3_value_int64(argv[0]);
uint64_t num1 = sqlite3_value_int64(argv[0]);
uint64_t num2 = sqlite3_value_int64(argv[1]);
rVal = calculate_popcount(num1 ^ num2);
sqlite3_result_int(context, rVal);
}
else {
sqlite3_result_null(context);
return;
}
}
/*
int init_sqlite(sqlite3 *db){
//sqlite3_create_function(db, "popcount", -1, SQLITE_ANY, 0, popcount, 0, 0);
return 0;
}
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_extension_init(
sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi){
//int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
//init_sqlite(db);
return SQLITE_OK == sqlite3_create_function(db, "popcount", -1, SQLITE_ANY | SQLITE_DETERMINISTIC, 0, popcount, 0, 0) ? SQLITE_OK : SQLITE_ERROR;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment