Skip to content

Commit

Permalink
Merge pull request #4 from SalvatorePreviti/roaring_bitmap_contains_r…
Browse files Browse the repository at this point in the history
…ange

Roaring bitmap ranges (add, contains)
  • Loading branch information
SalvatorePreviti authored Jun 16, 2018
2 parents ba37883 + 4f17673 commit 4a487e2
Show file tree
Hide file tree
Showing 6 changed files with 405 additions and 17 deletions.
43 changes: 31 additions & 12 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ declare class RoaringBitmap32 implements Iterable<number> {
*/
public has(value: number): boolean

/**
*
* @param rangeStart The start index. Must be an non-negative number less or equal to 4294967296.
* @param rangeEnd The end index. Must be a non-negative number less or equal to 4294967297.
*/
public hasRange(rangeStart: number, rangeEnd: number): boolean

/**
* Overwrite the content of this bitmap copying it from an Iterable or another RoaringBitmap32.
* This function is optimized for copying RoaringBitmap32 instances.
Expand Down Expand Up @@ -203,6 +210,28 @@ declare class RoaringBitmap32 implements Iterable<number> {
*/
public removeMany(values: Iterable<number>): this

/**
* Negates (in place) the roaring bitmap within a specified interval: [rangeStart, rangeEnd).
* First element is included, last element is excluded.
* The number of negated values is rangeEnd - rangeStart.
* Areas outside the range are passed through unchanged.
*
* @param rangeStart The start index. Trimmed to 0.
* @param rangeEnd The end index. Trimmed to 4294967297.
*/
public flipRange(rangeStart: number, rangeEnd: number): void

/**
* Adds all the values in the interval: [rangeStart, rangeEnd).
* First element is included, last element is excluded.
* The number of added values is rangeEnd - rangeStart.
* Areas outside the range are passed through unchanged.
*
* @param rangeStart The start index. Trimmed to 0.
* @param rangeEnd The end index. Trimmed to 4294967297.
*/
public addRange(rangeStart: number, rangeEnd: number): void

/**
* Removes all values from the set.
* It frees resources, if needed you can use clear to free some memory before the garbage collector disposes this instance.
Expand Down Expand Up @@ -343,16 +372,6 @@ declare class RoaringBitmap32 implements Iterable<number> {
*/
public jaccardIndex(other: RoaringBitmap32): number

/**
* Negates in place all the values within a specified interval.
* Areas outside the range are passed through unchanged.
* The function does nothing if values are not valid unsigned 32 bit integers.
*
* @param rangeStart The start index. Must be a 32 bit integer.
* @param rangeEnd The end index. Must be a 32 bit integer.
*/
public flipRange(rangeStart: number, rangeEnd: number): void

/**
* Remove run-length encoding even when it is more space efficient.
* Return whether a change was applied.
Expand Down Expand Up @@ -465,9 +484,9 @@ declare class RoaringBitmap32 implements Iterable<number> {

/**
* Returns a standard string representation of the content of this RoaringBitmap32 instance. It may return a very long string.
* Default max length is 260000, everything after around maxLength is truncated (ellipsis added).
* Default max length is 32000 characters, everything after maxLength is truncated (ellipsis added).
*
* @param maxLength Approximate maximum length of the string. Ellipsis will be added.
* @param maxLength Approximate maximum length of the string. Ellipsis will be added if the string is longer.
* @returns A string in the format "[1,2,3...]"
*/
public contentToString(maxLength?: number): string
Expand Down
2 changes: 1 addition & 1 deletion src/cpp/CRoaringUnityBuild
Submodule CRoaringUnityBuild updated 3 files
+114 −58 roaring.c
+512 −75 roaring.h
+19 −5 roaring.hh
37 changes: 35 additions & 2 deletions src/cpp/RoaringBitmap32/RoaringBitmap32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ void RoaringBitmap32::Init(v8::Local<v8::Object> exports) {

Nan::SetPrototypeMethod(ctor, "minimum", minimum);
Nan::SetPrototypeMethod(ctor, "maximum", maximum);
Nan::SetPrototypeMethod(ctor, "has", has);
Nan::SetPrototypeMethod(ctor, "contains", has);
Nan::SetPrototypeMethod(ctor, "has", has);
Nan::SetPrototypeMethod(ctor, "containsRange", hasRange);
Nan::SetPrototypeMethod(ctor, "hasRange", hasRange);
Nan::SetPrototypeMethod(ctor, "copyFrom", copyFrom);
Nan::SetPrototypeMethod(ctor, "add", add);
Nan::SetPrototypeMethod(ctor, "tryAdd", tryAdd);
Expand All @@ -52,6 +54,7 @@ void RoaringBitmap32::Init(v8::Local<v8::Object> exports) {
Nan::SetPrototypeMethod(ctor, "xorCardinality", xorCardinality);
Nan::SetPrototypeMethod(ctor, "jaccardIndex", jaccardIndex);
Nan::SetPrototypeMethod(ctor, "flipRange", flipRange);
Nan::SetPrototypeMethod(ctor, "addRange", addRange);
Nan::SetPrototypeMethod(ctor, "removeRunCompression", removeRunCompression);
Nan::SetPrototypeMethod(ctor, "runOptimize", runOptimize);
Nan::SetPrototypeMethod(ctor, "shrinkToFit", shrinkToFit);
Expand Down Expand Up @@ -184,6 +187,36 @@ void RoaringBitmap32::has(const Nan::FunctionCallbackInfo<v8::Value> & info) {
}
}

void RoaringBitmap32::hasRange(const Nan::FunctionCallbackInfo<v8::Value> & info) {
if (info.Length() < 2 || !info[0]->IsNumber() || !info[1]->IsNumber()) {
return info.GetReturnValue().Set(false);
}

double minimum = info[0]->NumberValue();
double maximum = info[1]->NumberValue();

if (std::isnan(minimum) || std::isnan(maximum)) {
return info.GetReturnValue().Set(false);
}

minimum = std::ceil(minimum);
maximum = std::ceil(maximum);
if (minimum < 0 || maximum > 4294967296) {
return info.GetReturnValue().Set(false);
}

uint64_t minInteger = (uint64_t)minimum;
uint64_t maxInteger = (uint64_t)maximum;

if (minInteger >= maxInteger || maxInteger > 4294967296) {
return info.GetReturnValue().Set(false);
}

RoaringBitmap32 * self = Nan::ObjectWrap::Unwrap<RoaringBitmap32>(info.Holder());

info.GetReturnValue().Set(roaring_bitmap_contains_range(&self->roaring, minInteger, maxInteger));
}

void RoaringBitmap32::minimum(const Nan::FunctionCallbackInfo<v8::Value> & info) {
RoaringBitmap32 * self = Nan::ObjectWrap::Unwrap<RoaringBitmap32>(info.Holder());
return info.GetReturnValue().Set(roaring_bitmap_minimum(&self->roaring));
Expand Down Expand Up @@ -277,7 +310,7 @@ void RoaringBitmap32::contentToString(const Nan::FunctionCallbackInfo<v8::Value>
struct iter_data {
std::string str;
char first_char = '[';
uint64_t maxLen = 260000;
uint64_t maxLen = 32000;
} iterData;

if (info.Length() >= 1 && info[0]->IsNumber()) {
Expand Down
3 changes: 3 additions & 0 deletions src/cpp/RoaringBitmap32/RoaringBitmap32.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define __ROARINGBITMAP32__H__

#include <nan.h>
#include <cmath>
#include "../roaring.h"

class RoaringBitmap32;
Expand All @@ -22,6 +23,7 @@ class RoaringBitmap32 : public Nan::ObjectWrap {

static void New(const Nan::FunctionCallbackInfo<v8::Value> & info);
static void has(const Nan::FunctionCallbackInfo<v8::Value> & info);
static void hasRange(const Nan::FunctionCallbackInfo<v8::Value> & info);
static void copyFrom(const Nan::FunctionCallbackInfo<v8::Value> & info);
static void add(const Nan::FunctionCallbackInfo<v8::Value> & info);
static void tryAdd(const Nan::FunctionCallbackInfo<v8::Value> & info);
Expand All @@ -44,6 +46,7 @@ class RoaringBitmap32 : public Nan::ObjectWrap {
static void xorCardinality(const Nan::FunctionCallbackInfo<v8::Value> & info);
static void jaccardIndex(const Nan::FunctionCallbackInfo<v8::Value> & info);
static void flipRange(const Nan::FunctionCallbackInfo<v8::Value> & info);
static void addRange(const Nan::FunctionCallbackInfo<v8::Value> & info);
static void rank(const Nan::FunctionCallbackInfo<v8::Value> & info);
static void select(const Nan::FunctionCallbackInfo<v8::Value> & info);

Expand Down
44 changes: 42 additions & 2 deletions src/cpp/RoaringBitmap32/RoaringBitmap32_operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,50 @@ void RoaringBitmap32::clear(const Nan::FunctionCallbackInfo<v8::Value> & info) {
self->roaring.high_low_container = std::move(newRoaring.high_low_container);
}

inline static bool getRangeOperationParameters(const Nan::FunctionCallbackInfo<v8::Value> & info, uint64_t & minInteger, uint64_t & maxInteger) {
if (info.Length() < 2 || !info[0]->IsNumber() || !info[1]->IsNumber()) {
return false;
}

double minimum = info[0]->NumberValue();
if (std::isnan(minimum)) {
return false;
}

double maximum = info[1]->NumberValue();
if (std::isnan(maximum)) {
return false;
}

if (minimum < 0) {
minimum = 0;
}

if (maximum < 0) {
maximum = 0;
} else if (maximum > 4294967296) {
maximum = 4294967296;
}

minInteger = (uint64_t)minimum;
maxInteger = (uint64_t)maximum;

return minInteger < maxInteger;
}

void RoaringBitmap32::flipRange(const Nan::FunctionCallbackInfo<v8::Value> & info) {
if (info.Length() >= 2 && info[0]->IsUint32() && info[1]->IsUint32()) {
uint64_t minInteger, maxInteger;
if (getRangeOperationParameters(info, minInteger, maxInteger)) {
RoaringBitmap32 * self = Nan::ObjectWrap::Unwrap<RoaringBitmap32>(info.Holder());
roaring_bitmap_flip_inplace(&self->roaring, minInteger, maxInteger);
}
}

void RoaringBitmap32::addRange(const Nan::FunctionCallbackInfo<v8::Value> & info) {
uint64_t minInteger, maxInteger;
if (getRangeOperationParameters(info, minInteger, maxInteger)) {
RoaringBitmap32 * self = Nan::ObjectWrap::Unwrap<RoaringBitmap32>(info.Holder());
roaring_bitmap_flip_inplace(&self->roaring, info[0]->Uint32Value(), info[1]->Uint32Value());
roaring_bitmap_add_range_closed(&self->roaring, (uint32_t)minInteger, (uint32_t)(maxInteger - 1));
}
}

Expand Down
Loading

0 comments on commit 4a487e2

Please sign in to comment.