source: trip-planner-front/node_modules/hdr-histogram-js/assembly/encoding.ts@ 59329aa

Last change on this file since 59329aa was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*
2 * This is a AssemblyScript port of the original Java version, which was written by
3 * Gil Tene as described in
4 * https://github.com/HdrHistogram/HdrHistogram
5 * and released to the public domain, as explained at
6 * http://creativecommons.org/publicdomain/zero/1.0/
7 */
8
9import ByteBuffer from "./ByteBuffer";
10import Histogram from "./Histogram";
11import ZigZagEncoding from "./ZigZagEncoding";
12
13const V2EncodingCookieBase = 0x1c849303;
14const V2CompressedEncodingCookieBase = 0x1c849304;
15const V2maxWordSizeInBytes = 9; // LEB128-64b9B + ZigZag require up to 9 bytes per word
16const encodingCookie = V2EncodingCookieBase | 0x10; // LSBit of wordsize byte indicates TLZE Encoding
17const compressedEncodingCookie = V2CompressedEncodingCookieBase | 0x10; // LSBit of wordsize byte indicates TLZE Encoding
18
19function fillBufferFromCountsArray<T, U>(
20 self: Histogram<T, U>,
21 buffer: ByteBuffer
22): void {
23 const countsLimit = self.countsArrayIndex(self.maxValue) + 1;
24 let srcIndex = 0;
25
26 while (srcIndex < countsLimit) {
27 // V2 encoding format uses a ZigZag LEB128-64b9B encoded long. Positive values are counts,
28 // while negative values indicate a repeat zero counts.
29 const count = self.getCountAtIndex(srcIndex++);
30 if (count < 0) {
31 throw new Error(
32 "Cannot encode histogram containing negative counts (" +
33 count.toString() +
34 ") at index " +
35 srcIndex.toString() +
36 ", corresponding the value range [" +
37 self.lowestEquivalentValue(self.valueFromIndex(srcIndex)).toString() +
38 "," +
39 self
40 .nextNonEquivalentValue(self.valueFromIndex(srcIndex))
41 .toString() +
42 ")"
43 );
44 }
45 // Count trailing 0s (which follow this count):
46 let zerosCount = 0;
47 if (count == 0) {
48 zerosCount = 1;
49 while (srcIndex < countsLimit && self.getCountAtIndex(srcIndex) == 0) {
50 zerosCount++;
51 srcIndex++;
52 }
53 }
54 if (zerosCount > 1) {
55 ZigZagEncoding.encode(buffer, -zerosCount);
56 } else {
57 ZigZagEncoding.encode(buffer, count);
58 }
59 }
60}
61
62/**
63 * Encode this histogram into a ByteBuffer
64 * @param buffer The buffer to encode into
65 * @return The number of bytes written to the buffer
66 */
67export function encodeIntoByteBuffer<T, U>(
68 self: Histogram<T, U>,
69 buffer: ByteBuffer
70): i32 {
71 const initialPosition = buffer.position;
72 buffer.putInt32(encodingCookie);
73 buffer.putInt32(0); // Placeholder for payload length in bytes.
74 buffer.putInt32(1);
75 buffer.putInt32(self.numberOfSignificantValueDigits);
76 buffer.putInt64(self.lowestDiscernibleValue);
77 buffer.putInt64(self.highestTrackableValue);
78 buffer.putInt64(1);
79
80 const payloadStartPosition = buffer.position;
81 fillBufferFromCountsArray(self, buffer);
82
83 const backupIndex = buffer.position;
84 buffer.position = initialPosition + 4;
85 buffer.putInt32(backupIndex - payloadStartPosition); // Record the payload length
86
87 buffer.position = backupIndex;
88
89 return backupIndex - initialPosition;
90}
91
92function fillCountsArrayFromSourceBuffer<T, U>(
93 self: Histogram<T, U>,
94 sourceBuffer: ByteBuffer,
95 lengthInBytes: u32,
96 wordSizeInBytes: u32
97): i32 {
98 if (
99 wordSizeInBytes != 2 &&
100 wordSizeInBytes != 4 &&
101 wordSizeInBytes != 8 &&
102 wordSizeInBytes != V2maxWordSizeInBytes
103 ) {
104 throw new Error(
105 "word size must be 2, 4, 8, or V2maxWordSizeInBytes (" +
106 V2maxWordSizeInBytes.toString() +
107 ") bytes"
108 );
109 }
110 let dstIndex: i32 = 0;
111 const endPosition = sourceBuffer.position + lengthInBytes;
112 while (sourceBuffer.position < endPosition) {
113 let zerosCount: i32 = 0;
114 let count = <i32>ZigZagEncoding.decode(sourceBuffer);
115 if (count < 0) {
116 zerosCount = -count;
117 dstIndex += zerosCount; // No need to set zeros in array. Just skip them.
118 } else {
119 self.setCountAtIndex(dstIndex++, count);
120 }
121 }
122 return dstIndex; // this is the destination length
123}
124
125function getCookieBase(cookie: u32): u32 {
126 return cookie & ~0xf0;
127}
128
129function getWordSizeInBytesFromCookie(cookie: u32): u32 {
130 if (
131 getCookieBase(cookie) == V2EncodingCookieBase ||
132 getCookieBase(cookie) == V2CompressedEncodingCookieBase
133 ) {
134 return V2maxWordSizeInBytes;
135 }
136 const sizeByte = (cookie & 0xf0) >> 4;
137 return sizeByte & 0xe;
138}
139
140export function decodeFromByteBuffer<T, U>(
141 buffer: ByteBuffer,
142 minBarForHighestTrackableValue: u64
143): Histogram<T, U> {
144 const cookie = buffer.getInt32();
145
146 let payloadLengthInBytes: u32;
147 let numberOfSignificantValueDigits: u8;
148 let lowestTrackableUnitValue: u64;
149 let highestTrackableValue: u64;
150
151 if (getCookieBase(cookie) === V2EncodingCookieBase) {
152 if (getWordSizeInBytesFromCookie(cookie) != V2maxWordSizeInBytes) {
153 throw new Error(
154 "The buffer does not contain a Histogram (no valid cookie found)"
155 );
156 }
157 payloadLengthInBytes = buffer.getInt32();
158 buffer.getInt32(); // normalizingIndexOffset not used
159 numberOfSignificantValueDigits = <u8>buffer.getInt32();
160 lowestTrackableUnitValue = buffer.getInt64();
161 highestTrackableValue = buffer.getInt64();
162 buffer.getInt64(); // integerToDoubleValueConversionRatio not used
163 } else {
164 throw new Error(
165 "The buffer does not contain a Histogram (no valid V2 encoding cookie found)"
166 );
167 }
168
169 highestTrackableValue = max(
170 highestTrackableValue,
171 minBarForHighestTrackableValue
172 );
173
174 const histogram: Histogram<T, U> = instantiate<Histogram<T, U>>(
175 lowestTrackableUnitValue,
176 highestTrackableValue,
177 numberOfSignificantValueDigits
178 );
179
180 const filledLength = fillCountsArrayFromSourceBuffer(
181 histogram,
182 buffer,
183 payloadLengthInBytes,
184 V2maxWordSizeInBytes
185 );
186
187 histogram.establishInternalTackingValues(filledLength);
188
189 return histogram;
190}
Note: See TracBrowser for help on using the repository browser.