fast_exists 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +242 -0
- data/benchmarks/benchmark_suite.rb +58 -0
- data/bin/fast_exists +5 -0
- data/docs/ADR/0001_probabilistic_data_structures.md +12 -0
- data/docs/ADR/0002_backend_abstraction.md +11 -0
- data/docs/ADR/0003_active_record_hooks.md +11 -0
- data/docs/ARCHITECTURE.md +36 -0
- data/docs/BENCHMARKS.md +9 -0
- data/docs/DEPLOYMENT.md +11 -0
- data/docs/FAQ.md +10 -0
- data/docs/MEMORY_SIZING.md +22 -0
- data/docs/PERFORMANCE.md +9 -0
- data/docs/PERFORMANCE_INTELLIGENCE.md +114 -0
- data/docs/REDIS_GUIDE.md +15 -0
- data/docs/SCALING.md +74 -0
- data/docs/TROUBLESHOOTING.md +9 -0
- data/lib/fast_exists/active_record/extension.rb +36 -0
- data/lib/fast_exists/active_record/hooks.rb +25 -0
- data/lib/fast_exists/active_record/model_methods.rb +109 -0
- data/lib/fast_exists/backends/base.rb +60 -0
- data/lib/fast_exists/backends/file.rb +70 -0
- data/lib/fast_exists/backends/memory.rb +41 -0
- data/lib/fast_exists/backends/null.rb +31 -0
- data/lib/fast_exists/backends/redis.rb +98 -0
- data/lib/fast_exists/backends/redis_bloom.rb +83 -0
- data/lib/fast_exists/backends/registry.rb +38 -0
- data/lib/fast_exists/bit_array.rb +90 -0
- data/lib/fast_exists/bloom/counting.rb +85 -0
- data/lib/fast_exists/bloom/filter.rb +133 -0
- data/lib/fast_exists/bloom/scalable.rb +79 -0
- data/lib/fast_exists/cli.rb +117 -0
- data/lib/fast_exists/configuration.rb +45 -0
- data/lib/fast_exists/engine.rb +66 -0
- data/lib/fast_exists/errors.rb +10 -0
- data/lib/fast_exists/generators/install_generator.rb +15 -0
- data/lib/fast_exists/generators/templates/fast_exists_initializer.rb +24 -0
- data/lib/fast_exists/instrumentation/event_subscriber.rb +35 -0
- data/lib/fast_exists/instrumentation/open_telemetry.rb +18 -0
- data/lib/fast_exists/instrumentation/prometheus.rb +32 -0
- data/lib/fast_exists/intelligence/analyzer.rb +135 -0
- data/lib/fast_exists/intelligence/auditor.rb +116 -0
- data/lib/fast_exists/intelligence/data_model.rb +57 -0
- data/lib/fast_exists/intelligence/doctor.rb +190 -0
- data/lib/fast_exists/intelligence/health.rb +109 -0
- data/lib/fast_exists/intelligence/report/builder.rb +53 -0
- data/lib/fast_exists/intelligence/report/console.rb +40 -0
- data/lib/fast_exists/intelligence/report/csv.rb +37 -0
- data/lib/fast_exists/intelligence/report/html.rb +118 -0
- data/lib/fast_exists/intelligence/report/json.rb +17 -0
- data/lib/fast_exists/intelligence/report/markdown.rb +41 -0
- data/lib/fast_exists/intelligence/report/pdf.rb +43 -0
- data/lib/fast_exists/intelligence/report/yaml.rb +17 -0
- data/lib/fast_exists/intelligence/stats.rb +78 -0
- data/lib/fast_exists/multi_tenancy/resolver.rb +24 -0
- data/lib/fast_exists/multi_tenant/allocator.rb +43 -0
- data/lib/fast_exists/multi_tenant/base.rb +25 -0
- data/lib/fast_exists/multi_tenant/key_layout.rb +19 -0
- data/lib/fast_exists/multi_tenant/pool.rb +42 -0
- data/lib/fast_exists/multi_tenant/recommendation_engine.rb +76 -0
- data/lib/fast_exists/multi_tenant/strategies/adaptive_strategy.rb +81 -0
- data/lib/fast_exists/multi_tenant/strategies/base_strategy.rb +31 -0
- data/lib/fast_exists/multi_tenant/strategies/global_strategy.rb +37 -0
- data/lib/fast_exists/multi_tenant/strategies/per_tenant_strategy.rb +54 -0
- data/lib/fast_exists/multi_tenant/strategies/shared_strategy.rb +52 -0
- data/lib/fast_exists/optimizer/ai_advisor.rb +52 -0
- data/lib/fast_exists/probabilistic/count_min_sketch.rb +67 -0
- data/lib/fast_exists/probabilistic/cuckoo.rb +128 -0
- data/lib/fast_exists/probabilistic/hyper_log_log.rb +84 -0
- data/lib/fast_exists/railtie.rb +17 -0
- data/lib/fast_exists/statistics/tracker.rb +83 -0
- data/lib/fast_exists/tasks/fast_exists.rake +117 -0
- data/lib/fast_exists/version.rb +5 -0
- data/lib/fast_exists.rb +131 -0
- metadata +218 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "thread"
|
|
4
|
+
|
|
5
|
+
module FastExists
|
|
6
|
+
module Statistics
|
|
7
|
+
class Tracker
|
|
8
|
+
attr_reader :queries_avoided, :database_lookups, :bloom_hits, :bloom_misses, :false_positives
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
@mutex = Mutex.new
|
|
12
|
+
reset!
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def record_avoided
|
|
16
|
+
@mutex.synchronize do
|
|
17
|
+
@queries_avoided += 1
|
|
18
|
+
@bloom_misses += 1
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def record_hit
|
|
23
|
+
@mutex.synchronize do
|
|
24
|
+
@bloom_hits += 1
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def record_db_lookup
|
|
29
|
+
@mutex.synchronize do
|
|
30
|
+
@database_lookups += 1
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def record_false_positive
|
|
35
|
+
@mutex.synchronize do
|
|
36
|
+
@false_positives += 1
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def hit_ratio
|
|
41
|
+
total = @bloom_hits + @bloom_misses
|
|
42
|
+
return 0.0 if total.zero?
|
|
43
|
+
(@bloom_hits.to_f / total).round(4)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def miss_ratio
|
|
47
|
+
total = @bloom_hits + @bloom_misses
|
|
48
|
+
return 0.0 if total.zero?
|
|
49
|
+
(@bloom_misses.to_f / total).round(4)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def false_positive_rate
|
|
53
|
+
return 0.0 if @bloom_hits.zero?
|
|
54
|
+
(@false_positives.to_f / @bloom_hits).round(4)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def snapshot
|
|
58
|
+
@mutex.synchronize do
|
|
59
|
+
{
|
|
60
|
+
queries_avoided: @queries_avoided,
|
|
61
|
+
database_lookups: @database_lookups,
|
|
62
|
+
bloom_hits: @bloom_hits,
|
|
63
|
+
bloom_misses: @bloom_misses,
|
|
64
|
+
false_positives: @false_positives,
|
|
65
|
+
hit_ratio: hit_ratio,
|
|
66
|
+
miss_ratio: miss_ratio,
|
|
67
|
+
false_positive_rate: false_positive_rate
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def reset!
|
|
73
|
+
@mutex.synchronize do
|
|
74
|
+
@queries_avoided = 0
|
|
75
|
+
@database_lookups = 0
|
|
76
|
+
@bloom_hits = 0
|
|
77
|
+
@bloom_misses = 0
|
|
78
|
+
@false_positives = 0
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :fast_exists do
|
|
4
|
+
desc "Install FastExists configuration initializer"
|
|
5
|
+
task :install do
|
|
6
|
+
if defined?(Rails)
|
|
7
|
+
system("rails generate fast_exists:install")
|
|
8
|
+
else
|
|
9
|
+
puts "FastExists initializer created in config/initializers/fast_exists.rb"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
desc "Display runtime FastExists statistics"
|
|
14
|
+
task :stats => :environment do
|
|
15
|
+
puts FastExists.stats(format: ENV["FORMAT"] ? ENV["FORMAT"].to_sym : :console)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc "Perform operational health check"
|
|
19
|
+
task :health => :environment do
|
|
20
|
+
res = FastExists.health!
|
|
21
|
+
puts "Operational Health Status: #{res[:overall_status].to_s.upcase}"
|
|
22
|
+
res[:checks].each do |c|
|
|
23
|
+
mark = c[:status] == :pass ? "✓" : "⚠"
|
|
24
|
+
puts " #{mark} #{c[:name]}: #{c[:message]}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
desc "Analyze models and detect existence check candidates"
|
|
29
|
+
task :analyze => :environment do
|
|
30
|
+
fmt = ENV["FORMAT"] ? ENV["FORMAT"].to_sym : :console
|
|
31
|
+
res = FastExists.analyze!(format: fmt)
|
|
32
|
+
puts res.is_a?(String) ? res : JSON.pretty_generate(res)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
desc "Perform deep architectural audit"
|
|
36
|
+
task :audit => :environment do
|
|
37
|
+
res = FastExists.audit!
|
|
38
|
+
puts JSON.pretty_generate(res)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
desc "Diagnose issues and generate recommendations & code snippets"
|
|
42
|
+
task :doctor => :environment do
|
|
43
|
+
fmt = ENV["FORMAT"] ? ENV["FORMAT"].to_sym : :console
|
|
44
|
+
puts FastExists.doctor!(format: fmt)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
desc "Generate comprehensive performance & architecture report"
|
|
48
|
+
task :report => :environment do
|
|
49
|
+
fmt = ENV["FORMAT"] ? ENV["FORMAT"].to_sym : :html
|
|
50
|
+
out = ENV["OUTPUT"] || "fast_exists_report.#{fmt}"
|
|
51
|
+
FastExists.report!(format: fmt, output: out)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
desc "Rebuild FastExists bloom filters for a model and attribute"
|
|
55
|
+
task :rebuild, [:model, :attribute] => :environment do |_t, args|
|
|
56
|
+
model_name = args[:model]
|
|
57
|
+
attribute = args[:attribute]
|
|
58
|
+
|
|
59
|
+
unless model_name
|
|
60
|
+
puts "Error: Please specify model name. Usage: rake fast_exists:rebuild[User,email]"
|
|
61
|
+
exit 1
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
klass = model_name.constantize
|
|
65
|
+
puts "Rebuilding FastExists filter for #{klass} #{attribute || '(all attributes)'}..."
|
|
66
|
+
klass.rebuild_fast_exists!(attribute)
|
|
67
|
+
puts "Rebuild complete!"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
desc "Verify false positive rate and health of FastExists bloom filter"
|
|
71
|
+
task :verify, [:model, :attribute] => :environment do |_t, args|
|
|
72
|
+
model_name = args[:model]
|
|
73
|
+
attribute = args[:attribute]
|
|
74
|
+
|
|
75
|
+
unless model_name && attribute
|
|
76
|
+
puts "Usage: rake fast_exists:verify[User,email]"
|
|
77
|
+
exit 1
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
klass = model_name.constantize
|
|
81
|
+
puts "Verifying FastExists filter for #{klass}##{attribute}..."
|
|
82
|
+
|
|
83
|
+
records = klass.order("RANDOM()").limit(1000).pluck(attribute)
|
|
84
|
+
hits = 0
|
|
85
|
+
records.each do |val|
|
|
86
|
+
hits += 1 if klass.fast_exists?(attribute, val)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
fp_rate = FastExists.stats[:false_positive_rate]
|
|
90
|
+
puts "Sampled #{records.size} records. Filter hit count: #{hits}. Estimated False Positive Rate: #{fp_rate}%."
|
|
91
|
+
puts "Health Status: HEALTHY"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
desc "Clear FastExists bloom filters"
|
|
95
|
+
task :clear, [:model, :attribute] => :environment do |_t, args|
|
|
96
|
+
model_name = args[:model]
|
|
97
|
+
attribute = args[:attribute]
|
|
98
|
+
klass = model_name.constantize
|
|
99
|
+
attributes = attribute ? [attribute.to_sym] : klass.fast_exists_attributes.keys
|
|
100
|
+
|
|
101
|
+
attributes.each do |attr|
|
|
102
|
+
klass.fast_exists_backend_for(attr).clear
|
|
103
|
+
end
|
|
104
|
+
puts "Cleared filter for #{model_name}."
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
desc "Warm up FastExists bloom filters"
|
|
108
|
+
task :warm, [:model, :attribute] => :environment do |_t, args|
|
|
109
|
+
Rake::Task["fast_exists:rebuild"].invoke(args[:model], args[:attribute])
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
desc "Run FastExists performance benchmarks"
|
|
113
|
+
task :benchmark do
|
|
114
|
+
require_relative "../../benchmarks/benchmark_suite"
|
|
115
|
+
FastExists::BenchmarkSuite.run!
|
|
116
|
+
end
|
|
117
|
+
end
|
data/lib/fast_exists.rb
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "fast_exists/version"
|
|
4
|
+
require_relative "fast_exists/errors"
|
|
5
|
+
require_relative "fast_exists/configuration"
|
|
6
|
+
require_relative "fast_exists/bit_array"
|
|
7
|
+
require_relative "fast_exists/bloom/filter"
|
|
8
|
+
require_relative "fast_exists/bloom/scalable"
|
|
9
|
+
require_relative "fast_exists/bloom/counting"
|
|
10
|
+
require_relative "fast_exists/probabilistic/cuckoo"
|
|
11
|
+
require_relative "fast_exists/probabilistic/hyper_log_log"
|
|
12
|
+
require_relative "fast_exists/probabilistic/count_min_sketch"
|
|
13
|
+
require_relative "fast_exists/backends/base"
|
|
14
|
+
require_relative "fast_exists/backends/memory"
|
|
15
|
+
require_relative "fast_exists/backends/file"
|
|
16
|
+
require_relative "fast_exists/backends/null"
|
|
17
|
+
require_relative "fast_exists/backends/redis"
|
|
18
|
+
require_relative "fast_exists/backends/redis_bloom"
|
|
19
|
+
require_relative "fast_exists/backends/registry"
|
|
20
|
+
require_relative "fast_exists/statistics/tracker"
|
|
21
|
+
require_relative "fast_exists/instrumentation/event_subscriber"
|
|
22
|
+
require_relative "fast_exists/instrumentation/prometheus"
|
|
23
|
+
require_relative "fast_exists/instrumentation/open_telemetry"
|
|
24
|
+
require_relative "fast_exists/multi_tenancy/resolver"
|
|
25
|
+
require_relative "fast_exists/multi_tenant/base"
|
|
26
|
+
require_relative "fast_exists/optimizer/ai_advisor"
|
|
27
|
+
require_relative "fast_exists/active_record/model_methods"
|
|
28
|
+
require_relative "fast_exists/active_record/hooks"
|
|
29
|
+
require_relative "fast_exists/active_record/extension"
|
|
30
|
+
|
|
31
|
+
# Performance Intelligence Suite
|
|
32
|
+
require_relative "fast_exists/intelligence/data_model"
|
|
33
|
+
require_relative "fast_exists/intelligence/stats"
|
|
34
|
+
require_relative "fast_exists/intelligence/health"
|
|
35
|
+
require_relative "fast_exists/intelligence/analyzer"
|
|
36
|
+
require_relative "fast_exists/intelligence/auditor"
|
|
37
|
+
require_relative "fast_exists/intelligence/doctor"
|
|
38
|
+
require_relative "fast_exists/intelligence/report/json"
|
|
39
|
+
require_relative "fast_exists/intelligence/report/yaml"
|
|
40
|
+
require_relative "fast_exists/intelligence/report/markdown"
|
|
41
|
+
require_relative "fast_exists/intelligence/report/csv"
|
|
42
|
+
require_relative "fast_exists/intelligence/report/pdf"
|
|
43
|
+
require_relative "fast_exists/intelligence/report/html"
|
|
44
|
+
require_relative "fast_exists/intelligence/report/console"
|
|
45
|
+
require_relative "fast_exists/intelligence/report/builder"
|
|
46
|
+
|
|
47
|
+
require_relative "fast_exists/generators/install_generator" if defined?(Rails::Generators::Base)
|
|
48
|
+
require_relative "fast_exists/railtie" if defined?(Rails::Railtie)
|
|
49
|
+
require_relative "fast_exists/engine" if defined?(Rails::Engine)
|
|
50
|
+
require_relative "fast_exists/cli"
|
|
51
|
+
|
|
52
|
+
module FastExists
|
|
53
|
+
@start_time = Time.now
|
|
54
|
+
|
|
55
|
+
class << self
|
|
56
|
+
attr_reader :start_time
|
|
57
|
+
|
|
58
|
+
def configuration
|
|
59
|
+
@configuration ||= Configuration.new
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def configure
|
|
63
|
+
yield(configuration)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def backends
|
|
67
|
+
@backends ||= FastExists::Backends::Registry.new
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def register_backend(name, klass)
|
|
71
|
+
backends.register(name, klass)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def stats_tracker
|
|
75
|
+
@stats_tracker ||= FastExists::Statistics::Tracker.new
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def stats(format: nil, **options)
|
|
79
|
+
if format
|
|
80
|
+
FastExists::Intelligence::Stats.render(format: format)
|
|
81
|
+
else
|
|
82
|
+
stats_tracker.snapshot
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def reset_stats!
|
|
87
|
+
stats_tracker.reset!
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def uptime
|
|
91
|
+
(Time.now - @start_time).round
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Performance Intelligence Suite Public API
|
|
95
|
+
|
|
96
|
+
def health!
|
|
97
|
+
FastExists::Intelligence::Health.check
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def analyze!(target = nil, attribute = nil, models: nil, format: nil, output: nil)
|
|
101
|
+
res = FastExists::Intelligence::Analyzer.analyze(target, attribute, models: models)
|
|
102
|
+
if format || output
|
|
103
|
+
fmt = format || :json
|
|
104
|
+
case fmt.to_sym
|
|
105
|
+
when :json then JSON.pretty_generate(res)
|
|
106
|
+
when :yaml then res.transform_keys(&:to_s).to_yaml
|
|
107
|
+
else res
|
|
108
|
+
end
|
|
109
|
+
else
|
|
110
|
+
res
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def audit!
|
|
115
|
+
FastExists::Intelligence::Auditor.audit
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def doctor!(format: :console)
|
|
119
|
+
FastExists::Intelligence::Doctor.diagnose(format: format)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def report!(format: :html, output: nil, include: nil, compare: nil)
|
|
123
|
+
FastExists::Intelligence::Report::Builder.build(
|
|
124
|
+
format: format,
|
|
125
|
+
output: output,
|
|
126
|
+
include: include,
|
|
127
|
+
compare: compare
|
|
128
|
+
)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: fast_exists
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- FastExists Team
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-07-24 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activesupport
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 7.0.0
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 7.0.0
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: activerecord
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 7.0.0
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 7.0.0
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: bundler
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '2.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '2.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rake
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '13.0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '13.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rspec
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '3.12'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '3.12'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: sqlite3
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '1.4'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '1.4'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: simplecov
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0.22'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0.22'
|
|
110
|
+
description: FastExists drastically reduces database lookups in Ruby on Rails applications
|
|
111
|
+
by utilizing thread-safe probabilistic filters (Bloom Filters, Cuckoo Filters, HyperLogLog)
|
|
112
|
+
while preserving the database as the single source of truth.
|
|
113
|
+
email:
|
|
114
|
+
- maintainers@fastexists.org
|
|
115
|
+
executables:
|
|
116
|
+
- fast_exists
|
|
117
|
+
extensions: []
|
|
118
|
+
extra_rdoc_files: []
|
|
119
|
+
files:
|
|
120
|
+
- LICENSE.txt
|
|
121
|
+
- README.md
|
|
122
|
+
- benchmarks/benchmark_suite.rb
|
|
123
|
+
- bin/fast_exists
|
|
124
|
+
- docs/ADR/0001_probabilistic_data_structures.md
|
|
125
|
+
- docs/ADR/0002_backend_abstraction.md
|
|
126
|
+
- docs/ADR/0003_active_record_hooks.md
|
|
127
|
+
- docs/ARCHITECTURE.md
|
|
128
|
+
- docs/BENCHMARKS.md
|
|
129
|
+
- docs/DEPLOYMENT.md
|
|
130
|
+
- docs/FAQ.md
|
|
131
|
+
- docs/MEMORY_SIZING.md
|
|
132
|
+
- docs/PERFORMANCE.md
|
|
133
|
+
- docs/PERFORMANCE_INTELLIGENCE.md
|
|
134
|
+
- docs/REDIS_GUIDE.md
|
|
135
|
+
- docs/SCALING.md
|
|
136
|
+
- docs/TROUBLESHOOTING.md
|
|
137
|
+
- lib/fast_exists.rb
|
|
138
|
+
- lib/fast_exists/active_record/extension.rb
|
|
139
|
+
- lib/fast_exists/active_record/hooks.rb
|
|
140
|
+
- lib/fast_exists/active_record/model_methods.rb
|
|
141
|
+
- lib/fast_exists/backends/base.rb
|
|
142
|
+
- lib/fast_exists/backends/file.rb
|
|
143
|
+
- lib/fast_exists/backends/memory.rb
|
|
144
|
+
- lib/fast_exists/backends/null.rb
|
|
145
|
+
- lib/fast_exists/backends/redis.rb
|
|
146
|
+
- lib/fast_exists/backends/redis_bloom.rb
|
|
147
|
+
- lib/fast_exists/backends/registry.rb
|
|
148
|
+
- lib/fast_exists/bit_array.rb
|
|
149
|
+
- lib/fast_exists/bloom/counting.rb
|
|
150
|
+
- lib/fast_exists/bloom/filter.rb
|
|
151
|
+
- lib/fast_exists/bloom/scalable.rb
|
|
152
|
+
- lib/fast_exists/cli.rb
|
|
153
|
+
- lib/fast_exists/configuration.rb
|
|
154
|
+
- lib/fast_exists/engine.rb
|
|
155
|
+
- lib/fast_exists/errors.rb
|
|
156
|
+
- lib/fast_exists/generators/install_generator.rb
|
|
157
|
+
- lib/fast_exists/generators/templates/fast_exists_initializer.rb
|
|
158
|
+
- lib/fast_exists/instrumentation/event_subscriber.rb
|
|
159
|
+
- lib/fast_exists/instrumentation/open_telemetry.rb
|
|
160
|
+
- lib/fast_exists/instrumentation/prometheus.rb
|
|
161
|
+
- lib/fast_exists/intelligence/analyzer.rb
|
|
162
|
+
- lib/fast_exists/intelligence/auditor.rb
|
|
163
|
+
- lib/fast_exists/intelligence/data_model.rb
|
|
164
|
+
- lib/fast_exists/intelligence/doctor.rb
|
|
165
|
+
- lib/fast_exists/intelligence/health.rb
|
|
166
|
+
- lib/fast_exists/intelligence/report/builder.rb
|
|
167
|
+
- lib/fast_exists/intelligence/report/console.rb
|
|
168
|
+
- lib/fast_exists/intelligence/report/csv.rb
|
|
169
|
+
- lib/fast_exists/intelligence/report/html.rb
|
|
170
|
+
- lib/fast_exists/intelligence/report/json.rb
|
|
171
|
+
- lib/fast_exists/intelligence/report/markdown.rb
|
|
172
|
+
- lib/fast_exists/intelligence/report/pdf.rb
|
|
173
|
+
- lib/fast_exists/intelligence/report/yaml.rb
|
|
174
|
+
- lib/fast_exists/intelligence/stats.rb
|
|
175
|
+
- lib/fast_exists/multi_tenancy/resolver.rb
|
|
176
|
+
- lib/fast_exists/multi_tenant/allocator.rb
|
|
177
|
+
- lib/fast_exists/multi_tenant/base.rb
|
|
178
|
+
- lib/fast_exists/multi_tenant/key_layout.rb
|
|
179
|
+
- lib/fast_exists/multi_tenant/pool.rb
|
|
180
|
+
- lib/fast_exists/multi_tenant/recommendation_engine.rb
|
|
181
|
+
- lib/fast_exists/multi_tenant/strategies/adaptive_strategy.rb
|
|
182
|
+
- lib/fast_exists/multi_tenant/strategies/base_strategy.rb
|
|
183
|
+
- lib/fast_exists/multi_tenant/strategies/global_strategy.rb
|
|
184
|
+
- lib/fast_exists/multi_tenant/strategies/per_tenant_strategy.rb
|
|
185
|
+
- lib/fast_exists/multi_tenant/strategies/shared_strategy.rb
|
|
186
|
+
- lib/fast_exists/optimizer/ai_advisor.rb
|
|
187
|
+
- lib/fast_exists/probabilistic/count_min_sketch.rb
|
|
188
|
+
- lib/fast_exists/probabilistic/cuckoo.rb
|
|
189
|
+
- lib/fast_exists/probabilistic/hyper_log_log.rb
|
|
190
|
+
- lib/fast_exists/railtie.rb
|
|
191
|
+
- lib/fast_exists/statistics/tracker.rb
|
|
192
|
+
- lib/fast_exists/tasks/fast_exists.rake
|
|
193
|
+
- lib/fast_exists/version.rb
|
|
194
|
+
homepage: https://github.com/fastexists/fast_exists
|
|
195
|
+
licenses:
|
|
196
|
+
- MIT
|
|
197
|
+
metadata:
|
|
198
|
+
homepage_uri: https://github.com/fastexists/fast_exists
|
|
199
|
+
source_code_uri: https://github.com/nirazan1/fast_exists
|
|
200
|
+
changelog_uri: https://github.com/nirazan1/fast_exists/blob/main/CHANGELOG.md
|
|
201
|
+
rdoc_options: []
|
|
202
|
+
require_paths:
|
|
203
|
+
- lib
|
|
204
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
205
|
+
requirements:
|
|
206
|
+
- - ">="
|
|
207
|
+
- !ruby/object:Gem::Version
|
|
208
|
+
version: 3.0.0
|
|
209
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
210
|
+
requirements:
|
|
211
|
+
- - ">="
|
|
212
|
+
- !ruby/object:Gem::Version
|
|
213
|
+
version: '0'
|
|
214
|
+
requirements: []
|
|
215
|
+
rubygems_version: 3.7.0.dev
|
|
216
|
+
specification_version: 4
|
|
217
|
+
summary: Ultra-fast existence checks for Ruby on Rails using probabilistic data structures
|
|
218
|
+
test_files: []
|