Skip to content

Commit 6a717c9

Browse files
gengdy1545bianhq
authored andcommitted
[Issue pixelsdb#741] add visibility structure (pixelsdb#822)
pixels-daemon: create retina rpc server. pixels-common: acts as a client and sends rpc requests to the retina server. pixels-retina: build and manage various data structures.
1 parent c2aff8a commit 6a717c9

File tree

19 files changed

+1092
-1
lines changed

19 files changed

+1092
-1
lines changed

cpp/pixels-retina/CMakeLists.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
cmake_minimum_required(VERSION 3.10)
2+
project(pixels-retina)
3+
4+
cmake_policy(SET CMP0177 NEW)
5+
6+
# Set the C++ standard
7+
set(CMAKE_CXX_STANDARD 11)
8+
set(CMAKE_CXX_STANDARD_REQUIRED True)
9+
10+
# Find Java and JNI
11+
find_package(Java REQUIRED)
12+
find_package(JNI REQUIRED)
13+
14+
# Include directories
15+
include_directories(${JAVA_INCLUDE_PATH})
16+
include_directories(${JAVA_INCLUDE_PATH2})
17+
include_directories(${CMAKE_SOURCE_DIR}/include)
18+
19+
# Source files
20+
set(SOURCES
21+
lib/visibility/Visibility_JNI.cpp
22+
lib/visibility/Visibility.cpp)
23+
24+
# Create shared library
25+
add_library(pixels-retina SHARED ${SOURCES})
26+
27+
# Set the target properties
28+
set_target_properties(pixels-retina PROPERTIES
29+
OUTPUT_NAME "pixels-retina"
30+
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
31+
32+
# Ensure the library is placed in the PIXELS_HOME directory
33+
install(TARGETS pixels-retina
34+
LIBRARY DESTINATION $ENV{PIXELS_HOME}/lib)

cpp/pixels-retina/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# DeleteTracker Native Methods
2+
Compiled here to generate shared libraries, handed over to java to load and call.
3+
4+
## How to compile
5+
```bash
6+
mkdir -p build
7+
cd build
8+
cmake ..
9+
make
10+
```
11+
12+
You can get `libDeleteTrackerNative.so` after compilation, and you can find this file in the `$PIXELS_HOME/lib` path.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2024 PixelsDB.
3+
*
4+
* This file is part of Pixels.
5+
*
6+
* Pixels is free software: you can redistribute it and/or modify
7+
* it under the terms of the Affero GNU General Public License as
8+
* published by the Free Software Foundation, either version 3 of
9+
* the License, or (at your option) any later version.
10+
*
11+
* Pixels is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* Affero GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the Affero GNU General Public
17+
* License along with Pixels. If not, see
18+
* <https://www.gnu.org/licenses/>.
19+
*/
20+
#ifndef PIXELS_RETINA_VISIBILITY_H
21+
#define PIXELS_RETINA_VISIBILITY_H
22+
23+
#define RECORDS_PER_VISIBILITY 256
24+
#define BITMAP_ARRAY_SIZE 4
25+
#define CHECKPOINT_SIZE 32
26+
#define GET_BITMAP_BIT(bitmap, rowId) (((bitmap)[(rowId) / 64] >> ((rowId) % 64)) & 1ULL)
27+
#define SET_BITMAP_BIT(bitmap, rowId) ((bitmap)[(rowId) / 64] |= (1ULL << ((rowId) % 64)))
28+
#define CLEAR_BITMAP_BIT(bitmap, rowId) ((bitmap)[(rowId) / 64] &= ~(1ULL << ((rowId) % 64)))
29+
30+
#include <vector>
31+
#include <cstdint>
32+
#include <mutex>
33+
34+
class Visibility {
35+
public:
36+
Visibility();
37+
~Visibility();
38+
39+
void getVisibilityBitmap(std::uint64_t epochTs, std::uint64_t *visibilityBitmap);
40+
void deleteRecord(int rowId, std::uint64_t epochTs);
41+
void createNewEpoch(std::uint64_t epochTs);
42+
void cleanEpochArrAndPatchArr(std::uint64_t cleanUpToEpochTs);
43+
44+
private:
45+
struct EpochEntry {
46+
std::uint64_t timestamp;
47+
std::size_t patchStartIndex;
48+
std::size_t patchEndIndex;
49+
};
50+
51+
int8_t allValue;
52+
std::uint64_t *intendDeleteBitmap;
53+
std::uint64_t *actualDeleteBitmap;
54+
std::vector<std::uint8_t> patchArr;
55+
std::vector<EpochEntry> epochArr;
56+
std::mutex mutex_;
57+
58+
std::size_t findEpoch(std::uint64_t epochTs) const;
59+
};
60+
61+
#endif //PIXELS_RETINA_VISIBILITY_H

cpp/pixels-retina/include/visibility/Visibility_JNI.h

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright 2024 PixelsDB.
3+
*
4+
* This file is part of Pixels.
5+
*
6+
* Pixels is free software: you can redistribute it and/or modify
7+
* it under the terms of the Affero GNU General Public License as
8+
* published by the Free Software Foundation, either version 3 of
9+
* the License, or (at your option) any later version.
10+
*
11+
* Pixels is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* Affero GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the Affero GNU General Public
17+
* License along with Pixels. If not, see
18+
* <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
#include "visibility/Visibility.h"
22+
#include <cstring>
23+
#include <stdexcept>
24+
25+
Visibility::Visibility() : allValue(0) {
26+
this->intendDeleteBitmap = new std::uint64_t[BITMAP_ARRAY_SIZE]();
27+
this->actualDeleteBitmap = new std::uint64_t[BITMAP_ARRAY_SIZE]();
28+
}
29+
30+
Visibility::~Visibility() {
31+
delete[] intendDeleteBitmap;
32+
delete[] actualDeleteBitmap;
33+
}
34+
35+
void Visibility::getVisibilityBitmap(std::uint64_t epochTs, std::uint64_t *visibilityBitmap) {
36+
std::lock_guard<std::mutex> lock(mutex_);
37+
38+
std::memset(visibilityBitmap, 0, sizeof(std::uint64_t) * BITMAP_ARRAY_SIZE);
39+
40+
int epochIndex = findEpoch(epochTs);
41+
std::size_t patchStart = epochArr[epochIndex].patchStartIndex;
42+
if (patchStart + CHECKPOINT_SIZE > patchArr.size()) {
43+
throw std::logic_error("Invalid state: patchStartIndex out of bound");
44+
}
45+
std::memcpy(visibilityBitmap, &patchArr[patchStart], CHECKPOINT_SIZE);
46+
47+
std::size_t patchPos = patchStart + 32;
48+
std::size_t patchEnd = epochArr[epochIndex].patchEndIndex;
49+
if (patchPos <= patchEnd && patchEnd <= patchArr.size()) {
50+
for (; patchPos < patchEnd; ++patchPos) {
51+
SET_BITMAP_BIT(visibilityBitmap, patchArr[patchPos]);
52+
}
53+
}
54+
55+
}
56+
57+
void Visibility::deleteRecord(int rowId, std::uint64_t epochTs) {
58+
std::lock_guard<std::mutex> lock(mutex_);
59+
rowId %= RECORDS_PER_VISIBILITY;
60+
if (GET_BITMAP_BIT(intendDeleteBitmap, rowId) == 0 &&
61+
GET_BITMAP_BIT(actualDeleteBitmap, rowId) == 0) {
62+
SET_BITMAP_BIT(intendDeleteBitmap, rowId);
63+
int epochIndex = findEpoch(epochTs);
64+
patchArr.push_back(static_cast<std::uint8_t>(rowId));
65+
epochArr[epochIndex].patchEndIndex += 1;
66+
} else {
67+
throw std::logic_error("Invalid state: impossible state");
68+
}
69+
70+
for (int i = 0; i < BITMAP_ARRAY_SIZE; ++i) {
71+
if (actualDeleteBitmap[i] != UINT64_MAX) {
72+
allValue = -1;
73+
return;
74+
}
75+
}
76+
allValue = 1; // all records are deleted
77+
}
78+
79+
void Visibility::createNewEpoch(std::uint64_t epochTs) {
80+
std::lock_guard<std::mutex> lock(mutex_);
81+
82+
EpochEntry newEpoch{};
83+
newEpoch.timestamp = epochTs;
84+
newEpoch.patchStartIndex = patchArr.size();
85+
86+
std::uint8_t checkpointBuf[CHECKPOINT_SIZE];
87+
std::memcpy(checkpointBuf, intendDeleteBitmap, CHECKPOINT_SIZE);
88+
89+
for (int i = 0; i < CHECKPOINT_SIZE; ++i) {
90+
patchArr.push_back(checkpointBuf[i]);
91+
}
92+
93+
newEpoch.patchEndIndex = patchArr.size();
94+
epochArr.push_back(newEpoch);
95+
}
96+
97+
std::size_t Visibility::findEpoch(std::uint64_t epochTs) const {
98+
std::size_t l = 0, r = epochArr.size() - 1;
99+
while (l <= r) {
100+
std::size_t mid = l + (r - l) / 2;
101+
if (epochArr[mid].timestamp <= epochTs) {
102+
l = mid + 1;
103+
} else {
104+
r = mid - 1;
105+
}
106+
}
107+
if (r == -1) {
108+
throw std::logic_error("Invalid state: epoch not found");
109+
}
110+
return r;
111+
}
112+
113+
void Visibility::cleanEpochArrAndPatchArr(std::uint64_t cleanUpToEpochTs) {
114+
std::lock_guard<std::mutex> lock(mutex_);
115+
std::size_t removeCount = 0;
116+
while (removeCount < epochArr.size() &&
117+
epochArr[removeCount].timestamp <= cleanUpToEpochTs) {
118+
removeCount++;
119+
}
120+
121+
if (removeCount == 0) {
122+
return;
123+
} else if (removeCount >= epochArr.size()) {
124+
throw std::logic_error("Invalid state: cannot remove all epochs");
125+
} else {
126+
std::size_t freePatchUpTo = epochArr[removeCount].patchStartIndex;
127+
patchArr.erase(patchArr.begin(), patchArr.begin() + freePatchUpTo);
128+
for (auto &epoch : epochArr) {
129+
epoch.patchStartIndex -= freePatchUpTo;
130+
epoch.patchEndIndex -= freePatchUpTo;
131+
}
132+
epochArr.erase(epochArr.begin(), epochArr.begin() + removeCount);
133+
}
134+
}

0 commit comments

Comments
 (0)