Class: File
- Inherits:
-
Object
- Object
- File
- Defined in:
- lib/rsgrep/file.rb
Class Method Summary collapse
Instance Method Summary collapse
Class Method Details
.sgrep(key, filename, options = {}) ⇒ Object
2 3 4 5 6 |
# File 'lib/rsgrep/file.rb', line 2 def self.sgrep key, filename, = {} File.open(filename) do |f| f.sgrep key, end end |
Instance Method Details
#sgrep(key, options = {}) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/rsgrep/file.rb', line 8 def sgrep key, = {} # initialise the variables that the binary search algorithm needs. hi = size lo = 0 mid = (hi + lo) / 2 ret = [] if [:insensitive] comparator = Proc.new do |key, line| key = key.downcase line = line.downcase if line.start_with? key 0 else key <=> line end end else comparator = Proc.new do |key, line| if line.start_with? key 0 else key <=> line end end end while lo < mid and mid < hi seek(mid) seek(-2, IO::SEEK_CUR) while (c = getc) != "\n" and c != nil case comparator.call(key, (line = gets)) when 0 # So we've found a line that matches the key, but this may not be the # first line that does (due to the nature of binary searching). This # begin/end block scans backwards in the file to find the first line # that matches the key. begin # Seek back 2 lines because "gets" will advance the file pointer # forward. 2.times do seek(-2, IO::SEEK_CUR) # First read will always be a newline, skip it seek(-2, IO::SEEK_CUR) while (c = getc) != "\n" and c != nil end end while comparator.call(key, (line = gets)) == 0 # Then scan forward line by line until all of the lines that match have # been added to the return array. ret << line.rstrip while (line = gets) != nil and comparator.call(key, line) == 0 # and we're done! return ret when -1 # Key is less than the line. Shift the hi value down and recalculate the # mid. hi = mid mid = (hi + lo) / 2 when 1 # Key is greater than the line. Shift the lo value up and recalculate # the mid. lo = mid mid = (hi + lo) / 2 else raise "Should not be raised, ever." end end return ret end |