Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ jobs:
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build /tmp/slotsboxmalloc/build -j
sudo cmake --install /tmp/slotsboxmalloc/build
- name: Install kvspace ABI headers (version from deps.json)
run: |
ver=$(jq -r '.kvspace' deps.json)
git clone --depth 1 --branch "$ver" https://github.com/array2d/kvspace.git /tmp/kvspace
sudo mkdir -p /usr/local/include
sudo cp -R /tmp/kvspace/include/. /usr/local/include/
- name: 构建
run: |
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ jobs:
run: ./ci/deps.sh
- name: 构建
run: make
- name: Run C tests
run: make test
- name: Run Python wrapper tests
run: KVSPACE_C_SO=build/libkvspace-c.so python3 py/tests/test_wire.py
6 changes: 4 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ jobs:
v="${RELEASE_TAG:-${GITHUB_REF_NAME}}"
d="kvspace-c-abi-$v-linux-x86_64"
mkdir -p "$d/include" "$d/lib"
# 头:本仓无公共头(内部头在 src/),权威 ABI 头在 kvspace 仓 → 递归整目录
git clone --depth 1 https://github.com/array2d/kvspace.git /tmp/kvspace-hdr
# Copy authoritative ABI headers from the pinned kvspace tag in deps.json.
kvspace_ver=$(jq -r '.kvspace' deps.json)
test -n "$kvspace_ver" && test "$kvspace_ver" != null
git clone --depth 1 --branch "$kvspace_ver" https://github.com/array2d/kvspace.git /tmp/kvspace-hdr
cp -R /tmp/kvspace-hdr/include/. "$d/include/"
# 库:扫构建目录的所有 .so*/.dylib(-P 保符号链接)
find build -maxdepth 3 \( -name 'lib*.so*' -o -name 'lib*.dylib' \) -exec cp -P {} "$d/lib/" \;
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build/
build-test/
cmake-build-*/
*.o
*.a
Expand Down
13 changes: 8 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ if(KVSPACE_BUILD_TESTS)
target_include_directories(test_codec_abi PRIVATE src)
target_link_libraries(test_codec_abi PRIVATE kvspace-c)
add_test(NAME codec_abi COMMAND test_codec_abi)
add_executable(test_abi_contract tests/test_abi_contract.c)
target_include_directories(test_abi_contract PRIVATE src)
target_link_libraries(test_abi_contract PRIVATE kvspace-c)
add_test(NAME abi_contract COMMAND test_abi_contract)
add_executable(test_inplace_body_only tests/test_inplace_body_only.c)
target_include_directories(test_inplace_body_only PRIVATE src)
target_link_libraries(test_inplace_body_only PRIVATE kvspace-c)
add_test(NAME inplace_body_only COMMAND test_inplace_body_only)
add_executable(test_set_part_fastpath tests/test_set_part_fastpath.c)
target_include_directories(test_set_part_fastpath PRIVATE src)
target_link_libraries(test_set_part_fastpath PRIVATE kvspace-c)
Expand All @@ -80,11 +88,6 @@ if(KVSPACE_BUILD_TESTS)
target_link_libraries(test_slot_view PRIVATE kvspace-c)
add_test(NAME slot_view COMMAND test_slot_view)

add_executable(test_inplace_body_only tests/test_inplace_body_only.c)
target_include_directories(test_inplace_body_only PRIVATE src)
target_link_libraries(test_inplace_body_only PRIVATE kvspace-c)
add_test(NAME inplace_body_only COMMAND test_inplace_body_only)

add_executable(test_art_alignment tests/test_art_alignment.c)
target_include_directories(test_art_alignment PRIVATE src)
target_compile_definitions(test_art_alignment PRIVATE P2_TEST_HOOKS)
Expand Down
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
.PHONY: build clean
.PHONY: build test clean

build:
@mkdir -p build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j$$(nproc)

# Tests need the kvspace ABI headers (<kvspace/kvspace.h>) on the include path.
test:
@mkdir -p build-test && cd build-test && \
cmake -DCMAKE_BUILD_TYPE=Debug -DKVSPACE_BUILD_TESTS=ON .. && \
make -j$$(nproc) && ctest --output-on-failure

clean:
rm -rf build
rm -rf build build-test
29 changes: 19 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ Backend: `shm://` — single file-backed mmap block (ART-tree key index + slotsb

```bash
make # → build/libkvspace-c.so
make test # → build-test/, runs ctest (needs the kvspace ABI headers)
```

Dependencies: [`blockmalloc`](../blockmalloc), [`slotsboxmalloc`](../slotsboxmalloc) (header-only + `.so` dual-mode libraries).
Dependencies: [`blockmalloc`](../blockmalloc), [`slotsboxmalloc`](../slotsboxmalloc) (header-only, compiled into this library).
Tests additionally include the authoritative ABI header `<kvspace/kvspace.h>` from [`kvspace`](../kvspace) (`include/`).
`ci/deps.sh` installs all three at the versions pinned in `deps.json`.

## API

Two surfaces:

1. **Native C API** (`kvspaceShm*`) — `include/kvspace/kvspace.h`:
1. **Native C API** (`kvspaceShm*`) — `src/kvspace_shm.h` (internal header):
`kvspaceShmOpen/Close`, `kvspaceShmGet/Set`, `kvspaceShmList`, `kvspaceShmDel/Deltree`, `kvspaceShmMkindex`, `kvspaceShmExtindex/Delextindex`, `kvspaceShmNotify/Watch`.

2. **durable C ABI** — byte-compatible with `kvspace-durable` (`src/durable_abi.c`):
Expand All @@ -33,24 +36,30 @@ Two surfaces:

## XValue

Fixed 8-byte head wire format (`#566`), read/written by direct `memcpy` of the
`kvspaceXvalueHead` struct:
Fixed 8-byte head (`#566`) followed by the body and an attr region (`#571`), stored as one value under one key:

```
[len:u48 le @0-5][storetype:u8 @6][ptr:u8 @7][body @8]
[len:u48 le @0-5][storetype:u8 @6][ptr:u8 @7][body @8][attr @8+len]
attr = [attr_len:u16 le][records] attr_len includes itself; empty attr = 2
record = [tag:u8][len:u16 le][data] tag 1 = langtype (kindexpr); 2+ reserved
total = 8 + len + attr_len
```

- storetype selects short, slack, large, or extension storage; ptr marks pointer/ext.
- langtype (kindexpr) is not in the head — it lives in the `x‥langtype` attr key.
- The head is built with `kvspaceXvalueHeadNew*` constructors.
- langtype (kindexpr) is the tag-1 record of the attr region; no record = untyped.
- Values are built with the `kvspaceXvalueHeadNew*` constructors. `kvspaceSetValue`
rejects values whose attr region is missing or runs past the value.
- Store format version 6 (this wire). Stores written by older versions are refused at open; rebuild them.

## Tutorial
## Tests

```bash
python3 tutorial/test.py
make test # C tests (ctest)
KVSPACE_C_SO=build/libkvspace-c.so python3 py/tests/test_wire.py
(cd rust && cargo test) # links ../build
```

Cases: `01_basic.c`, `02_cpp.cpp`, `03_python.py`, `04_rust.rs`, `05_integrity.c`, `06_multiprocess.c`.
Cross-language tutorials live in the [`kvspace`](../kvspace) repo (`tutorial-c/`).

## Language wrappers

Expand Down
48 changes: 48 additions & 0 deletions build.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[ 3%] Building C object CMakeFiles/test_xvalue_head.dir/tests/test_xvalue_head.c.o
[ 6%] Building C object CMakeFiles/test_xvalue_head.dir/src/xvalue_head.c.o
[ 13%] Building C object CMakeFiles/kvspace-c.dir/src/xvalue_head.c.o
[ 13%] Building C object CMakeFiles/kvspace-c.dir/src/coord.c.o
[ 16%] Building C object CMakeFiles/kvspace-c.dir/src/kvspace.c.o
[ 20%] Building C object CMakeFiles/kvspace-c.dir/src/durable_abi.c.o
[ 23%] Linking C executable test_xvalue_head
[ 23%] Built target test_xvalue_head
[ 26%] Linking C shared library libkvspace-c.so
[ 26%] Built target kvspace-c
[ 30%] Building C object CMakeFiles/test_shm_split.dir/tests/test_shm_split.c.o
[ 33%] Building C object CMakeFiles/test_shm_resize.dir/tests/test_shm_resize.c.o
[ 43%] Building C object CMakeFiles/test_codec_abi.dir/tests/test_codec_abi.c.o
[ 43%] Building C object CMakeFiles/test_handle_cache.dir/tests/test_handle_cache.c.o
[ 43%] Building C object CMakeFiles/test_art_scan.dir/tests/test_art_scan.c.o
[ 46%] Building C object CMakeFiles/test_abi_contract.dir/tests/test_abi_contract.c.o
[ 50%] Building C object CMakeFiles/test_inplace_body_only.dir/tests/test_inplace_body_only.c.o
[ 56%] Building C object CMakeFiles/test_set_part_fastpath.dir/tests/test_set_part_fastpath.c.o
[ 56%] Building C object CMakeFiles/test_new_wire_shm.dir/tests/test_new_wire_shm.c.o
[ 63%] Building C object CMakeFiles/test_art_alignment.dir/tests/test_art_alignment.c.o
[ 63%] Building C object CMakeFiles/test_slot_view.dir/tests/test_slot_view.c.o
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c: In function 'run':
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c:46:18: warning: implicit declaration of function 'mkdtemp' [-Wimplicit-function-declaration]
46 | char *made = mkdtemp(dir);
| ^~~~~~~
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c:46:18: warning: initialization of 'char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
[ 66%] Linking C executable test_art_alignment
[ 70%] Linking C executable test_slot_view
[ 73%] Linking C executable test_new_wire_shm
[ 76%] Linking C executable test_codec_abi
[ 80%] Linking C executable test_inplace_body_only
[ 83%] Linking C executable test_handle_cache
[ 86%] Linking C executable test_shm_split
[ 90%] Linking C executable test_set_part_fastpath
[ 93%] Linking C executable test_shm_resize
[ 96%] Linking C executable test_art_scan
[100%] Linking C executable test_abi_contract
[100%] Built target test_art_alignment
[100%] Built target test_codec_abi
[100%] Built target test_new_wire_shm
[100%] Built target test_slot_view
[100%] Built target test_inplace_body_only
[100%] Built target test_handle_cache
[100%] Built target test_set_part_fastpath
[100%] Built target test_shm_split
[100%] Built target test_shm_resize
[100%] Built target test_art_scan
[100%] Built target test_abi_contract
40 changes: 40 additions & 0 deletions build2.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[ 10%] Built target test_xvalue_head
[ 26%] Built target kvspace-c
[ 36%] Built target test_shm_resize
[ 33%] Building C object CMakeFiles/test_inplace_body_only.dir/tests/test_inplace_body_only.c.o
[ 43%] Built target test_art_scan
[ 50%] Built target test_handle_cache
[ 63%] Built target test_codec_abi
[ 63%] Built target test_shm_split
[ 70%] Built target test_abi_contract
[ 76%] Built target test_set_part_fastpath
[ 83%] Built target test_new_wire_shm
[ 90%] Built target test_slot_view
[ 96%] Built target test_art_alignment
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c: In function 'run':
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c:46:18: warning: implicit declaration of function 'mkdtemp' [-Wimplicit-function-declaration]
46 | char *made = mkdtemp(dir);
| ^~~~~~~
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c:46:18: warning: initialization of 'char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
In file included from /tmp/resolve_kvc/prside/tests/test_inplace_body_only.c:5:
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c:122:47: error: 'sp0' undeclared (first use in this function); did you mean 'sp2'?
122 | REQUIRE(sp2.raw != NULL && sp2.len == sp0.len, "body write geometry");
| ^~~
/tmp/resolve_kvc/prside/tests/test_util.h:12:11: note: in definition of macro 'CHECK'
12 | if (!(cond)) { \
| ^~~~
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c:122:9: note: in expansion of macro 'REQUIRE'
122 | REQUIRE(sp2.raw != NULL && sp2.len == sp0.len, "body write geometry");
| ^~~~~~~
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c:122:47: note: each undeclared identifier is reported only once for each function it appears in
122 | REQUIRE(sp2.raw != NULL && sp2.len == sp0.len, "body write geometry");
| ^~~
/tmp/resolve_kvc/prside/tests/test_util.h:12:11: note: in definition of macro 'CHECK'
12 | if (!(cond)) { \
| ^~~~
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c:122:9: note: in expansion of macro 'REQUIRE'
122 | REQUIRE(sp2.raw != NULL && sp2.len == sp0.len, "body write geometry");
| ^~~~~~~
gmake[2]: *** [CMakeFiles/test_inplace_body_only.dir/build.make:76: CMakeFiles/test_inplace_body_only.dir/tests/test_inplace_body_only.c.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:315: CMakeFiles/test_inplace_body_only.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2
20 changes: 20 additions & 0 deletions build3.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[ 10%] Built target test_xvalue_head
[ 26%] Built target kvspace-c
[ 33%] Built target test_shm_split
[ 40%] Built target test_handle_cache
[ 43%] Building C object CMakeFiles/test_inplace_body_only.dir/tests/test_inplace_body_only.c.o
[ 50%] Built target test_art_scan
[ 56%] Built target test_abi_contract
[ 63%] Built target test_set_part_fastpath
[ 70%] Built target test_codec_abi
[ 76%] Built target test_slot_view
[ 86%] Built target test_art_alignment
[ 90%] Built target test_new_wire_shm
[ 96%] Built target test_shm_resize
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c: In function 'run':
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c:46:18: warning: implicit declaration of function 'mkdtemp' [-Wimplicit-function-declaration]
46 | char *made = mkdtemp(dir);
| ^~~~~~~
/tmp/resolve_kvc/prside/tests/test_inplace_body_only.c:46:18: warning: initialization of 'char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
[100%] Linking C executable test_inplace_body_only
[100%] Built target test_inplace_body_only
15 changes: 15 additions & 0 deletions cfg.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- The C compiler identification is GNU 13.3.0
-- The CXX compiler identification is GNU 13.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (0.5s)
-- Generating done (0.0s)
-- Build files have been written to: /tmp/resolve_kvc/prside/build
1 change: 1 addition & 0 deletions deps.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"blockmalloc": "v0.1.5",
"kvspace": "v0.3.23",
"slotsboxmalloc": "v0.1.7"
}
Loading
Loading