SRC_DIR='../../../src/log/'

assert = require 'assert'
utils = require '../../TestUtils.coffee'
Addr64 = (require SRC_DIR + 'Addr64.coffee').Addr64
Cache = (require SRC_DIR + 'LogCache.coffee').LogCache
LoggableToWrite = (require SRC_DIR + 'LoggableToWrite').LoggableToWrite
NullLoggable = (require SRC_DIR + 'NullLoggable').NullLoggable
RandomAccessLoggable =
  (require SRC_DIR + 'RandomAccessLoggable').RandomAccessLoggable
ArrayByteIterable =
  (require SRC_DIR + '../database/impl/iterate/ArrayByteIterable.coffee').
  ArrayByteIterable
LogConfig = (require SRC_DIR + 'LogConfig.coffee').LogConfig
Log = (require SRC_DIR + 'Log').Log
LogUtil = (require SRC_DIR + 'LogUtil').LogUtil

console.log ""
console.log "*** Started Log Performance test ***"
console.log ""

# Constants
N = 60000
fileSize = 32 #KB
pageSize = 1024 * 16 #bytes
NPages = 100
config = undefined
console.log "Writing and reading", N, "records"

# Initialisation
path = utils.getNewDirName()
addrs = new Array()
comp = ArrayByteIterable.create$Buffer new Buffer("My beautiful value is equal")

calculateDiff = (d1, d2) ->
  h = parseInt d2.getHours()
  h -= parseInt d1.getHours()
  m = parseInt d2.getMinutes() + h * 60
  m -= parseInt d1.getMinutes()
  s = parseInt d2.getSeconds() + m * 60
  s -= parseInt d1.getSeconds()
  ms = parseInt d2.getMilliseconds()
  ms -= parseInt d1.getMilliseconds()
  ms = ms / 1000.0
  s = m + s + ms

firstTest = () =>
  config = LogConfig.create()
  config.setDir path
  config.setFileSize fileSize
  config.setCachePageSize pageSize
  config.setCacheOpenFilesCount NPages
  log = Log.create$LogConfig config
  log.once 'close', (fn) =>
    d2 = new Date()
    s = calculateDiff d1, d2
    console.log "The size of written data is", log.getHighAddress().toFloat() / 1024 / 1024,
            "MB"
    console.log "Records are written in", s, "sec"
    console.log "Speed of writing is", log.getHighAddress().toFloat() / s / 1024 / 1024,
            "MB/sec"
    secondTest()
  d1 = new Date()
  for i in [0..N - 1]
    b = ArrayByteIterable.create$Buffer new Buffer("My beautiful value is equal to " + i.toString())
    d = LoggableToWrite.create$int$ByteIterable$int i, b, i
    addrs[i] = log.write$Loggable d
  log.close$emit()

secondTest = () =>
  log2 = Log.create$LogConfig config
  onRead = (loggable) =>
    n += 1
    if n % (N / 10) == 0
      console.log (n / (N / 10) * 10).toString(), "% are read"
    if n == N
      d2 = new Date()
      s = calculateDiff d1, d2
      console.log "Records are read in", s, "sec"
      console.log "Speed of reading is", log2.getHighAddress().toFloat() / s / 1024 / 1024,
              "MB/sec"
      console.log ""
      console.log "*** Finished Log Performance Test ***"
      console.log ""
  n = 0
  d1 = new Date()
  for i in [0..(N - 1)]
    rand = Math.floor Math.random() * (N - 1)
    addrString = Addr64.addr64ToString$Addr64$int(addrs[rand], LogUtil.LOG_NAME_BASE)
    log2.once 'read' + addrString, (loggable) =>
      onRead loggable
    log2.read$Addr64$emit addrs[rand]

firstTest()
