Skip to content

Feat/search api - #472

Open
Uriagat wants to merge 62 commits into
develfrom
feat/search-api
Open

Feat/search api#472
Uriagat wants to merge 62 commits into
develfrom
feat/search-api

Conversation

@Uriagat

@Uriagat Uriagat commented Aug 4, 2026

Copy link
Copy Markdown
Member

No description provided.

kisielewski and others added 30 commits October 31, 2025 16:12
Replaced manual string construction from istreambuf_iterator with
Poco::StreamCopier::copyToString for improved readability and reliability.
Reserve string capacity based on response content length to improve
performance and reduce reallocations when reading the HTTP response.
Modified file corruption check to skip exception when original file
size is zero, preventing false positives for empty files.
Adjusted stopIndex computation to correctly handle zero-length data,
preventing out-of-range chunk index calculation.
Modified UpdateChunkData calculation to use std::max when truncating,
ensuring that size deltas do not become negative for partially filled chunks.
Moved squashedChanges reference inside the loop to avoid
overwriting it incorrectly when pushing new UpdateChanges,
ensuring proper merging of consecutive chunks.
Removed file size bounds verification in seekg and seekp to allow
seeking beyond current file size, deferring validation to later operations.
mplemented a function to sanitize file paths so that they comply with
the Bridge server requirements. The function replaces unsupported
characters with allowed ones ('/', '_', ':', '-') and removes whitespaces.
Handled the case where opening the SQLite database file fails,
preventing a segmentation fault. Additionally, fixed a memory leak
that occurred when the database file was opened successfully, ensuring
proper resource cleanup in all cases.
Uriagat and others added 22 commits March 11, 2026 16:00
* test: e2e testing for StreamApi

* test: fix StreamApi

* test: fix: e2e_runner

* test: new Dataset

* test: searchApi

* fix: searchApi reading kvdbEntry

* chore: cleanup

* test: searchApi new tests

* test: fix searchApi

* test: Dataset update

* test: Dataset Update
* fix: searchApi loop when kvdb data decrypt failed

