mirror of
https://github.com/tiennm99/tjahzi.git
synced 2026-10-14 04:16:39 +00:00
Re #9: Fixed bugs and added test.
This commit is contained in:
1 parent
29f2dd1313
commit
b2d5d1e0d4
2 files changed
+191
-35
No files matched your search
@@ -13,6 +13,19 @@ public class LogBufferSerializer {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
public int calculateRequiredSizeAscii(
|
||||
Map<String, String> labels,
|
||||
String logLevelLabel,
|
||||
String logLevel,
|
||||
ByteBuffer line
|
||||
) {
|
||||
int logLineSize = Integer.BYTES + line.remaining();
|
||||
int logLevelSize = calculateOptionalLabelSizeAscii(logLevelLabel, logLevel);
|
||||
int headerAndLabelsSize = calculateRequiredSizeAscii(labels);
|
||||
|
||||
return headerAndLabelsSize + logLineSize + logLevelSize;
|
||||
}
|
||||
|
||||
public void writeTo(
|
||||
int cursor,
|
||||
long timestamp,
|
||||
@@ -21,16 +34,54 @@ public class LogBufferSerializer {
|
||||
String logLevel,
|
||||
ByteBuffer line
|
||||
) {
|
||||
cursor = writeHeader(cursor, timestamp, labels);
|
||||
cursor = writeHeader(
|
||||
cursor,
|
||||
timestamp,
|
||||
labels,
|
||||
logLevelLabel != null
|
||||
);
|
||||
|
||||
cursor = writeLabels(cursor, labels);
|
||||
cursor = writeLabel(
|
||||
cursor = writeOptionalLabel(
|
||||
cursor,
|
||||
logLevelLabel,
|
||||
logLevel
|
||||
);
|
||||
|
||||
writeLogLine(cursor, line);
|
||||
}
|
||||
|
||||
private int writeHeader(
|
||||
int cursor,
|
||||
long timestamp,
|
||||
Map<String, String> labels,
|
||||
boolean hasLogLevelLabel
|
||||
) {
|
||||
buffer.putLong(cursor, timestamp);
|
||||
cursor += Long.BYTES;
|
||||
|
||||
int labelsCount = labels.size();
|
||||
if (hasLogLevelLabel) {
|
||||
labelsCount++;
|
||||
}
|
||||
|
||||
buffer.putInt(cursor, labelsCount);
|
||||
cursor += Integer.BYTES;
|
||||
return cursor;
|
||||
}
|
||||
|
||||
private int writeLabels(int cursor, Map<String, String> labels) {
|
||||
for (Map.Entry<String, String> entry : labels.entrySet()) {
|
||||
cursor = writeLabel(
|
||||
cursor,
|
||||
entry.getKey(),
|
||||
entry.getValue()
|
||||
);
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
private void writeLogLine(int cursor, ByteBuffer line) {
|
||||
buffer.putInt(cursor, line.remaining());
|
||||
cursor += Integer.BYTES;
|
||||
@@ -42,27 +93,7 @@ public class LogBufferSerializer {
|
||||
);
|
||||
}
|
||||
|
||||
private int writeLabels(int cursor, Map<String, String> labels) {
|
||||
for (Map.Entry<String, String> entry : labels.entrySet()) {
|
||||
cursor = writeLabel(
|
||||
cursor,
|
||||
entry.getKey(),
|
||||
entry.getValue()
|
||||
);
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
|
||||
private int writeHeader(int cursor, long timestamp, Map<String, String> labels) {
|
||||
buffer.putLong(cursor, timestamp);
|
||||
cursor += Long.BYTES;
|
||||
|
||||
buffer.putInt(cursor, labels.size() + 1);
|
||||
cursor += Integer.BYTES;
|
||||
return cursor;
|
||||
}
|
||||
|
||||
public int writeLabel(
|
||||
private int writeLabel(
|
||||
int cursor,
|
||||
String key,
|
||||
String value
|
||||
@@ -73,32 +104,42 @@ public class LogBufferSerializer {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
private int writeOptionalLabel(
|
||||
int cursor,
|
||||
String key,
|
||||
String value
|
||||
) {
|
||||
if (key != null) {
|
||||
cursor += buffer.putStringAscii(cursor, key);
|
||||
cursor += buffer.putStringAscii(cursor, value);
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
private int calculateRequiredSizeAscii(Map<String, String> labels) {
|
||||
int timestampSize = Long.BYTES;
|
||||
int labelsCountSize = Integer.BYTES;
|
||||
int sum = timestampSize + labelsCountSize;
|
||||
|
||||
for (Map.Entry<String, String> entry : labels.entrySet()) {
|
||||
sum += calculateLabeSizeAscii(entry.getKey(), entry.getValue());
|
||||
sum += calculateLabelSizeAscii(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
private int calculateLabeSizeAscii(String key, String value) {
|
||||
private int calculateOptionalLabelSizeAscii(String key, String value) {
|
||||
if (key == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Integer.BYTES + key.length()
|
||||
+ Integer.BYTES + value.length();
|
||||
}
|
||||
|
||||
public int calculateRequiredSizeAscii(
|
||||
Map<String, String> labels,
|
||||
String logLevelLabel,
|
||||
String logLevel,
|
||||
ByteBuffer line
|
||||
) {
|
||||
int lineSize = Integer.BYTES + line.remaining();
|
||||
int logLevelSize = calculateLabeSizeAscii(logLevelLabel, logLevel);
|
||||
|
||||
return calculateRequiredSizeAscii(labels) + lineSize + logLevelSize;
|
||||
private int calculateLabelSizeAscii(String key, String value) {
|
||||
return Integer.BYTES + key.length()
|
||||
+ Integer.BYTES + value.length();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package pl.tkowalcz.tjahzi;
|
||||
|
||||
import org.agrona.concurrent.UnsafeBuffer;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class LogBufferSerializerTest {
|
||||
|
||||
private static Stream<Arguments> variousMessageConfigurations() {
|
||||
return Stream.of(
|
||||
Arguments.of(
|
||||
"Message with all fields filled",
|
||||
Map.of("ip", "10.0.0.42",
|
||||
"hostname", "razor-crest",
|
||||
"region", "outer-rim"
|
||||
),
|
||||
"log_level",
|
||||
"WARN",
|
||||
ByteBuffer.wrap("[Mando] You have something I want.".getBytes()),
|
||||
38 // log line
|
||||
+ 21 // log level
|
||||
+ 45 // labels string sizes
|
||||
+ 6 * 4 // labels string length indicators
|
||||
+ 8 // timestamp
|
||||
+ 4 // labels count
|
||||
),
|
||||
Arguments.of(
|
||||
"Message with empty labels",
|
||||
Map.of(),
|
||||
"log_level",
|
||||
"WARN",
|
||||
ByteBuffer.wrap("[Mando] You have something I want.".getBytes()),
|
||||
38 // log line
|
||||
+ 21 // log level
|
||||
+ 8 // timestamp
|
||||
+ 4 // labels count
|
||||
),
|
||||
Arguments.of(
|
||||
"Message with null log level",
|
||||
Map.of("ip", "10.0.0.42",
|
||||
"hostname", "razor-crest",
|
||||
"region", "outer-rim"
|
||||
),
|
||||
null,
|
||||
null,
|
||||
ByteBuffer.wrap("[Mando] You have something I want.".getBytes()),
|
||||
38 // log line
|
||||
+ 45 // labels string sizes
|
||||
+ 6 * 4 // labels string length indicators
|
||||
+ 8 // timestamp
|
||||
+ 4 // labels count
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "{0}")
|
||||
@MethodSource("variousMessageConfigurations")
|
||||
void shouldCalculateSizeOfMessage(
|
||||
String testName,
|
||||
Map<String, String> labels,
|
||||
String logLevelLabel,
|
||||
String logLevel,
|
||||
ByteBuffer logLine,
|
||||
int expectedSize) {
|
||||
// Given
|
||||
UnsafeBuffer buffer = new UnsafeBuffer(new byte[expectedSize]);
|
||||
LogBufferSerializer serializer = new LogBufferSerializer(buffer);
|
||||
|
||||
// When
|
||||
int actual = serializer.calculateRequiredSizeAscii(
|
||||
labels,
|
||||
logLevelLabel,
|
||||
logLevel,
|
||||
logLine
|
||||
);
|
||||
|
||||
// Then
|
||||
assertThat(actual).isEqualTo(expectedSize);
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "{0}")
|
||||
@MethodSource("variousMessageConfigurations")
|
||||
void shouldSerializeMessage(
|
||||
String testName,
|
||||
Map<String, String> labels,
|
||||
String logLevelLabel,
|
||||
String logLevel,
|
||||
ByteBuffer logLine,
|
||||
int expectedSize) {
|
||||
// Given
|
||||
UnsafeBuffer buffer = new UnsafeBuffer(new byte[expectedSize]);
|
||||
LogBufferSerializer serializer = new LogBufferSerializer(buffer);
|
||||
|
||||
// When
|
||||
serializer.writeTo(
|
||||
0,
|
||||
42L,
|
||||
labels,
|
||||
logLevelLabel,
|
||||
logLevel,
|
||||
logLine
|
||||
);
|
||||
|
||||
// Then
|
||||
// There was no buffer overflow so seems legit.
|
||||
// TODO: verify contents after extracting deserialization code to separate class.
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user