ProjectIterator.coffee 2.1 KB

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