* fix: small fix + more logegrs
…ile size (#436)

* feat: add cache abstraction layer to store module

Introduces CacheInterface with InMemory and NoOp implementations, plus a temporary GlobalCache singleton.

* feat(store,search): buffered writes, chunk read cache, and cache isolation

Refactor FileHandler to accumulate writes and truncates into an in-memory
dirty-chunk map instead of uploading to the server on every write() call.
Dirty chunks are encrypted and sent in a single batch on flush()/close(),
reducing round-trips for workloads that perform many small random writes
(e.g. SQLite index updates via the Search API VFS layer).

Introduce a per-connection scoped chunk read cache backed by GlobalCache:
- CacheScopedNamespace wraps a shared CacheInterface and prepends a
  "host;pubkey;" prefix to every key, isolating cache entries between
  different Bridge connections and users without separate instances.
- CacheKey provides a factory for cache key strings with a consistent
  "type;entity_id;sub_key" format.
- GlobalCache is refactored: lazy thread-safe init via std::once_flag,
  new setChunksCache() / setChunksCacheEnabled() API for runtime
  configuration before the first connect(), renamed getChunksCacheInstance().
- ChunkDataProvider populates the cache for every chunk in a fetched server
  segment on first read, validates hits by HMAC, and evicts on mismatch.
  Freshly written chunks are also inserted into the cache after upload.

Propagate the scoped cache instance through FileReadHandle and
FileReadWriteHandle constructors and expose it to InboxApiImpl so inbox
file reads share the same cache infrastructure.

Expose flushFile() and getFileSizeFromHandle() on StoreApi / StoreApiImpl
to allow callers to trigger a batch flush and query pending file size without
a server round-trip.

Update PrivmxFS (Search API): sync() calls flushFile(), getFileSize()
reads from the open handle, and access() blocks WAL file paths to prevent
SQLite from attempting write-ahead logging against the PrivMX backend.

* fix(search,kvdb): fix build errors after devel merge

- Make KvdbApiImpl::createKvdbEx public so SearchApiImpl can call it
- Fix DynamicTypes.hpp in search module: replace missing
  privmx/endpoint/core/TypesMacros.hpp with the correct
  privmx/utils/TypedObject.hpp + privmx/utils/TypesMacros.hpp,
  and replace undefined ENDPOINT_CLIENT_TYPE with DECLARE_CORE_TYPE

* feat(store): batch server writes with 5 MB limit per updateOnServer call

flush() splits chunks into batches sized upfront from the fixed encrypted
chunk size; plaintext for gap chunks is allocated one chunk at a time to
avoid N×plainChunkSize spikes. Each batch gets its own encrypted meta and
advances local state immediately, so a failure in a later batch leaves the
client consistent with what the server has already committed.

* refactor(search): remove Writer buffering and clean up SQLite VFS bindings

Writes go directly to storeApi; Writer class removed. VFS callbacks use
nullptr for unused params and structs are completed with version 2/3 slots.

* fix(store): guard flushFile/getFileSize against invalid handles

Throw InvalidFileReadWriteHandleException instead of silently no-op or dereferencing null.
Rename getFileSizeFromHandle -> getFileSize.

* fix(search): update getFileSizeFromHandle call to renamed getFileSize

* style: apply clang-format to inbox, search, and store modules

* fix(search): remove redundant sync() call before read in PrivmxFile

* refactor(store): extract repeated FileHandler helpers

Replace three inline-duplicated expressions in FileHandler with
named private helpers: committedChunkCount(), isMidTruncateActive(),
and midTruncateClearStart(). Also promote PendingChunk from a
flush()-local struct to a private nested type in the class.

* refactor(store): reorder FileHandler methods by visibility and call depth

* docs(store): note thread-safety issues in getChunk()

* refactor(store): rename server chunk to segment in ChunkDataProvider

* refactor(store): replace Pson::BinaryString with core::Buffer in cache API

* refactor(store): pass cache value by const ref in CacheInterface::put

* refactor(store): move CacheInterface and GlobalCache to include_pub

* test(store): add flushFile calls before read assertions in random write tests

---------

Co-authored-by: Jerzy Czarkowski <jczarkowski@simplito.com>
…issing key (#439)

Adds KvdbApi::findEntry backed by a new kvdbEntryFind server call that
returns std::optional<KvdbEntry> when the key is absent, instead of
throwing KvdbEntryDoesNotExistException.

Updates PrivmxFS::access and getFileId in the search module to use
findEntry, removing the try/catch exception-based control flow used
previously to handle legitimately missing entries.

Co-authored-by: Jerzy Czarkowski <jczarkowski@simplito.com>
Adds beginTransaction, commit, and rollback methods to FullTextSearch,
SearchApiImpl, SearchApi, and SearchApiVarInterface (methods 14–16),
allowing callers to batch document mutations inside an explicit SQLite
transaction. Adds matching TransactionBeginException, TransactionCommitException,
and TransactionRollbackException (codes 0x0301–0x0303).
* feat: add cache abstraction layer to store module

Introduces CacheInterface with InMemory and NoOp implementations, plus a temporary GlobalCache singleton.

* feat(store,search): buffered writes, chunk read cache, and cache isolation

Refactor FileHandler to accumulate writes and truncates into an in-memory
dirty-chunk map instead of uploading to the server on every write() call.
Dirty chunks are encrypted and sent in a single batch on flush()/close(),
reducing round-trips for workloads that perform many small random writes
(e.g. SQLite index updates via the Search API VFS layer).

Introduce a per-connection scoped chunk read cache backed by GlobalCache:
- CacheScopedNamespace wraps a shared CacheInterface and prepends a
  "host;pubkey;" prefix to every key, isolating cache entries between
  different Bridge connections and users without separate instances.
- CacheKey provides a factory for cache key strings with a consistent
  "type;entity_id;sub_key" format.
- GlobalCache is refactored: lazy thread-safe init via std::once_flag,
  new setChunksCache() / setChunksCacheEnabled() API for runtime
  configuration before the first connect(), renamed getChunksCacheInstance().
- ChunkDataProvider populates the cache for every chunk in a fetched server
  segment on first read, validates hits by HMAC, and evicts on mismatch.
  Freshly written chunks are also inserted into the cache after upload.

Propagate the scoped cache instance through FileReadHandle and
FileReadWriteHandle constructors and expose it to InboxApiImpl so inbox
file reads share the same cache infrastructure.

Expose flushFile() and getFileSizeFromHandle() on StoreApi / StoreApiImpl
to allow callers to trigger a batch flush and query pending file size without
a server round-trip.

Update PrivmxFS (Search API): sync() calls flushFile(), getFileSize()
reads from the open handle, and access() blocks WAL file paths to prevent
SQLite from attempting write-ahead logging against the PrivMX backend.

* fix(search,kvdb): fix build errors after devel merge

- Make KvdbApiImpl::createKvdbEx public so SearchApiImpl can call it
- Fix DynamicTypes.hpp in search module: replace missing
  privmx/endpoint/core/TypesMacros.hpp with the correct
  privmx/utils/TypedObject.hpp + privmx/utils/TypesMacros.hpp,
  and replace undefined ENDPOINT_CLIENT_TYPE with DECLARE_CORE_TYPE

* feat(store): batch server writes with 5 MB limit per updateOnServer call

flush() splits chunks into batches sized upfront from the fixed encrypted
chunk size; plaintext for gap chunks is allocated one chunk at a time to
avoid N×plainChunkSize spikes. Each batch gets its own encrypted meta and
advances local state immediately, so a failure in a later batch leaves the
client consistent with what the server has already committed.

* refactor(search): remove Writer buffering and clean up SQLite VFS bindings

Writes go directly to storeApi; Writer class removed. VFS callbacks use
nullptr for unused params and structs are completed with version 2/3 slots.

* fix(store): guard flushFile/getFileSize against invalid handles

Throw InvalidFileReadWriteHandleException instead of silently no-op or dereferencing null.
Rename getFileSizeFromHandle -> getFileSize.

* fix(search): update getFileSizeFromHandle call to renamed getFileSize

* style: apply clang-format to inbox, search, and store modules

* fix(search): remove redundant sync() call before read in PrivmxFile

* refactor(store): extract repeated FileHandler helpers

Replace three inline-duplicated expressions in FileHandler with
named private helpers: committedChunkCount(), isMidTruncateActive(),
and midTruncateClearStart(). Also promote PendingChunk from a
flush()-local struct to a private nested type in the class.

* refactor(store): reorder FileHandler methods by visibility and call depth

* docs(store): note thread-safety issues in getChunk()

* refactor(store): rename server chunk to segment in ChunkDataProvider

* refactor(store): replace Pson::BinaryString with core::Buffer in cache API

* refactor(store): pass cache value by const ref in CacheInterface::put

* refactor(store): move CacheInterface and GlobalCache to include_pub

* test(store): add flushFile calls before read assertions in random write tests

* feat(store): add SLRU-backed persistent chunk cache

Introduces a segmented LRU (SLRU) eviction policy and a pluggable cache
backend abstraction. GlobalCache now uses SlruBackedCache with an
in-memory backend by default, and exposes setChunksCacheBackend() for
external persistent backends (e.g. LevelDB).

---------

Co-authored-by: Jerzy Czarkowski <jczarkowski@simplito.com>
SQLite queries the VFS for WAL file existence on every read/write
operation. Since the Search module does not use WAL mode, intercepting
these calls in PrivmxExtFS::access() avoids unnecessary round-trips to
the server.

Co-authored-by: Jerzy Czarkowski <jczarkowski@simplito.com>
* feat(lock): add dedicated Lock API module for resource locking

Introduces a new lock module (endpoint/lock/) with lock, unlock, and
checkReservedLock operations backed by direct server-side RPC calls.

Replaces the KVDB-based LockSession/LockSetLogic in SearchApi, which
required a read followed by a write — creating a TOCTOU window and
doubling the number of bridge round-trips per lock acquisition.

* fix(search): remove unused LockSession include from PrivmxFS.hpp

---------

Co-authored-by: Jerzy Czarkowski <jczarkowski@simplito.com>
@Uriagat
Uriagat requested review from djenczewski and imaTik0 August 4, 2026 13:05
@Uriagat Uriagat self-assigned this Aug 4, 2026
@Uriagat
Uriagat marked this pull request as ready for review August 5, 2026 06:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants