Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[epilogue] Fix lazy logging of mutable arrays #7665

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public void log(String identifier, byte[] value) {
return;
}

m_previousValues.put(identifier, value);
m_previousValues.put(identifier, value.clone());
m_backend.log(identifier, value);
}

Expand All @@ -130,7 +130,7 @@ public void log(String identifier, int[] value) {
return;
}

m_previousValues.put(identifier, value);
m_previousValues.put(identifier, value.clone());
m_backend.log(identifier, value);
}

Expand All @@ -143,7 +143,7 @@ public void log(String identifier, long[] value) {
return;
}

m_previousValues.put(identifier, value);
m_previousValues.put(identifier, value.clone());
m_backend.log(identifier, value);
}

Expand All @@ -156,7 +156,7 @@ public void log(String identifier, float[] value) {
return;
}

m_previousValues.put(identifier, value);
m_previousValues.put(identifier, value.clone());
m_backend.log(identifier, value);
}

Expand All @@ -169,7 +169,7 @@ public void log(String identifier, double[] value) {
return;
}

m_previousValues.put(identifier, value);
m_previousValues.put(identifier, value.clone());
m_backend.log(identifier, value);
}

Expand All @@ -182,7 +182,7 @@ public void log(String identifier, boolean[] value) {
return;
}

m_previousValues.put(identifier, value);
m_previousValues.put(identifier, value.clone());
m_backend.log(identifier, value);
}

Expand All @@ -208,7 +208,7 @@ public void log(String identifier, String[] value) {
return;
}

m_previousValues.put(identifier, value);
m_previousValues.put(identifier, value.clone());
m_backend.log(identifier, value);
}

Expand All @@ -234,7 +234,7 @@ public <S> void log(String identifier, S[] value, Struct<S> struct) {
return;
}

m_previousValues.put(identifier, value);
m_previousValues.put(identifier, value.clone());
m_backend.log(identifier, value, struct);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

package edu.wpi.first.epilogue.logging;

import edu.wpi.first.util.struct.Struct;
import edu.wpi.first.util.struct.StructSerializable;
import java.nio.ByteBuffer;

