rank true/false working
This commit is contained in:
parent
4cfecc045e
commit
e36f5699fe
4 changed files with 98 additions and 101 deletions
48
flake.lock
48
flake.lock
|
@ -1,43 +1,25 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"flake-utils": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1710146030,
|
|
||||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1712192574,
|
"lastModified": 1701282334,
|
||||||
"narHash": "sha256-LbbVOliJKTF4Zl2b9salumvdMXuQBr2kuKP5+ZwbYq4=",
|
"narHash": "sha256-MxCVrXY6v4QmfTwIysjjaX0XUhqBbxTWWB4HXtDYsdk=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "f480f9d09e4b4cf87ee6151eba068197125714de",
|
"rev": "057f9aecfb71c4437d2b27d3323df7f93c010b7e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "nixpkgs-unstable",
|
"ref": "23.11",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixpkgs": "nixpkgs"
|
"utils": "utils"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
|
@ -54,6 +36,24 @@
|
||||||
"repo": "default",
|
"repo": "default",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1710146030,
|
||||||
|
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|
98
flake.nix
98
flake.nix
|
@ -2,58 +2,54 @@
|
||||||
description = "A sparse bitmapped index library in C.";
|
description = "A sparse bitmapped index library in C.";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
# nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
nixpkgs.url = "github:NixOS/nixpkgs/23.11";
|
||||||
|
utils.url = "github:numtide/flake-utils";
|
||||||
|
utils.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs = { self, nixpkgs, ... }
|
||||||
{ self
|
@inputs: inputs.utils.lib.eachSystem [
|
||||||
, nixpkgs
|
"x86_64-linux" "i686-linux" "aarch64-linux" "x86_64-darwin"
|
||||||
, flake-utils
|
] (system:
|
||||||
, ...
|
let pkgs = import nixpkgs {
|
||||||
}:
|
inherit system;
|
||||||
flake-utils.lib.eachDefaultSystem (system:
|
overlays = [];
|
||||||
let
|
config.allowUnfree = true;
|
||||||
pkgs = import nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
config = { allowUnfree = true; };
|
|
||||||
};
|
|
||||||
supportedSystems = [ "x86_64-linux" ];
|
|
||||||
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
|
|
||||||
nixpkgsFor = forAllSystems (system: import nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
overlays = [ self.overlay ];
|
|
||||||
});
|
|
||||||
in {
|
|
||||||
pkgs = import nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
devShell = nixpkgs.legacyPackages.${system} {
|
|
||||||
pkgs.mkShell = {
|
|
||||||
nativeBuildInputs = with pkgs.buildPackages; [
|
|
||||||
act
|
|
||||||
autoconf
|
|
||||||
clang
|
|
||||||
ed
|
|
||||||
gcc
|
|
||||||
gdb
|
|
||||||
gettext
|
|
||||||
graphviz-nox
|
|
||||||
libtool
|
|
||||||
m4
|
|
||||||
perl
|
|
||||||
pkg-config
|
|
||||||
python3
|
|
||||||
ripgrep
|
|
||||||
valgrind
|
|
||||||
];
|
|
||||||
buildInputs = with pkgs; [
|
|
||||||
libbacktrace
|
|
||||||
glibc.out
|
|
||||||
glibc.static
|
|
||||||
];
|
|
||||||
};
|
|
||||||
DOCKER_BUILDKIT = 1;
|
|
||||||
};
|
};
|
||||||
};
|
in {
|
||||||
});
|
devShell = pkgs.mkShell rec {
|
||||||
|
name = "sparsemap";
|
||||||
|
packages = with pkgs; [
|
||||||
|
act
|
||||||
|
autoconf
|
||||||
|
clang
|
||||||
|
ed
|
||||||
|
gcc
|
||||||
|
gdb
|
||||||
|
gettext
|
||||||
|
graphviz-nox
|
||||||
|
libtool
|
||||||
|
m4
|
||||||
|
perl
|
||||||
|
pkg-config
|
||||||
|
python3
|
||||||
|
ripgrep
|
||||||
|
valgrind
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
libbacktrace
|
||||||
|
glibc.out
|
||||||
|
glibc.static
|
||||||
|
];
|
||||||
|
|
||||||
|
shellHook = let
|
||||||
|
icon = "f121";
|
||||||
|
in ''
|
||||||
|
export PS1="$(echo -e '\u${icon}') {\[$(tput sgr0)\]\[\033[38;5;228m\]\w\[$(tput sgr0)\]\[\033[38;5;15m\]} (${name}) \\$ \[$(tput sgr0)\]"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
DOCKER_BUILDKIT = 1;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -490,6 +490,14 @@ __sm_chunk_map_rank(__sm_chunk_t *map, size_t *offset, size_t idx, size_t *pos,
|
||||||
|
|
||||||
*pos = 0;
|
*pos = 0;
|
||||||
|
|
||||||
|
/* A chunk can only hold at most SM_CHUNK_MAX_CAPACITY bits, so if the
|
||||||
|
offset is larger than that, we're basically done. */
|
||||||
|
if (*offset > SM_CHUNK_MAX_CAPACITY) {
|
||||||
|
*pos = SM_CHUNK_MAX_CAPACITY;
|
||||||
|
*offset -= SM_CHUNK_MAX_CAPACITY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
register uint8_t *p = (uint8_t *)map->m_data;
|
register uint8_t *p = (uint8_t *)map->m_data;
|
||||||
for (size_t i = 0; i < sizeof(sm_bitvec_t); i++, p++) {
|
for (size_t i = 0; i < sizeof(sm_bitvec_t); i++, p++) {
|
||||||
for (int j = 0; j < SM_FLAGS_PER_INDEX_BYTE; j++) {
|
for (int j = 0; j < SM_FLAGS_PER_INDEX_BYTE; j++) {
|
||||||
|
@ -511,7 +519,7 @@ __sm_chunk_map_rank(__sm_chunk_t *map, size_t *offset, size_t idx, size_t *pos,
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*pos += idx;
|
*pos += idx + 1;
|
||||||
if (value == false) {
|
if (value == false) {
|
||||||
if (*offset > idx) {
|
if (*offset > idx) {
|
||||||
*offset = *offset - idx;
|
*offset = *offset - idx;
|
||||||
|
@ -538,7 +546,7 @@ __sm_chunk_map_rank(__sm_chunk_t *map, size_t *offset, size_t idx, size_t *pos,
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*pos += idx;
|
*pos += idx + 1;
|
||||||
if (value == true) {
|
if (value == true) {
|
||||||
if (*offset > idx) {
|
if (*offset > idx) {
|
||||||
*offset = *offset - idx;
|
*offset = *offset - idx;
|
||||||
|
@ -567,7 +575,7 @@ __sm_chunk_map_rank(__sm_chunk_t *map, size_t *offset, size_t idx, size_t *pos,
|
||||||
ret += pc;
|
ret += pc;
|
||||||
*offset = (*offset > SM_BITS_PER_VECTOR) ? *offset - SM_BITS_PER_VECTOR : 0;
|
*offset = (*offset > SM_BITS_PER_VECTOR) ? *offset - SM_BITS_PER_VECTOR : 0;
|
||||||
} else {
|
} else {
|
||||||
*pos += idx;
|
*pos += idx + 1;
|
||||||
sm_bitvec_t mw;
|
sm_bitvec_t mw;
|
||||||
uint64_t mask;
|
uint64_t mask;
|
||||||
uint64_t idx_mask = (idx == 63) ? UINT64_MAX : ((uint64_t)1 << (idx + 1)) - 1;
|
uint64_t idx_mask = (idx == 63) ? UINT64_MAX : ((uint64_t)1 << (idx + 1)) - 1;
|
||||||
|
@ -1326,8 +1334,10 @@ size_t
|
||||||
sparsemap_rank_vec(sparsemap_t *map, size_t x, size_t y, bool value, sm_bitvec_t *vec)
|
sparsemap_rank_vec(sparsemap_t *map, size_t x, size_t y, bool value, sm_bitvec_t *vec)
|
||||||
{
|
{
|
||||||
assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
||||||
size_t amt = 0, gap, pos = 0, result = 0, prev = 0, count = __sm_get_chunk_map_count(map);
|
size_t amt, gap, pos = 0, result = 0, prev = 0, count;
|
||||||
uint8_t *p = __sm_get_chunk_map_data(map, 0);
|
uint8_t *p;
|
||||||
|
|
||||||
|
count = __sm_get_chunk_map_count(map);
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
if (value == false) {
|
if (value == false) {
|
||||||
|
@ -1336,30 +1346,31 @@ sparsemap_rank_vec(sparsemap_t *map, size_t x, size_t y, bool value, sm_bitvec_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p = __sm_get_chunk_map_data(map, 0);
|
||||||
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
sm_idx_t start = *(sm_idx_t *)p;
|
sm_idx_t start = *(sm_idx_t *)p;
|
||||||
gap = start - (prev == 0 ? start : prev);
|
gap = start - prev; /* [prev, start), prev is the last bit examined 0-based */
|
||||||
(void)gap; // TODO... necessary?
|
|
||||||
/* Start of this chunk is greater than the end of the desired range. */
|
/* Start of this chunk is greater than the end of the desired range. */
|
||||||
if (start > y) {
|
if (start > y) {
|
||||||
|
/* This chunk starts after our range [x, y]. */
|
||||||
if (value == true) {
|
if (value == true) {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
/* This chunk starts after our range [x, y]. */
|
|
||||||
return result + (y - x) + 1;
|
return result + (y - x) + 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* The range and this chunk overlap. */
|
/* The range and this chunk overlap. */
|
||||||
if (value == false) {
|
if (value == false) {
|
||||||
if (x > start) {
|
if (x > gap) {
|
||||||
x -= start;
|
x -= gap;
|
||||||
} else {
|
} else {
|
||||||
result += start - x;
|
result += gap - x;
|
||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prev = start;
|
prev = start - 1;
|
||||||
p += sizeof(sm_idx_t);
|
p += sizeof(sm_idx_t);
|
||||||
__sm_chunk_t chunk;
|
__sm_chunk_t chunk;
|
||||||
__sm_chunk_map_init(&chunk, p);
|
__sm_chunk_map_init(&chunk, p);
|
||||||
|
@ -1372,9 +1383,9 @@ sparsemap_rank_vec(sparsemap_t *map, size_t x, size_t y, bool value, sm_bitvec_t
|
||||||
/* Count any additional unset bits that fall outside the last chunk but
|
/* Count any additional unset bits that fall outside the last chunk but
|
||||||
within the range. */
|
within the range. */
|
||||||
if (value == false) {
|
if (value == false) {
|
||||||
size_t last = prev + pos - 1;
|
size_t last = prev + pos;
|
||||||
if (y > last) {
|
if (y > last) {
|
||||||
result += y - last;
|
result += y - last - x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
14
tests/test.c
14
tests/test.c
|
@ -820,28 +820,18 @@ test_api_rank_false(const MunitParameter params[], void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// one chunk means not so empty now!
|
// One chunk means not so empty now!
|
||||||
sparsemap_idx_t hole = 4999;
|
sparsemap_idx_t hole = 4999;
|
||||||
sparsemap_set(map, hole, true);
|
sparsemap_set(map, hole, true);
|
||||||
#if 1
|
|
||||||
for (int i = 0; i < 10000; i++) {
|
for (int i = 0; i < 10000; i++) {
|
||||||
for (int j = i; j < 10000; j++) {
|
for (int j = i; j < 10000; j++) {
|
||||||
#else
|
|
||||||
for (int i = 7041; i < 10000; i++) {
|
|
||||||
for (int j = 7040; j < 10000; j++) {
|
|
||||||
#endif
|
|
||||||
int amt = j - i + 1 - ((hole >= i && j >= hole) ? 1 : 0);
|
int amt = j - i + 1 - ((hole >= i && j >= hole) ? 1 : 0);
|
||||||
r = sparsemap_rank(map, i, j, false);
|
r = sparsemap_rank(map, i, j, false);
|
||||||
#ifdef DEBUG
|
|
||||||
if (r != amt) {
|
|
||||||
printf("\033[2K\r");
|
|
||||||
printf("%d\t%d\t--\t%d\t%d", i, j, amt, r);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
assert_true(r == amt);
|
assert_true(r == amt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sparsemap_clear(map);
|
||||||
sparsemap_set(map, 1, true);
|
sparsemap_set(map, 1, true);
|
||||||
sparsemap_set(map, 11, true);
|
sparsemap_set(map, 11, true);
|
||||||
r = sparsemap_rank(map, 0, 11, false);
|
r = sparsemap_rank(map, 0, 11, false);
|
||||||
|
|
Loading…
Reference in a new issue