aboutsummaryrefslogtreecommitdiff
path: root/src/server/memory_index.odin
blob: f609ca2bc69df335691a80d9e86e5fcea560dd7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package server

import "core:hash"
import "core:strings"
import "core:fmt"
import "core:log"
import "core:slice"

import "shared:common"

MemoryIndex :: struct {
	collection:        SymbolCollection,
	last_package_name: string,
	last_package:      ^map[string]Symbol,
}

make_memory_index :: proc(collection: SymbolCollection) -> MemoryIndex {
	return MemoryIndex{collection = collection}
}

memory_index_clear_cache :: proc(index: ^MemoryIndex) {
	index.last_package_name = ""
	index.last_package = nil
}

memory_index_lookup :: proc(
	index: ^MemoryIndex,
	name: string,
	pkg: string,
) -> (
	Symbol,
	bool,
) {
	if index.last_package_name == pkg && index.last_package != nil {
		return index.last_package[name]
	}

	if _pkg, ok := &index.collection.packages[pkg]; ok {
		index.last_package = _pkg
		index.last_package_name = pkg
		return _pkg[name]
	} else {
		index.last_package = nil
		index.last_package_name = ""
	}

	return {}, false
}

memory_index_fuzzy_search :: proc(
	index: ^MemoryIndex,
	name: string,
	pkgs: []string,
) -> (
	[]FuzzyResult,
	bool,
) {
	symbols := make([dynamic]FuzzyResult, 0, context.temp_allocator)

	fuzzy_matcher := common.make_fuzzy_matcher(name)

	top := 20

	for pkg in pkgs {
		if pkg, ok := index.collection.packages[pkg]; ok {
			for _, symbol in pkg {
				if score, ok := common.fuzzy_match(fuzzy_matcher, symbol.name);
				   ok == 1 {
					result := FuzzyResult {
						symbol = symbol,
						score  = score,
					}

					append(&symbols, result)
				}
			}
		}
	}

	slice.sort_by(symbols[:], proc(i, j: FuzzyResult) -> bool {
		return j.score < i.score
	})

	if name == "" {
		return symbols[:], true
	} else {
		return symbols[:min(top, len(symbols))], true
	}
}