public record CustomStruct(int x) implements StructSerializable {
public static final Serializer struct = new Serializer();

public static final class Serializer implements Struct<CustomStruct> {
@Override
public Class<CustomStruct> getTypeClass() {
return CustomStruct.class;
}

@Override
public String getTypeName() {
return "CustomStruct";
}

@Override
public int getSize() {
return kSizeInt32;
}

@Override
public String getSchema() {
return "int32 x;";
}

@Override
public CustomStruct unpack(ByteBuffer bb) {
return new CustomStruct(bb.getInt());
}

@Override
public void pack(ByteBuffer bb, CustomStruct value) {
bb.putInt(value.x);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

package edu.wpi.first.epilogue.logging;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;

Expand Down Expand Up @@ -53,4 +54,135 @@ void lazyInt() {
backend.getEntries());
}
}

@Test
void inPlaceByteArray() {
var backend = new TestBackend();
var lazy = new LazyBackend(backend);

byte[] arr = new byte[] {0};
lazy.log("arr", arr);

arr[0] = 1;
lazy.log("arr", arr);

assertEquals(2, backend.getEntries().size());
assertArrayEquals(new byte[] {0}, (byte[]) backend.getEntries().get(0).value());
assertArrayEquals(new byte[] {1}, (byte[]) backend.getEntries().get(1).value());
}

@Test
void inPlaceIntArray() {
var backend = new TestBackend();
var lazy = new LazyBackend(backend);

int[] arr = new int[] {0};
lazy.log("arr", arr);

arr[0] = 1;
lazy.log("arr", arr);

assertEquals(2, backend.getEntries().size());
assertArrayEquals(new int[] {0}, (int[]) backend.getEntries().get(0).value());
assertArrayEquals(new int[] {1}, (int[]) backend.getEntries().get(1).value());
}

@Test
void inPlaceLongArray() {
var backend = new TestBackend();
var lazy = new LazyBackend(backend);

long[] arr = new long[] {0};
lazy.log("arr", arr);

arr[0] = 1;
lazy.log("arr", arr);

assertEquals(2, backend.getEntries().size());
assertArrayEquals(new long[] {0}, (long[]) backend.getEntries().get(0).value());
assertArrayEquals(new long[] {1}, (long[]) backend.getEntries().get(1).value());
}

@Test
void inPlaceFloatArray() {
var backend = new TestBackend();
var lazy = new LazyBackend(backend);

float[] arr = new float[] {0};
lazy.log("arr", arr);

arr[0] = 1;
lazy.log("arr", arr);

assertEquals(2, backend.getEntries().size());
assertArrayEquals(new float[] {0}, (float[]) backend.getEntries().get(0).value());
assertArrayEquals(new float[] {1}, (float[]) backend.getEntries().get(1).value());
}

@Test
void inPlaceDoubleArray() {
var backend = new TestBackend();
var lazy = new LazyBackend(backend);

double[] arr = new double[] {0};
lazy.log("arr", arr);

arr[0] = 1;
lazy.log("arr", arr);

assertEquals(2, backend.getEntries().size());
assertArrayEquals(new double[] {0}, (double[]) backend.getEntries().get(0).value());
assertArrayEquals(new double[] {1}, (double[]) backend.getEntries().get(1).value());
}

@Test
void inPlaceBooleanArray() {
var backend = new TestBackend();
var lazy = new LazyBackend(backend);

boolean[] arr = new boolean[] {false};
lazy.log("arr", arr);

arr[0] = true;
lazy.log("arr", arr);

assertEquals(2, backend.getEntries().size());
assertArrayEquals(new boolean[] {false}, (boolean[]) backend.getEntries().get(0).value());
assertArrayEquals(new boolean[] {true}, (boolean[]) backend.getEntries().get(1).value());
}

@Test
void inPlaceStringArray() {
var backend = new TestBackend();
var lazy = new LazyBackend(backend);

String[] arr = new String[] {"0"};
lazy.log("arr", arr);

arr[0] = "1";
lazy.log("arr", arr);

assertEquals(2, backend.getEntries().size());
assertArrayEquals(new String[] {"0"}, (String[]) backend.getEntries().get(0).value());
assertArrayEquals(new String[] {"1"}, (String[]) backend.getEntries().get(1).value());
}

@Test
void inPlaceStructArray() {
var backend = new TestBackend();
var lazy = new LazyBackend(backend);

CustomStruct[] arr = new CustomStruct[] {new CustomStruct(0)};

lazy.log("arr", arr, CustomStruct.struct);

arr[0] = new CustomStruct(1);
lazy.log("arr", arr, CustomStruct.struct);

assertEquals(2, backend.getEntries().size());
assertArrayEquals(
new byte[] {0x00, 0x00, 0x00, 0x00}, (byte[]) backend.getEntries().get(0).value());
assertArrayEquals(
new byte[] {0x01, 0x00, 0x00, 0x00}, (byte[]) backend.getEntries().get(1).value());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,32 +55,32 @@ public void log(String identifier, boolean value) {

@Override
public void log(String identifier, byte[] value) {
m_entries.add(new LogEntry<>(identifier, value));
m_entries.add(new LogEntry<>(identifier, value.clone()));
}

@Override
public void log(String identifier, int[] value) {
m_entries.add(new LogEntry<>(identifier, value));
m_entries.add(new LogEntry<>(identifier, value.clone()));
}

@Override
public void log(String identifier, long[] value) {
m_entries.add(new LogEntry<>(identifier, value));
m_entries.add(new LogEntry<>(identifier, value.clone()));
}

@Override
public void log(String identifier, float[] value) {
m_entries.add(new LogEntry<>(identifier, value));
m_entries.add(new LogEntry<>(identifier, value.clone()));
}

@Override
public void log(String identifier, double[] value) {
m_entries.add(new LogEntry<>(identifier, value));
m_entries.add(new LogEntry<>(identifier, value.clone()));
}

@Override
public void log(String identifier, boolean[] value) {
m_entries.add(new LogEntry<>(identifier, value));
m_entries.add(new LogEntry<>(identifier, value.clone()));
}

@Override
Expand All @@ -90,19 +90,27 @@ public void log(String identifier, String value) {

@Override
public void log(String identifier, String[] value) {
m_entries.add(new LogEntry<>(identifier, value));
m_entries.add(new LogEntry<>(identifier, value.clone()));
}

@Override
public <S> void log(String identifier, S value, Struct<S> struct) {
var serialized = StructBuffer.create(struct).write(value).array();
var buffer = StructBuffer.create(struct).write(value).position(0);
var serialized = new byte[buffer.capacity()];
for (int i = 0; i < buffer.capacity(); i++) {
serialized[i] = buffer.get();
}

m_entries.add(new LogEntry<>(identifier, serialized));
}

@Override
public <S> void log(String identifier, S[] value, Struct<S> struct) {
var serialized = StructBuffer.create(struct).writeArray(value).array();
var buffer = StructBuffer.create(struct).writeArray(value).position(0);
var serialized = new byte[buffer.capacity()];
for (int i = 0; i < buffer.capacity(); i++) {
serialized[i] = buffer.get();
}

m_entries.add(new LogEntry<>(identifier, serialized));
}
Expand Down
Loading