Skip to content

Commit

Permalink
Can search through a segment.
Browse files Browse the repository at this point in the history
  • Loading branch information
Doug Youch committed May 20, 2010
1 parent 8558a23 commit d12fa76
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
24 changes: 24 additions & 0 deletions app/models/user_segment.rb
Expand Up @@ -107,5 +107,29 @@ def paginate(page,args = {})
:count => items.length
}, items ]
end

def search(offset=0, args={})
args = args.clone.symbolize_keys!

page_size = args.delete(:per_page).to_i
page_size = 20 if page_size <= 0

cache_offset = offset % UserSegmentCache::SIZE

ids = []
((offset / UserSegmentCache::SIZE).to_i..self.user_segment_caches.length-1).each do |position|
cache = self.user_segment_caches.find_by_position(position)
cache_offset, cache_ids = cache.search(cache_offset, args.merge(:limit => page_size-ids.length))
ids = ids + cache_ids
offset = UserSegmentCache::SIZE * position + cache_offset
cache_offset = 0
break if ids.length >= page_size
end

args.delete(:conditions)
args.delete(:joins)
users = EndUser.find(:all, args.merge(:conditions => {:id => ids}))
return [offset, users]
end
end

27 changes: 27 additions & 0 deletions app/models/user_segment_cache.rb
Expand Up @@ -19,6 +19,33 @@ def fetch_users(opts={})
ids.map { |id| users_by_id[id] }.compact
end

def search(offset=0, opts={})
opts = opts.clone.symbolize_keys!
opts.delete(:offset)
opts.delete(:include)
limit = opts.delete(:limit) || 20
batch_size = opts.delete(:batch_size) || DEFAULT_BATCH_SIZE
num_chunks = (self.id_list.size / batch_size).to_i
num_chunks = num_chunks.succ if (self.id_list.length % batch_size) > 0

base_scope = EndUser.scoped(opts)

ids = []
((offset/batch_size).to_i..num_chunks-1).each do |chunk|
sub_list = self.id_list[offset..(offset+batch_size-1)]
scope = base_scope.scoped(:select => 'id', :conditions => {:id => sub_list})
users_by_id = scope.find(:all).index_by(&:id)
ids = ids + sub_list.map { |id| users_by_id[id] ? id : nil }.compact unless users_by_id.empty?
offset = offset + batch_size
break if ids.length > limit
end

has_more = ids.length > limit
ids = ids[0..limit-1] if has_more
offset = ids.size > 0 ? self.id_list.index(ids[-1]) : 0
[offset, ids]
end

def find_in_batches(opts={})
limit = opts[:batch_size] || DEFAULT_BATCH_SIZE
offset = 0
Expand Down

0 comments on commit d12fa76

Please sign in to comment.