CIRCT 22.0.0git
Loading...
Searching...
No Matches
PendingChanges.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LIB_CIRCT_TOOLS_CIRCT_VERILOG_LSP_SERVER_PENDINGCHANGES_H_
10#define LIB_CIRCT_TOOLS_CIRCT_VERILOG_LSP_SERVER_PENDINGCHANGES_H_
11
12#include "llvm/ADT/StringMap.h"
13#include "llvm/Support/LSP/Protocol.h"
14#include "llvm/Support/ThreadPool.h"
15
17
18#include <chrono>
19#include <cstdint>
20#include <mutex>
21#include <thread>
22#include <vector>
23
24namespace circt {
25namespace lsp {
26
27/// Build a pool strategy with a sensible minimum.
28static llvm::ThreadPoolStrategy makeStrategy(unsigned maxThreads) {
29 llvm::ThreadPoolStrategy s = llvm::hardware_concurrency();
30 s.ThreadsRequested = (maxThreads == 0 ? 1u : maxThreads);
31 return s;
32}
33
34/// Debounce tuning for document-change bursts.
36 /// If true, flush immediately (no sleep/check).
37 bool disableDebounce = false;
38 /// Minimum quiet time before we flush.
39 uint64_t debounceMinMs = 0;
40 /// Maximum total burst time (0 = no cap).
41 uint64_t debounceMaxMs = 0;
42 static DebounceOptions
44};
45
46/// Accumulated edits + timing for a single document key.
48 std::vector<llvm::lsp::TextDocumentContentChangeEvent> changes;
49 int64_t version = 0;
50 std::chrono::steady_clock::time_point firstChangeTime{};
51 std::chrono::steady_clock::time_point lastChangeTime{};
52};
53
54/// Thread-safe accumulator + debouncer for text document changes.
56public:
58 unsigned maxThreads = std::thread::hardware_concurrency())
59 : pool(makeStrategy(maxThreads)), tasks(pool) {}
60
61 /// Call during server shutdown; Erase all file changes, then clear file map.
62 /// Thread-safe.
63 void abort();
64
65 /// Remove all pending edits for a document key.
66 /// Safe to call from the LSP thread when a file closes.
67 /// Thread-safe.
68 void erase(llvm::StringRef key);
69
70 // Convenience overload for using with an URI.
71 void erase(const llvm::lsp::URIForFile &uri);
72
73 /// Append new edits for a document key, then start a debounced update thread.
74 /// Thread-safe.
75 void
76 debounceAndUpdate(const llvm::lsp::DidChangeTextDocumentParams &params,
77 DebounceOptions options,
78 std::function<void(std::unique_ptr<PendingChanges>)> cb);
79
80 /// Append new edits for a document key.
81 /// Thread-safe.
82 void enqueueChange(const llvm::lsp::DidChangeTextDocumentParams &params);
83
84 /// Schedule a debounce check on the internal pool and call `cb` when ready.
85 /// If the task becomes obsolete (newer edits arrive before the quiet window,
86 /// and max cap not reached), `cb(nullptr)` is invoked.
87 /// Thread-safe.
88 void debounceAndThen(const llvm::lsp::DidChangeTextDocumentParams &params,
89 DebounceOptions options,
90 std::function<void(std::unique_ptr<PendingChanges>)> cb);
91
92private:
93 /// NOT thread-safe; caller must hold mu.
94 PendingChanges &getOrCreateEntry(std::string_view key);
95
96 /// NOT thread-safe; caller must hold mu.
97 std::unique_ptr<PendingChanges>
98 takeAndErase(llvm::StringMap<PendingChanges>::iterator it);
99
100 /// Per-document edit bursts, keyed by file string.
101 /// Stored by value; safe to move out when flushing.
102 llvm::StringMap<PendingChanges> pending;
103 /// Guards `pending`.
104 std::mutex mu;
105
106 /// Internal concurrency used for sleeps + checks.
107 llvm::StdThreadPool pool;
108 llvm::ThreadPoolTaskGroup tasks;
109};
110
111} // namespace lsp
112} // namespace circt
113
114#endif // LIB_CIRCT_TOOLS_CIRCT_VERILOG_LSP_SERVER_PENDINGCHANGES_H_
Thread-safe accumulator + debouncer for text document changes.
void debounceAndThen(const llvm::lsp::DidChangeTextDocumentParams &params, DebounceOptions options, std::function< void(std::unique_ptr< PendingChanges >)> cb)
Schedule a debounce check on the internal pool and call cb when ready.
std::mutex mu
Guards pending.
PendingChangesMap(unsigned maxThreads=std::thread::hardware_concurrency())
llvm::ThreadPoolTaskGroup tasks
llvm::StdThreadPool pool
Internal concurrency used for sleeps + checks.
std::unique_ptr< PendingChanges > takeAndErase(llvm::StringMap< PendingChanges >::iterator it)
NOT thread-safe; caller must hold mu.
llvm::StringMap< PendingChanges > pending
Per-document edit bursts, keyed by file string.
void abort()
Call during server shutdown; Erase all file changes, then clear file map.
void enqueueChange(const llvm::lsp::DidChangeTextDocumentParams &params)
Append new edits for a document key.
void debounceAndUpdate(const llvm::lsp::DidChangeTextDocumentParams &params, DebounceOptions options, std::function< void(std::unique_ptr< PendingChanges >)> cb)
Append new edits for a document key, then start a debounced update thread.
void erase(llvm::StringRef key)
Remove all pending edits for a document key.
PendingChanges & getOrCreateEntry(std::string_view key)
NOT thread-safe; caller must hold mu.
static llvm::ThreadPoolStrategy makeStrategy(unsigned maxThreads)
Build a pool strategy with a sensible minimum.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Debounce tuning for document-change bursts.
uint64_t debounceMinMs
Minimum quiet time before we flush.
static DebounceOptions fromLSPOptions(const circt::lsp::LSPServerOptions &opts)
Factory: build from server options. Keep mapping 1:1 for clarity.
bool disableDebounce
If true, flush immediately (no sleep/check).
uint64_t debounceMaxMs
Maximum total burst time (0 = no cap).
Accumulated edits + timing for a single document key.
std::chrono::steady_clock::time_point firstChangeTime
std::chrono::steady_clock::time_point lastChangeTime
std::vector< llvm::lsp::TextDocumentContentChangeEvent > changes