aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-09-07 15:26:26 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2011-09-07 15:26:47 -0700
commite1b500ec96987de595da1541a73a7d5fb9eece9c (patch)
tree1104d03e3e384e4a3f264cdcfa390e96a9159407 /activerecord
parente6adeaa2fa043d961ab9f027d10ca63a7ccc3323 (diff)
downloadrails-e1b500ec96987de595da1541a73a7d5fb9eece9c.tar.gz
rails-e1b500ec96987de595da1541a73a7d5fb9eece9c.tar.bz2
rails-e1b500ec96987de595da1541a73a7d5fb9eece9c.zip
LRU cache in mysql and sqlite are now per-process caches.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG6
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb27
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb24
-rw-r--r--activerecord/test/cases/adapters/mysql/statement_pool_test.rb23
-rw-r--r--activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb24
5 files changed, 82 insertions, 22 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 700e11ff94..143de81925 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,4 +1,8 @@
-*Rails 3.2.0 (unreleased)*
+Wed Sep 7 15:25:02 2011 Aaron Patterson <aaron@tenderlovemaking.com>
+
+ * lib/active_record/connection_adapters/mysql_adapter.rb: LRU cache
+ keys are per process id.
+ * lib/active_record/connection_adapters/sqlite_adapter.rb: ditto
* Support bulk change_table in mysql2 adapter, as well as the mysql one. [Jon Leighton]
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 73e3afe1d5..a1824fe396 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -94,27 +94,32 @@ module ActiveRecord
class StatementPool < ConnectionAdapters::StatementPool
def initialize(connection, max = 1000)
super
- @cache = {}
+ @cache = Hash.new { |h,pid| h[pid] = {} }
end
- def each(&block); @cache.each(&block); end
- def key?(key); @cache.key?(key); end
- def [](key); @cache[key]; end
- def length; @cache.length; end
- def delete(key); @cache.delete(key); end
+ def each(&block); cache.each(&block); end
+ def key?(key); cache.key?(key); end
+ def [](key); cache[key]; end
+ def length; cache.length; end
+ def delete(key); cache.delete(key); end
def []=(sql, key)
- while @max <= @cache.size
- @cache.shift.last[:stmt].close
+ while @max <= cache.size
+ cache.shift.last[:stmt].close
end
- @cache[sql] = key
+ cache[sql] = key
end
def clear
- @cache.values.each do |hash|
+ cache.values.each do |hash|
hash[:stmt].close
end
- @cache.clear
+ cache.clear
+ end
+
+ private
+ def cache
+ @cache[$$]
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 7c7e762c19..1932a849ee 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -52,29 +52,33 @@ module ActiveRecord
class StatementPool < ConnectionAdapters::StatementPool
def initialize(connection, max)
super
- @cache = {}
+ @cache = Hash.new { |h,pid| h[pid] = {} }
end
- def each(&block); @cache.each(&block); end
- def key?(key); @cache.key?(key); end
- def [](key); @cache[key]; end
- def length; @cache.length; end
+ def each(&block); cache.each(&block); end
+ def key?(key); cache.key?(key); end
+ def [](key); cache[key]; end
+ def length; cache.length; end
def []=(sql, key)
- while @max <= @cache.size
- dealloc(@cache.shift.last[:stmt])
+ while @max <= cache.size
+ dealloc(cache.shift.last[:stmt])
end
- @cache[sql] = key
+ cache[sql] = key
end
def clear
- @cache.values.each do |hash|
+ cache.values.each do |hash|
dealloc hash[:stmt]
end
- @cache.clear
+ cache.clear
end
private
+ def cache
+ @cache[$$]
+ end
+
def dealloc(stmt)
stmt.close unless stmt.closed?
end
diff --git a/activerecord/test/cases/adapters/mysql/statement_pool_test.rb b/activerecord/test/cases/adapters/mysql/statement_pool_test.rb
new file mode 100644
index 0000000000..83de90f179
--- /dev/null
+++ b/activerecord/test/cases/adapters/mysql/statement_pool_test.rb
@@ -0,0 +1,23 @@
+require 'cases/helper'
+
+module ActiveRecord::ConnectionAdapters
+ class MysqlAdapter
+ class StatementPoolTest < ActiveRecord::TestCase
+ def test_cache_is_per_pid
+ return skip('must support fork') unless Process.respond_to?(:fork)
+
+ cache = StatementPool.new nil, 10
+ cache['foo'] = 'bar'
+ assert_equal 'bar', cache['foo']
+
+ pid = fork {
+ lookup = cache['foo'];
+ exit!(!lookup)
+ }
+
+ Process.waitpid pid
+ assert $?.success?, 'process should exit successfully'
+ end
+ end
+ end
+end
diff --git a/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb b/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb
new file mode 100644
index 0000000000..ae272e2c4b
--- /dev/null
+++ b/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb
@@ -0,0 +1,24 @@
+require 'cases/helper'
+
+module ActiveRecord::ConnectionAdapters
+ class SQLiteAdapter
+ class StatementPoolTest < ActiveRecord::TestCase
+ def test_cache_is_per_pid
+ return skip('must support fork') unless Process.respond_to?(:fork)
+
+ cache = StatementPool.new nil, 10
+ cache['foo'] = 'bar'
+ assert_equal 'bar', cache['foo']
+
+ pid = fork {
+ lookup = cache['foo'];
+ exit!(!lookup)
+ }
+
+ Process.waitpid pid
+ assert $?.success?, 'process should exit successfully'
+ end
+ end
+ end
+end
+