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
|