ProjectIterator.coffee 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. Heap = require "heap"
  2. module.exports = ProjectIterator =
  3. class ProjectIterator
  4. constructor: (packs, @before, @getPackByIdFn) ->
  5. byEndTs = (a,b) -> (b.meta.end_ts - a.meta.end_ts) || (a.fromIndex - b.fromIndex)
  6. @packs = packs.slice().sort byEndTs
  7. @queue = new Heap(byEndTs)
  8. next: (callback) ->
  9. # what's up next
  10. #console.log ">>> top item", iterator.packs[0]
  11. iterator = this
  12. before = @before
  13. queue = iterator.queue
  14. opsToReturn = []
  15. nextPack = iterator.packs[0]
  16. lowWaterMark = nextPack?.meta.end_ts || 0
  17. nextItem = queue.peek()
  18. #console.log "queue empty?", queue.empty()
  19. #console.log "nextItem", nextItem
  20. #console.log "nextItem.meta.end_ts", nextItem?.meta.end_ts
  21. #console.log "lowWaterMark", lowWaterMark
  22. while before? and nextPack?.meta.start_ts > before
  23. # discard pack that is outside range
  24. iterator.packs.shift()
  25. nextPack = iterator.packs[0]
  26. lowWaterMark = nextPack?.meta.end_ts || 0
  27. if (queue.empty() or nextItem?.meta.end_ts <= lowWaterMark) and nextPack?
  28. # retrieve the next pack and populate the queue
  29. return @getPackByIdFn nextPack.project_id, nextPack.doc_id, nextPack._id, (err, pack) ->
  30. return callback(err) if err?
  31. iterator.packs.shift() # have now retrieved this pack, remove it
  32. #console.log "got pack", pack
  33. for op in pack.pack when (not before? or op.meta.end_ts < before)
  34. #console.log "adding op", op
  35. op.doc_id = nextPack.doc_id
  36. op.project_id = nextPack.project_id
  37. queue.push op
  38. # now try again
  39. return iterator.next(callback)
  40. #console.log "nextItem", nextItem, "lowWaterMark", lowWaterMark
  41. while nextItem? and (nextItem?.meta.end_ts > lowWaterMark)
  42. opsToReturn.push nextItem
  43. queue.pop()
  44. nextItem = queue.peek()
  45. #console.log "queue empty?", queue.empty()
  46. #console.log "nextPack", nextPack?
  47. if queue.empty() and not nextPack? # got everything
  48. iterator._done = true
  49. callback(null, opsToReturn)
  50. done: () ->
  51. return @_done