Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Speed improvements for each().

  • Loading branch information...
commit 9b77daa461b67102a211ac1e241e082064214a58 1 parent a98eae0
@JEG2 authored
Showing with 34 additions and 2 deletions.
  1. +1 −0  CHANGELOG.txt
  2. +33 −2 lib/rufus/tokyo/hmethods.rb
View
1  CHANGELOG.txt
@@ -25,6 +25,7 @@
(Edo interface only)
- todo : reenabled #copy for Tyrant (Edo and Tokyo)
- added : query_count() to match query_delete() for tables (Edo and Tokyo)
+- todo : made iteration faster in most cases
== rufus-tokyo - 1.0.1 released 2009/09/18
View
35 lib/rufus/tokyo/hmethods.rb
@@ -59,8 +59,39 @@ def values
# Our classical 'each'
#
def each
-
- keys.each { |k| yield(k, self[k]) }
+ #
+ # drop to Edo's C API calls to avoid two-step iteration
+ # (keys() then each())
+ #
+ if defined?(@db) and %w[iterinit iternext].all? { |m| @db.respond_to?(m) }
+ @db.iterinit
+ while k = @db.iternext
+ yield(k, self[k])
+ end
+ #
+ # drop to Tokyo's FFI calls to avoid two-step iteration
+ # (keys() then each())
+ #
+ elsif self.class.name != "Rufus::Tokyo::Table" and # use String for Edo
+ defined?(@db) and
+ respond_to?(:lib) and
+ %w[abs_iterinit abs_iternext].all? { |m| lib.respond_to?(m) }
+ begin
+ lib.abs_iterinit(@db)
+ int = FFI::MemoryPointer.new(:int)
+ loop do
+ key_pointer = lib.abs_iternext(@db, int)
+ break if key_pointer.address.zero?
+ k = key_pointer.get_bytes(0, int.get_int(0))
+ yield(k, self[k])
+ end
+ ensure
+ int.free if int
+ end
+ # we couldn't do it fast, so go ahead with slow-but-accurate
+ else
+ keys.each { |k| yield(k, self[k]) }
+ end
end
# Turns this instance into a Ruby hash
Please sign in to comment.
Something went wrong with that request. Please try again.