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": {
|
||||
"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": {
|
||||
"locked": {
|
||||
"lastModified": 1712192574,
|
||||
"narHash": "sha256-LbbVOliJKTF4Zl2b9salumvdMXuQBr2kuKP5+ZwbYq4=",
|
||||
"lastModified": 1701282334,
|
||||
"narHash": "sha256-MxCVrXY6v4QmfTwIysjjaX0XUhqBbxTWWB4HXtDYsdk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f480f9d09e4b4cf87ee6151eba068197125714de",
|
||||
"rev": "057f9aecfb71c4437d2b27d3323df7f93c010b7e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"ref": "23.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
"nixpkgs": "nixpkgs",
|
||||
"utils": "utils"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
|
@ -54,6 +36,24 @@
|
|||
"repo": "default",
|
||||
"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",
|
||||
|
|
98
flake.nix
98
flake.nix
|
@ -2,58 +2,54 @@
|
|||
description = "A sparse bitmapped index library in C.";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
# nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/23.11";
|
||||
utils.url = "github:numtide/flake-utils";
|
||||
utils.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{ self
|
||||
, nixpkgs
|
||||
, flake-utils
|
||||
, ...
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
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;
|
||||
outputs = { self, nixpkgs, ... }
|
||||
@inputs: inputs.utils.lib.eachSystem [
|
||||
"x86_64-linux" "i686-linux" "aarch64-linux" "x86_64-darwin"
|
||||
] (system:
|
||||
let pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [];
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
});
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
for (size_t i = 0; i < sizeof(sm_bitvec_t); i++, p++) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
*pos += idx;
|
||||
*pos += idx + 1;
|
||||
if (value == false) {
|
||||
if (*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;
|
||||
}
|
||||
} else {
|
||||
*pos += idx;
|
||||
*pos += idx + 1;
|
||||
if (value == true) {
|
||||
if (*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;
|
||||
*offset = (*offset > SM_BITS_PER_VECTOR) ? *offset - SM_BITS_PER_VECTOR : 0;
|
||||
} else {
|
||||
*pos += idx;
|
||||
*pos += idx + 1;
|
||||
sm_bitvec_t mw;
|
||||
uint64_t mask;
|
||||
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)
|
||||
{
|
||||
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);
|
||||
uint8_t *p = __sm_get_chunk_map_data(map, 0);
|
||||
size_t amt, gap, pos = 0, result = 0, prev = 0, count;
|
||||
uint8_t *p;
|
||||
|
||||
count = __sm_get_chunk_map_count(map);
|
||||
|
||||
if (count == 0) {
|
||||
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++) {
|
||||
sm_idx_t start = *(sm_idx_t *)p;
|
||||
gap = start - (prev == 0 ? start : prev);
|
||||
(void)gap; // TODO... necessary?
|
||||
gap = start - prev; /* [prev, start), prev is the last bit examined 0-based */
|
||||
/* Start of this chunk is greater than the end of the desired range. */
|
||||
if (start > y) {
|
||||
/* This chunk starts after our range [x, y]. */
|
||||
if (value == true) {
|
||||
return result;
|
||||
} else {
|
||||
/* This chunk starts after our range [x, y]. */
|
||||
return result + (y - x) + 1;
|
||||
}
|
||||
} else {
|
||||
/* The range and this chunk overlap. */
|
||||
if (value == false) {
|
||||
if (x > start) {
|
||||
x -= start;
|
||||
if (x > gap) {
|
||||
x -= gap;
|
||||
} else {
|
||||
result += start - x;
|
||||
result += gap - x;
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = start;
|
||||
prev = start - 1;
|
||||
p += sizeof(sm_idx_t);
|
||||
__sm_chunk_t chunk;
|
||||
__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
|
||||
within the range. */
|
||||
if (value == false) {
|
||||
size_t last = prev + pos - 1;
|
||||
size_t last = prev + pos;
|
||||
if (y > last) {
|
||||
result += y - last;
|
||||
result += y - last - x;
|
||||
}
|
||||
}
|
||||
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_set(map, hole, true);
|
||||
#if 1
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
sparsemap_clear(map);
|
||||
sparsemap_set(map, 1, true);
|
||||
sparsemap_set(map, 11, true);
|
||||
r = sparsemap_rank(map, 0, 11, false);
|
||||
|
|
Loading…
Reference in a new issue