clang-tools 23.0.0git
Trigram.h
Go to the documentation of this file.
1//===--- Trigram.h - Trigram generation for Fuzzy Matching ------*- C++ -*-===//
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/// \file
10/// Trigrams are attributes of the symbol unqualified name used to effectively
11/// extract symbols which can be fuzzy-matched given user query from the
12/// inverted index. To match query with the extracted set of trigrams Q, the set
13/// of generated trigrams T for identifier (unqualified symbol name) should
14/// contain all items of Q, i.e. Q ⊆ T.
15///
16/// Trigram sets extracted from unqualified name and from query are different:
17/// the set of query trigrams only contains consecutive sequences of three
18/// characters (which is only a subset of all trigrams generated for an
19/// identifier).
20///
21//===----------------------------------------------------------------------===//
22
23#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_DEX_TRIGRAM_H
24#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_DEX_TRIGRAM_H
25
26#include "index/dex/Token.h"
27#include "llvm/ADT/bit.h"
28
29#include <array>
30#include <string>
31
32namespace clang {
33namespace clangd {
34namespace dex {
35
36// Compact representation of a trigram (string with up to 3 characters).
37// Trigram generation is the hot path of indexing, so Token is too wasteful.
38class Trigram {
39 std::array<char, 4> Data; // Last element is length.
40 uint32_t id() const { return llvm::bit_cast<uint32_t>(Data); }
41
42public:
43 Trigram() : Data{0, 0, 0, 0} {}
44 Trigram(char A) : Data{A, 0, 0, 1} {}
45 Trigram(char A, char B) : Data{A, B, 0, 2} {}
46 Trigram(char A, char B, char C) : Data{A, B, C, 3} {}
47 std::string str() const { return std::string(Data.data(), Data[3]); }
48 friend struct ::llvm::DenseMapInfo<Trigram>;
49 friend bool operator==(Trigram L, Trigram R) { return L.id() == R.id(); }
50 friend bool operator<(Trigram L, Trigram R) { return L.id() < R.id(); }
51};
52
53/// Produces list of unique fuzzy-search trigrams from unqualified symbol.
54/// The trigrams give the 3-character query substrings this symbol can match.
55///
56/// The symbol's name is broken into segments, e.g. "FooBar" has two segments.
57/// Trigrams can start at any character in the input. Then we can choose to move
58/// to the next character or to the start of the next segment.
59///
60/// Short trigrams (length 1-2) are used for short queries. These are:
61/// - prefixes of the identifier, of length 1 and 2
62/// - the first character + next head character
63///
64/// For "FooBar" we get the following trigrams:
65/// {f, fo, fb, foo, fob, fba, oob, oba, bar}.
66///
67/// Trigrams are lowercase, as trigram matching is case-insensitive.
68/// Trigrams in the list are deduplicated.
69void generateIdentifierTrigrams(llvm::StringRef Identifier,
70 std::vector<Trigram> &Out);
71
72/// Returns list of unique fuzzy-search trigrams given a query.
73///
74/// Query is segmented using FuzzyMatch API and downcasted to lowercase. Then,
75/// the simplest trigrams - sequences of three consecutive letters and digits
76/// are extracted and returned after deduplication.
77///
78/// For short queries (less than 3 characters with Head or Tail roles in Fuzzy
79/// Matching segmentation) this returns a single trigram with the first
80/// characters (up to 3) to perform prefix match.
81std::vector<Token> generateQueryTrigrams(llvm::StringRef Query);
82
83} // namespace dex
84} // namespace clangd
85} // namespace clang
86
87namespace llvm {
88template <> struct DenseMapInfo<clang::clangd::dex::Trigram> {
90 static unsigned getHashValue(Trigram V) {
91 // Finalize step from MurmurHash3.
92 uint32_t X = V.id();
93 X ^= X >> 16;
94 X *= uint32_t{0x85ebca6b};
95 X ^= X >> 13;
96 X *= uint32_t{0xc2b2ae35};
97 X ^= X >> 16;
98 return X;
99 }
100 static bool isEqual(const Trigram &LHS, const Trigram &RHS) {
101 return LHS == RHS;
102 }
103};
104} // namespace llvm
105
106#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_DEX_TRIGRAM_H
static clang::FrontendPluginRegistry::Add< clang::tidy::ClangTidyPluginAction > X("clang-tidy", "clang-tidy")
Trigram(char A, char B)
Definition Trigram.h:45
friend bool operator==(Trigram L, Trigram R)
Definition Trigram.h:49
friend bool operator<(Trigram L, Trigram R)
Definition Trigram.h:50
std::string str() const
Definition Trigram.h:47
Trigram(char A, char B, char C)
Definition Trigram.h:46
Token objects represent a characteristic of a symbol, which can be used to perform efficient search.
void generateIdentifierTrigrams(llvm::StringRef Identifier, std::vector< Trigram > &Result)
Produces list of unique fuzzy-search trigrams from unqualified symbol.
Definition Trigram.cpp:100
std::vector< Token > generateQueryTrigrams(llvm::StringRef Query)
Returns list of unique fuzzy-search trigrams given a query.
Definition Trigram.cpp:123
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
Definition AST.cpp:44
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Some operations such as code completion produce a set of candidates.
Definition Generators.h:152
static unsigned getHashValue(Trigram V)
Definition Trigram.h:90
static bool isEqual(const Trigram &LHS, const Trigram &RHS)
Definition Trigram.h:100