• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nshkrdotcom / ElixirScope / 997dd201c48cfc5a93ab9d8799c4f839ab1728ae

29 May 2025 07:59PM UTC coverage: 58.374% (-0.05%) from 58.426%
997dd201c48cfc5a93ab9d8799c4f839ab1728ae

push

github

NSHkr
refactor performance_optimizer

0 of 159 new or added lines in 6 files covered. (0.0%)

14 existing lines in 1 file now uncovered.

6082 of 10419 relevant lines covered (58.37%)

3184.09 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/lib/elixir_scope/ast_repository/performance_optimizer/lazy_loader.ex
1
# ==============================================================================
2
# Lazy Loading Component
3
# ==============================================================================
4

5
defmodule ElixirScope.ASTRepository.PerformanceOptimizer.LazyLoader do
6
  @moduledoc """
7
  Manages lazy loading of expensive analysis data like CFG and DFG.
8
  """
9

10
  use GenServer
11

12
  alias ElixirScope.ASTRepository.{MemoryManager, EnhancedRepository}
13

14
  @function_cache_prefix "function:"
15
  @lazy_loading_threshold 1000  # bytes
16

17
  def start_link(opts \\ []) do
NEW
18
    GenServer.start_link(__MODULE__, opts, name: __MODULE__)
×
19
  end
20

NEW
21
  def init(_opts) do
×
22
    {:ok, %{}}
23
  end
24

25
  @doc """
26
  Retrieves function with lazy analysis loading.
27
  """
28
  @spec get_function_lazy(atom(), atom(), non_neg_integer()) :: {:ok, term()} | {:error, term()}
29
  def get_function_lazy(module_name, function_name, arity) do
NEW
30
    cache_key = @function_cache_prefix <> "#{module_name}.#{function_name}/#{arity}"
×
31

NEW
32
    case MemoryManager.cache_get(:analysis, cache_key) do
×
33
      {:ok, cached_data} ->
NEW
34
        track_access({module_name, function_name, arity}, :cache_hit)
×
35
        {:ok, cached_data}
36

37
      :miss ->
NEW
38
        case EnhancedRepository.get_enhanced_function(module_name, function_name, arity) do
×
39
          {:ok, function_data} ->
NEW
40
            optimized_data = apply_lazy_loading(function_data)
×
NEW
41
            MemoryManager.cache_put(:analysis, cache_key, optimized_data)
×
NEW
42
            track_access({module_name, function_name, arity}, :cache_miss)
×
43
            {:ok, optimized_data}
44

45
          error ->
NEW
46
            error
×
47
        end
48
    end
49
  end
50

51
  @doc """
52
  Stores function with lazy analysis optimization.
53
  """
54
  @spec store_function_lazy(atom(), atom(), non_neg_integer(), term(), keyword()) :: {:ok, term()} | {:error, term()}
55
  def store_function_lazy(module_name, function_name, arity, ast, opts) do
NEW
56
    ast_size = estimate_ast_size(ast)
×
57

NEW
58
    if ast_size > @lazy_loading_threshold do
×
NEW
59
      lazy_opts = Keyword.put(opts, :lazy_analysis, true)
×
NEW
60
      EnhancedRepository.store_enhanced_function(module_name, function_name, arity, ast, lazy_opts)
×
61
    else
NEW
62
      EnhancedRepository.store_enhanced_function(module_name, function_name, arity, ast, opts)
×
63
    end
64
  end
65

66
  # Private implementation
67
  defp apply_lazy_loading(function_data) do
NEW
68
    cond do
×
NEW
69
      is_nil(function_data.cfg_data) and should_load_cfg?(function_data) ->
×
NEW
70
        case EnhancedRepository.get_cfg(function_data.module_name, function_data.function_name, function_data.arity) do
×
NEW
71
          {:ok, cfg} -> %{function_data | cfg_data: cfg}
×
NEW
72
          _ -> function_data
×
73
        end
74

NEW
75
      is_nil(function_data.dfg_data) and should_load_dfg?(function_data) ->
×
NEW
76
        case EnhancedRepository.get_dfg(function_data.module_name, function_data.function_name, function_data.arity) do
×
NEW
77
          {:ok, dfg} -> %{function_data | dfg_data: dfg}
×
NEW
78
          _ -> function_data
×
79
        end
80

NEW
81
      true ->
×
NEW
82
        function_data
×
83
    end
84
  end
85

86
  defp should_load_cfg?(function_data) do
NEW
87
    complexity = get_function_complexity(function_data)
×
NEW
88
    access_count = get_access_count({function_data.module_name, function_data.function_name, function_data.arity})
×
89

NEW
90
    complexity > 5 or access_count > 10
×
91
  end
92

93
  defp should_load_dfg?(function_data) do
NEW
94
    has_variables = function_has_variables?(function_data.ast)
×
NEW
95
    access_count = get_access_count({function_data.module_name, function_data.function_name, function_data.arity})
×
96

NEW
97
    has_variables and access_count > 5
×
98
  end
99

100
  defp estimate_ast_size(ast) do
NEW
101
    :erlang.external_size(ast)
×
102
  end
103

104
  defp get_function_complexity(function_data) do
NEW
105
    case function_data.complexity_metrics do
×
NEW
106
      %{cyclomatic_complexity: complexity} -> complexity
×
NEW
107
      _ -> 1
×
108
    end
109
  end
110

111
  defp function_has_variables?(ast) do
NEW
112
    is_tuple(ast) and tuple_size(ast) > 0
×
113
  end
114

115
  defp get_access_count(identifier) do
NEW
116
    case :ets.lookup(:ast_repo_access_tracking, identifier) do
×
NEW
117
      [{^identifier, _last_access, access_count}] -> access_count
×
NEW
118
      [] -> 0
×
119
    end
120
  end
121

122
  defp track_access(identifier, access_type) do
NEW
123
    current_time = System.monotonic_time(:second)
×
124

NEW
125
    case :ets.lookup(:ast_repo_access_tracking, identifier) do
×
126
      [{^identifier, _last_access, access_count}] ->
NEW
127
        new_count = if access_type == :cache_hit, do: access_count + 1, else: access_count
×
NEW
128
        :ets.insert(:ast_repo_access_tracking, {identifier, current_time, new_count})
×
129

130
      [] ->
NEW
131
        :ets.insert(:ast_repo_access_tracking, {identifier, current_time, 1})
×
132
    end
133
  end
134
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc