Jump To …

CompressedUnsignedLongByteIterable.coffee

fs = require 'fs'
Addr64 = (require '../Addr64.coffee').Addr64
LogUtil = (require '../LogUtil.coffee').LogUtil
ByteIterableBase =
  (require '../../database/impl/iterate/ByteIterableBase.coffee').ByteIterableBase
IllegalArgumentError =
  (require '../../errors/IllegalArgumentError.coffee').IllegalArgumentError
EventEmitter = (require 'events').EventEmitter

TODO there is some cache in exodus - what is it for?

This class is used for compressed reading and writing of numbers using iterators.

class CompressedUnsignedLongByteIterable extends ByteIterableBase

@private

  MAX_DIGIT_NUMBER: 10

@private

  l: undefined

  @EMITTER = new EventEmitter()
  @EMITTER.setMaxListeners 0

Constructor.

  @create: (o) ->
    if !o? then o = new CompressedUnsignedLongByteIterable
    return o

Constructor.

@param l.

  @create$int: (l, o) ->
    if !o? then o = new CompressedUnsignedLongByteIterable
    if (l < 0)
      throw new IllegalArgumentError(l.toString())
    o.l = l
    return o

Gets new iterable.

@param l number. @return new iterable.

  @getIterable$int: (l) ->
    return CompressedUnsignedLongByteIterable.create$int l

Calculates the compressed number length.

@param l number. @return number length.

  @getCompressedSize$int: (l) ->
    ll = l
    ll >>>= 7
    result = 1
    while ll > 0
      result += 1
      ll >>>= 7
    return result

Writes compressed number to stream.

@param l number. @param stream the stream to write number in.

@return reference to the same stream (just for tests!).

  @fillBytes$int$LightOutputStream: (l, stream) ->
    if (l < 0)
      throw new IllegalArgumentError(l.toString())
    ll = l
    while true
      b = ll & 0x7f
      if ((ll >>>= 7) == 0)
        stream.writeFast$int b | 0x80
        break
      stream.writeFast$int b
    return stream

Reads int from iterable. Method contains corruption check: if we have already read MAXDIGITNUMBER and continue reading, it means that info is not a number.

@param iterable the iterable to read data from. @return number if it could be read without events, and undefined otherwise. If undefined, the 'getInt' event is emitted with number or undefined if it can't be read.

  @getInt$ByteIterable$emit: (iterable) ->
    CompressedUnsignedLongByteIterable.
    getInt$ByteIterator$emit iterable.getIterator()

Reads int from iterable. Method contains corruption check: if we have already read MAXDIGITNUMBER and continue reading, it means that info is not a number.

@param iterator the iterator to the place to read data from. @return number if it could be read without events, and undefined otherwise. If undefined, the 'getInt' event is emitted with number or undefined if it can't be read.

  @getInt$ByteIterator$emit: (iterator) ->
    num = 0
    ll = 0
    shift = 0
    valueIsRead = false
    emitGetInt = true
    oldIt = iterator.copy()
    iterator.removeAllListeners()
    if oldIt.addr != undefined
      addrString = Addr64.addr64ToString$Addr64$int(oldIt.addr,
              LogUtil.LOG_NAME_BASE)
    emit = false
    onGetNext = (v) =>
      if v != undefined
        if num > @MAX_DIGIT_NUMBER
          CompressedUnsignedLongByteIterable.EMITTER.emit 'getInt' + addrString,
                  undefined, iterator
          return undefined
        ll += ((v & 0x7f) << shift)
        if (v & 0x80) != 0
          iterator.removeAllListeners 'next'
          if emit
            CompressedUnsignedLongByteIterable.EMITTER.emit 'getInt' +
            addrString, ll, iterator
            return undefined
          return ll
        shift += 7
        num += 1
        onGetNext iterator.next$emit()
    iterator.on 'next', (v) =>
      emit = true
      onGetNext v
    onGetNext iterator.next$emit()

This methods are the same as getInt. Used for compatibility.

  @getLong$ByteIterable$emit: (iterable) ->
    CompressedUnsignedLongByteIterable.
    getInt$ByteIterator$emit iterable.getIterator()

  @getLong$ByteIterator$emit: (iterator) ->
    CompressedUnsignedLongByteIterable.
    getInt$ByteIterator$emit iterator

exports.CompressedUnsignedLongByteIterable = CompressedUnsignedLongByteIterable