Revision: 34d42daf2135
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 18:21:21 2012
Log: worked out why the values were wrong under the perMetricLock.
The glo...
http://code.google.com/p/parfait/source/detail?r=34d42daf2135
Revision: d1519b117488
Author: psmith <psm...@aconex.com>
Date: Tue Feb 14 14:08:28 2012
Log: One little line. ONE LITTLE LINE that cost OH SO MUCH PAIN. Of
course...
http://code.google.com/p/parfait/source/detail?r=d1519b117488
==============================================================================
Revision: 34d42daf2135
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 18:21:21 2012
Log: worked out why the values were wrong under the perMetricLock.
The global lock way uses a single ByteBuffer that is marked as volatile so
proper thread memory handling ensues. Since we have a ByteBuffer instance
per metric stored in the map, it's not subject to this, and we were
originally synchronizing on the PcpValueInfo, however just synchronizing on
the perMetric byteBuffer now ensues all memory writes happen for each
thread to see and we don't get whacky half-long updates to the counter.
http://code.google.com/p/parfait/source/detail?r=34d42daf2135
Modified:
/dxm/src/main/java/com/custardsource/parfait/dxm/BasePcpWriter.java
=======================================
--- /dxm/src/main/java/com/custardsource/parfait/dxm/BasePcpWriter.java Sat
Feb 11 04:27:55 2012
+++ /dxm/src/main/java/com/custardsource/parfait/dxm/BasePcpWriter.java Sat
Feb 11 18:21:21 2012
@@ -40,7 +40,7 @@
private final Collection<PcpString> stringInfo = new
CopyOnWriteArrayList<PcpString>();
private final ByteBufferFactory byteBufferFactory;
private final Map<PcpValueInfo,ByteBuffer> perMetricByteBuffers =
newConcurrentMap();
- private boolean usePerMetricLock = true;
+ private volatile boolean usePerMetricLock = true;
protected BasePcpWriter(File file, IdentifierSourceSet
identifierSources) {
@@ -114,8 +114,10 @@
TypeHandler<?> rawHandler = info.getTypeHandler();
int bufferPosition = rawHandler.requiresLargeStorage() ?
info.getLargeValue()
.getOffset() : info.getOffset();
+ // need to position the original buffer first, as the
sliced buffer starts from there
+ dataFileBuffer.position(bufferPosition);
ByteBuffer metricByteBufferSlice = dataFileBuffer.slice();
- metricByteBufferSlice.position(bufferPosition);
+ metricByteBufferSlice.limit(rawHandler.getDataLength());
perMetricByteBuffers.put(info, metricByteBufferSlice);
}
}
@@ -151,10 +153,9 @@
private void writeValueWithLockPerMetric(PcpValueInfo info, Object
value, TypeHandler rawHandler) {
ByteBuffer perMetricByteBuffer = perMetricByteBuffers.get(info);
- synchronized (info) {
- int originalBufferPosition = perMetricByteBuffer.position();
+ synchronized (perMetricByteBuffer) {
+ perMetricByteBuffer.position(0);
rawHandler.putBytes(perMetricByteBuffer, value);
- perMetricByteBuffer.position(originalBufferPosition);
}
}
==============================================================================
Revision: d1519b117488
Author: psmith <psm...@aconex.com>
Date: Tue Feb 14 14:08:28 2012
Log: One little line. ONE LITTLE LINE that cost OH SO MUCH PAIN. Of
course the docs mention that the sliced buffer is everything the parent
buffer is, but doesn't make mention of this little quirk, that somehow, the
byte order of the slice is different than the parent. WTF?
http://code.google.com/p/parfait/source/detail?r=d1519b117488
Modified:
/dxm/src/main/java/com/custardsource/parfait/dxm/BasePcpWriter.java
=======================================
--- /dxm/src/main/java/com/custardsource/parfait/dxm/BasePcpWriter.java Sat
Feb 11 18:21:21 2012
+++ /dxm/src/main/java/com/custardsource/parfait/dxm/BasePcpWriter.java Tue
Feb 14 14:08:28 2012
@@ -119,6 +119,7 @@
ByteBuffer metricByteBufferSlice = dataFileBuffer.slice();
metricByteBufferSlice.limit(rawHandler.getDataLength());
perMetricByteBuffers.put(info, metricByteBufferSlice);
+ metricByteBufferSlice.order(dataFileBuffer.order());
}
}