rank true/false working

This commit is contained in:
Gregory Burd 2024-04-24 13:16:37 -04:00
parent 4cfecc045e
commit e36f5699fe
4 changed files with 98 additions and 101 deletions

View file

@ -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",

View file

@ -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;
});
}

View file

@ -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;

View file

@ -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);