Skip to content

Instantly share code, notes, and snippets.

@matt-stj
Created June 1, 2018 21:32
Show Gist options
  • Save matt-stj/d3885f8dd57bbac63b528b120fe27804 to your computer and use it in GitHub Desktop.
Save matt-stj/d3885f8dd57bbac63b528b120fe27804 to your computer and use it in GitHub Desktop.
const MinHeap = require('min-heap')
module.exports = class Sorter {
constructor(logSources, printer, async = false) {
this.heap = new MinHeap
this.min = null
this.logsObj = {}
this.currentMinLog = null
this.complete = false
this.logSources = logSources
this.printer = printer
this.async = async
}
initialSetup() {
this.async ? this.startAsync() : this.startSync()
}
startSync() {
this.logSources.map((source) => {
const logEntry = source.pop()
const date = logEntry.date.getTime()
logEntry.source = source
this.insertIntoLogsObj(date, logEntry)
this.heap.insert(date)
})
this.loopLogs()
}
async startAsync() {
await Promise.all(this.logSources.map(this.buildlogObjAsync.bind(this)))
this.loopLogsAsync()
}
async start() {
}
loopLogs() {
while(!this.complete) {
const min = this.heap.removeHead()
if(!min) {
this.complete = true
return this.printer.done()
}
const currentMinLog = this.logsObj[min]
if(currentMinLog.length) {
currentMinLog.forEach((log) => this.printAndPop(log))
} else {
this.printAndPop(currentMinLog)
}
}
}
async loopLogsAsync() {
while(!this.complete) {
const min = this.heap.removeHead()
// the heap does not refelct the logsObject
// the heap is empty while the logsObj is not
if(!min) {
this.complete = true
return this.printer.done()
}
const currentMinLog = this.logsObj[min]
if(currentMinLog.length) {
await currentMinLog.forEach((log) => this.printAndPopAsync(log))
} else {
await this.printAndPopAsync(currentMinLog)
}
}
}
printAndPop(currentMinLog) {
this.printer.print(currentMinLog)
const src = currentMinLog.source
const nextLog = src.pop()
if(!nextLog) { return }
const date = nextLog.date.getTime()
nextLog.source = src
this.insertIntoLogsObj(date, nextLog)
this.heap.insert(date)
}
async printAndPopAsync(currentMinLog) {
this.printer.print(currentMinLog)
const src = currentMinLog.source
const nextLog = await src.popAsync()
if(!nextLog) { return }
const date = nextLog.date.getTime()
nextLog.source = src
this.insertIntoLogsObj(date, nextLog)
this.heap.insert(date)
}
insertIntoLogsObj(date, logEntry) {
if(date in this.logsObj) {
const oldLogEntry = this.logsObj[date]
this.logsObj[date] = Array.isArray(oldLogEntry) ? oldLogEntry.concat(logEntry) : [oldLogEntry, logEntry]
} else {
this.logsObj[date] = logEntry
}
}
async buildlogObjAsync(source) {
const logEntry = await source.popAsync()
const date = logEntry.date.getTime()
logEntry.source = source
this.logsObj[date] = logEntry
this.heap.insert(date)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment