================
@@ -123,6 +156,107 @@ class IndexActionFactory : public
tooling::FrontendActionFactory {
RelationSlab::Builder Relations;
};
+// Action factory that writes per-file shards (for sharded index format).
+// Each TU's index data is sharded independently — no merging across TUs.
+// Header shards are deduplicated: if a header's content hasn't changed since
+// the last time we wrote its shard, we skip writing it again.
+class ShardedIndexActionFactory : public tooling::FrontendActionFactory {
+public:
+ ShardedIndexActionFactory(BackgroundIndexStorage &Storage)
+ : Storage(Storage) {}
+
+ std::unique_ptr<FrontendAction> create() override {
+ // Snapshot the current shard versions so the callback can check staleness
+ // without holding the lock during indexing.
+ llvm::StringMap<ShardVersion> Snapshot;
+ {
+ std::lock_guard<std::mutex> Lock(ShardVersionsMu);
+ Snapshot = ShardVersions;
+ }
+
+ SymbolCollector::Options Opts;
+ Opts.CountReferences = true;
+
+ return createStaticIndexingAction(
+ Opts, [this, Snapshot](IndexFileIn Index) {
+ writeShards(std::move(Index), Snapshot);
+ });
+ }
+
+ bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
+ FileManager *Files,
+ std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+ DiagnosticConsumer *DiagConsumer) override {
+ disableUnsupportedOptions(*Invocation);
+ return tooling::FrontendActionFactory::runInvocation(
+ std::move(Invocation), Files, std::move(PCHContainerOps),
DiagConsumer);
+ }
+
+private:
+ void writeShards(IndexFileIn Index,
+ const llvm::StringMap<ShardVersion> &Snapshot) {
+ if (!Index.Sources)
+ return;
+
+ // Find the URI of the main file (the TU root). Store as owned string
+ // because we move Index below, which would invalidate any StringRef into
it.
+ std::string MainUri;
+ for (const auto &[Uri, Node] : *Index.Sources) {
+ if (Node.Flags & IncludeGraphNode::SourceFlag::IsTU) {
+ MainUri = Uri.str();
+ break;
+ }
+ }
+
+ // Collect files that need updated shards, based on content digest.
+ // Files whose shard was already written with the same digest are skipped.
+ llvm::StringMap<std::pair<Path, FileDigest>> FilesToUpdate;
+ for (const auto &[Uri, Node] : *Index.Sources) {
+ auto AbsPath = URI::resolve(Uri, MainUri);
+ if (!AbsPath) {
+ elog("Failed to resolve URI {0}: {1}", Uri, AbsPath.takeError());
+ continue;
+ }
+ auto DigestIt = Snapshot.find(*AbsPath);
+ if (DigestIt == Snapshot.end() || DigestIt->second.Digest != Node.Digest)
+ FilesToUpdate[Uri] = {std::move(*AbsPath), Node.Digest};
+ }
+
+ // Shard the index data by file.
+ FileShardedIndex ShardedIndex(std::move(Index));
+
+ unsigned Written = 0;
+ for (const auto &[Uri, PathAndDigest] : FilesToUpdate) {
+ auto Shard = ShardedIndex.getShard(Uri);
+ if (!Shard) {
+ elog("Failed to get shard for {0}", Uri);
+ continue;
+ }
+ PathRef Path = PathAndDigest.first;
+
+ // Command line is only meaningful for the TU's main file.
+ if (Uri != MainUri)
+ Shard->Cmd.reset();
+
+ IndexFileOut Out(*Shard);
+ Out.Format = IndexFileFormat::RIFF;
----------------
HighCommander4 wrote:
Since we're hardcoding `RIFF` here, we should error out if
`--index-type=sharded` is used with `--format=yaml`, rather than silently
succeeding and writing RIFF anyways.
https://github.com/llvm/llvm-project/pull/175209
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits