ConversionManager.coffee 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. {db, ObjectId} = require "./mongojs"
  2. ConcatManager = require "./ConcatManager"
  3. module.exports = ConversionManager =
  4. OPS_TO_LEAVE: 10
  5. popLatestCompressedUpdate: (doc_id, callback = (error, update) ->) ->
  6. db.docHistory.findAndModify
  7. query: { doc_id: ObjectId(doc_id) }
  8. fields: { docOps: { $slice: -1 } }
  9. update: { $pop: { docOps: 1 } }
  10. , (error, history = { docOps: [] }) ->
  11. return callback(error) if error?
  12. callback null, history.docOps[0]
  13. insertCompressedUpdates: (doc_id, updates, callback = (error) ->) ->
  14. db.docHistory.update { doc_id: ObjectId(doc_id) }, { $push: { docOps: { $each: updates } } }, { upsert: true }, callback
  15. popOldRawUpdates: (doc_id, callback = (error, updates) ->) ->
  16. db.docOps.find { doc_id: ObjectId(doc_id) }, { version: true, tailVersion: true }, (error, docs) ->
  17. return callback(error) if error?
  18. return callback(new Error("doc not found")) if docs.length == 0
  19. doc = docs[0]
  20. currentVersion = doc.version
  21. tailVersion = doc.tailVersion or 0
  22. if currentVersion - tailVersion > ConversionManager.OPS_TO_LEAVE
  23. db.docOps.findAndModify
  24. query: { doc_id: ObjectId(doc_id), version: currentVersion }
  25. update: {
  26. $push: { docOps: { $each: [], $slice: - ConversionManager.OPS_TO_LEAVE } }
  27. $set: tailVersion: currentVersion - ConversionManager.OPS_TO_LEAVE,
  28. }
  29. fields: { docOps: $slice: currentVersion - tailVersion - ConversionManager.OPS_TO_LEAVE }
  30. , (error, doc) ->
  31. return callback(error) if error?
  32. if !doc?
  33. # Version was modified since so try again
  34. return ConversionManager.popOldRawUpdates doc_id, callback
  35. else
  36. return callback null, doc.docOps
  37. else
  38. callback null, []
  39. convertOldRawUpdates: (doc_id, callback = (error) ->) ->
  40. ConversionManager.popOldRawUpdates doc_id, (error, rawUpdates) ->
  41. return callback(error) if error?
  42. length = rawUpdates.length
  43. normalizedRawUpdates = []
  44. for rawUpdate in rawUpdates
  45. normalizedRawUpdates = normalizedRawUpdates.concat ConcatManager.normalizeUpdate(rawUpdate)
  46. rawUpdates = normalizedRawUpdates
  47. ConversionManager.popLatestCompressedUpdate doc_id, (error, lastCompressedUpdate) ->
  48. return callback(error) if error?
  49. if !lastCompressedUpdate?
  50. lastCompressedUpdate = rawUpdates.shift()
  51. if !lastCompressedUpdate?
  52. # No saved versions, no raw updates, nothing to do
  53. return callback()
  54. compressedUpdates = [lastCompressedUpdate]
  55. for rawUpdate in rawUpdates
  56. lastCompressedUpdate = compressedUpdates.pop()
  57. if lastCompressedUpdate?
  58. compressedUpdates = compressedUpdates.concat ConcatManager.concatTwoUpdates lastCompressedUpdate, rawUpdate
  59. else
  60. compressedUpdates.push rawUpdate
  61. ConversionManager.insertCompressedUpdates doc_id, compressedUpdates, (error) ->
  62. return callback(error) if error?
  63. console.log doc_id, "Pushed doc ops", length
  64. callback()