Skip to content

Commit d8c758c

Browse files
authored
Merge pull request #40 from cardmagic/fix-race-condition-bug-deleting-categories
Fix race condition bug deleting categories
2 parents 17143ab + 9b559f2 commit d8c758c

File tree

6 files changed

+42
-12
lines changed

6 files changed

+42
-12
lines changed

.github/workflows/ruby.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
runs-on: ubuntu-latest
2323
strategy:
2424
matrix:
25-
ruby-version: ['2.7', '3.0', '3.1', '3.2', 'head']
25+
ruby-version: ['2.7', 'head']
2626

2727
steps:
2828
- uses: actions/checkout@v4

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ gemspec
33

44
gem 'fast-stemmer'
55
gem 'matrix'
6+
gem 'mutex_m'

Gemfile.lock

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
PATH
22
remote: .
33
specs:
4-
classifier (1.4.0)
5-
fast-stemmer (~> 1.0.0)
4+
classifier (1.4.2)
5+
fast-stemmer (~> 1.0)
6+
mutex_m (~> 0.2)
67
rake
78

89
GEM
@@ -11,6 +12,7 @@ GEM
1112
fast-stemmer (1.0.2)
1213
matrix (0.4.2)
1314
minitest (5.18.1)
15+
mutex_m (0.2.0)
1416
psych (5.1.2)
1517
stringio
1618
rake (13.0.6)
@@ -28,6 +30,7 @@ DEPENDENCIES
2830
fast-stemmer
2931
matrix
3032
minitest
33+
mutex_m
3134
rdoc
3235

3336
BUNDLED WITH

classifier.gemspec

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Gem::Specification.new do |s|
22
s.name = 'classifier'
3-
s.version = '1.4.1'
3+
s.version = '1.4.2'
44
s.summary = 'A general classifier module to allow Bayesian and other types of classifications.'
55
s.description = 'A general classifier module to allow Bayesian and other types of classifications.'
66
s.author = 'Lucas Carlson'
@@ -9,7 +9,8 @@ Gem::Specification.new do |s|
99
s.files = Dir['{lib}/**/*.rb', 'bin/*', 'LICENSE', '*.md', 'test/*']
1010
s.license = 'LGPL'
1111

12-
s.add_dependency 'fast-stemmer', '~> 1.0.0'
12+
s.add_dependency 'fast-stemmer', '~> 1.0'
13+
s.add_dependency 'mutex_m', '~> 0.2'
1314
s.add_dependency 'rake'
1415
s.add_development_dependency 'minitest'
1516
s.add_development_dependency 'rdoc'

lib/classifier/bayes.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,11 @@ def remove_category(category)
152152
category = category.prepare_category_name
153153
raise StandardError, "No such category: #{category}" unless @categories.key?(category)
154154

155+
@total_words -= @category_word_count[category].to_i
156+
155157
@categories.delete(category)
156158
@category_counts.delete(category)
157159
@category_word_count.delete(category)
158-
@total_words -= @category_word_count[category].to_i
159160
end
160161
end
161162
end

test/bayes/bayesian_test.rb

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,6 @@ def test_remove_category
5454
assert_equal ['Interesting'], @classifier.categories
5555
end
5656

57-
def test_remove_nonexistent_category
58-
assert_raises(StandardError) do
59-
@classifier.remove_category 'NonexistentCategory'
60-
end
61-
end
62-
6357
def test_remove_category_affects_classification
6458
@classifier.train_interesting 'This is interesting content'
6559
@classifier.train_uninteresting 'This is uninteresting content'
@@ -94,4 +88,34 @@ def test_remove_category_preserves_other_category_data
9488

9589
assert_equal interesting_classification, @classifier.classify('This is interesting')
9690
end
91+
92+
def test_remove_category_check_counts
93+
initial_total_words = @classifier.instance_variable_get(:@total_words)
94+
category_word_count = @classifier.instance_variable_get(:@category_word_count)['Interesting']
95+
96+
@classifier.remove_category('Interesting')
97+
98+
assert_nil @classifier.instance_variable_get(:@categories)['Interesting']
99+
assert_equal @classifier.instance_variable_get(:@category_counts)['Interesting'], 0
100+
assert_equal @classifier.instance_variable_get(:@category_word_count)['Interesting'], 0
101+
102+
new_total_words = @classifier.instance_variable_get(:@total_words)
103+
assert_equal initial_total_words - category_word_count, new_total_words
104+
end
105+
106+
def test_remove_category_updates_total_words_before_deletion
107+
initial_total_words = @classifier.instance_variable_get(:@total_words)
108+
category_word_count = @classifier.instance_variable_get(:@category_word_count)['Interesting']
109+
110+
@classifier.remove_category('Interesting')
111+
112+
new_total_words = @classifier.instance_variable_get(:@total_words)
113+
assert_equal initial_total_words - category_word_count, new_total_words
114+
end
115+
116+
def test_remove_nonexistent_category
117+
assert_raises(StandardError, 'No such category: Nonexistent Category') do
118+
@classifier.remove_category('Nonexistent Category')
119+
end
120+
end
97121
end

0 commit comments

Comments
 (0)