pack.coffee 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. mongojs = require "mongojs"
  2. async = require "async"
  3. db = mongojs.connect("localhost/sharelatex", ["docHistory"])
  4. BSON=db.bson.BSON
  5. util = require 'util'
  6. _ = require 'underscore'
  7. MAX_SIZE = 1024*1024
  8. MAX_COUNT = 1024
  9. MIN_COUNT = 100
  10. KEEP_OPS = 100
  11. insertPack = (packObj, callback) ->
  12. bulk = db.docHistory.initializeOrderedBulkOp();
  13. expect_nInserted = 1
  14. expect_nRemoved = packObj.pack.length
  15. console.log 'inserting', expect_nInserted, 'pack, will remove', expect_nRemoved, 'ops'
  16. bulk.insert packObj
  17. packObj.pack.forEach (op) ->
  18. bulk.find({_id:op._id}).removeOne()
  19. bulk.execute (err, result) ->
  20. if err? or result.nInserted != expect_nInserted or result.nRemoved != expect_nRemoved
  21. console.log err, result
  22. console.log 'nInserted', result.nInserted, 'nRemoved', result.nRemoved
  23. callback(err, result)
  24. packDocHistory = (doc_id, callback) ->
  25. console.log 'packing doc_id', doc_id
  26. db.docHistory.find({doc_id:mongojs.ObjectId(doc_id),pack:{$exists:false}}).sort {v:1}, (err, docs) ->
  27. packs = []
  28. top = null
  29. origDocs = docs.length
  30. # keep the last KEEP_OPS as individual ops
  31. docs = docs.slice(0,-KEEP_OPS)
  32. docs.forEach (d,i) ->
  33. sz = BSON.calculateObjectSize(d)
  34. if top? && top.pack.length < MAX_COUNT && top.sz + sz < MAX_SIZE
  35. top.pack = top.pack.concat {v: d.v, meta: d.meta, op: d.op, _id: d._id}
  36. top.sz += sz
  37. top.v_end = d.v
  38. top.meta.end_ts = d.meta.end_ts
  39. return
  40. else if sz < MAX_SIZE
  41. # create a new pack
  42. top = _.clone(d)
  43. top.pack = [ {v: d.v, meta: d.meta, op: d.op, _id: d._id} ]
  44. top.meta = { start_ts: d.meta.start_ts, end_ts: d.meta.end_ts }
  45. top.sz = sz
  46. delete top.op
  47. delete top._id
  48. packs.push top
  49. else
  50. # keep the op
  51. console.log 'keeping large op unchanged'
  52. # only store packs with a sufficient number of ops, discard others
  53. packs = packs.filter (packObj) ->
  54. packObj.pack.length > MIN_COUNT
  55. console.log 'docs', origDocs, 'packs', packs.length
  56. async.each packs, insertPack, (err, result) ->
  57. if err?
  58. console.log 'err', err
  59. console.log 'done writing packs'
  60. callback err, result
  61. async.each process.argv.slice(2), (doc_id, callback) ->
  62. packDocHistory(doc_id, callback)
  63. , (err, results) ->
  64. console.log 'closing db'
  65. db.close()