2017-01-11 2 views
0

Byteableのキーと値クラスを使用してChronicleMap 3.12を使用する方法を学習しています。コールスタックに基づいたChronicleMap.putオペレーションのループでコードを実行すると、ChronicleMap.putが呼び出されるたびに値オブジェクトが作成されるようです。 Byteable値クラスを使用すると、オブジェクトの作成が妨げられていると思います。誰かが私が潜在的に間違って何かをしたかどうか教えてもらえますか?ChronicleMap.putを使用しているときに、バイト可能なデータの新しいインスタンスを作成しないようにする方法

コードChronicleMap(TestDataKeyForChronicleMapとTestDataForChronicleMap両方がByteableある)を作成するために:私はChronicleMap.put

at sun.reflect.GeneratedConstructorAccessor1.newInstance(Unknown Source) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) 
    at net.openhft.chronicle.core.util.ObjectUtils.lambda$null$0(ObjectUtils.java:71) 
    at net.openhft.chronicle.core.util.ThrowingSupplier.lambda$asSupplier$0(ThrowingSupplier.java:42) 
    at net.openhft.chronicle.core.util.ObjectUtils.newInstance(ObjectUtils.java:297) 
    at net.openhft.chronicle.hash.serialization.impl.InstanceCreatingMarshaller.createInstance(InstanceCreatingMarshaller.java:67) 
    at net.openhft.chronicle.hash.serialization.impl.ByteableSizedReader.read(ByteableSizedReader.java:42) 
    at net.openhft.chronicle.hash.serialization.impl.ByteableSizedReader.read(ByteableSizedReader.java:31) 
    at net.openhft.chronicle.map.impl.CompiledMapQueryContext$EntryValueBytesData.innerGetUsing(CompiledMapQueryContext.java:585) 
    at net.openhft.chronicle.map.impl.CompiledMapQueryContext$EntryValueBytesData.getUsing(CompiledMapQueryContext.java:595) 
    at net.openhft.chronicle.map.impl.CompiledMapQueryContext$DefaultReturnValue.initDefaultReturnedValue(CompiledMapQueryContext.java:411) 
    at net.openhft.chronicle.map.impl.CompiledMapQueryContext$DefaultReturnValue.returnValue(CompiledMapQueryContext.java:400) 
    at net.openhft.chronicle.map.MapMethods.put(MapMethods.java:86) 
    at net.openhft.chronicle.map.VanillaChronicleMap.put(VanillaChronicleMap.java:716) 

を実行していたときにコールスタック感謝を

map = ChronicleMap.of(TestDataKeyForChronicleMap.class, TestDataForChronicleMap.class) 
      .name("TestDataMapForChronicleMap") 
      .entries(aMaxNoOfRecords). 
      .create(); 

を。 TestDataMap

ため

/** 
* test add 
* @param aMap map to be used 
* @param aNoOfData no of data to be used for testing 
* @return time taken in ms 
*/ 
public final static long TestAdd(final TestDataMap aMap, final long aNoOfData) 
{ 
    long time = System.currentTimeMillis(); 
    TestData data = aMap.createTestData(); 
    for(long count=0; count<aNoOfData; count++) 
    { 
     data.setData(count, count+aNoOfData); 
     aMap.put(data); 
    } 
    return System.currentTimeMillis() - time; 
} 

インタフェース:TestDataForChronicleMapため

import java.nio.BufferOverflowException; 
import java.nio.BufferUnderflowException; 

import net.openhft.chronicle.bytes.Byteable; 
import net.openhft.chronicle.bytes.BytesStore; 

public class TestDataKeyForChronicleMap implements Byteable 
{ 
    private final static long MAX_SIZE = 16; 
    private BytesStore bytesStore; 
    private long offset; 

    @Override 
    public BytesStore bytesStore() 
    { 
     return bytesStore; 
    } 

    @Override 
    public void bytesStore(BytesStore aBytesStore, long anOffset, long aSize) 
      throws IllegalStateException, IllegalArgumentException, 
      BufferOverflowException, BufferUnderflowException 
    { 
     if (aSize != MAX_SIZE) 
     { 
      throw new IllegalArgumentException(); 
     } 
     bytesStore = aBytesStore; 
     offset = anOffset; 
    } 

    @Override 
    public long maxSize() 
    { 
     return MAX_SIZE; 
    } 

    @Override 
    public long offset() 
    { 
     return offset; 
    } 

    /** 
    * set key 
    * @param aKey1 key 1 
    * @param aKey2 key 2 
    */ 
    public void setKey(long aKey1, long aKey2) 
    { 
     bytesStore.writeLong(offset, aKey1); 
     bytesStore.writeLong(offset + 8, aKey2); 
    } 

    /** 
    * get key 1 
    * @return key 1 
    */ 
    public long getKey1() 
    { 
     return bytesStore.readLong(offset); 
    } 

    /** 
    * get key 2 
    * @return key 2 
    */ 
    public long getKey2() 
    { 
     return bytesStore.readLong(offset + 8); 
    } 
} 

コード:プットループの

import java.nio.BufferOverflowException; 
import java.nio.BufferUnderflowException; 

import net.openhft.chronicle.bytes.Byteable; 
import net.openhft.chronicle.bytes.BytesStore; 

public final class TestDataForChronicleMap implements TestData, Byteable 
{ 
    private final static long MAX_SIZE = 48; 
    private BytesStore bytesStore; 
    private long offset; 

    public TestDataForChronicleMap() 
    { 
     Thread.currentThread().dumpStack(); 
    } 

    @Override 
    public BytesStore bytesStore() 
    { 
     return bytesStore; 
    } 

    @Override 
    public void bytesStore(BytesStore aBytesStore, long anOffset, long aSize) 
      throws IllegalStateException, IllegalArgumentException, 
      BufferOverflowException, BufferUnderflowException 
    { 
     if (aSize != MAX_SIZE) 
     { 
      throw new IllegalArgumentException(); 
     } 
     bytesStore = aBytesStore; 
     offset = anOffset; 
    } 

    @Override 
    public long maxSize() 
    { 
     return MAX_SIZE; 
    } 

    @Override 
    public long offset() 
    { 
     return offset; 
    } 

    @Override 
    public void setKey(long aKey1, long aKey2) 
    { 
     bytesStore.writeLong(offset+0, aKey1); 
     bytesStore.writeLong(offset+8, aKey2); 
     bytesStore.writeLong(offset+16, -1L); 
     bytesStore.writeLong(offset+24, -1L); 
     bytesStore.writeLong(offset+32, -1L); 
     bytesStore.writeLong(offset+40, -1L); 
    } 

    @Override 
    public void setData(long aKey1, long aKey2) 
    { 
     bytesStore.writeLong(offset+0, aKey1); 
     bytesStore.writeLong(offset+8, aKey2); 
     bytesStore.writeLong(offset+16, aKey1); 
     bytesStore.writeLong(offset+24, aKey2); 
     bytesStore.writeLong(offset+32, aKey2); 
     bytesStore.writeLong(offset+40, aKey1); 
    } 

    @Override 
    public boolean isCorrect() 
    { 
     return (bytesStore.readLong(offset+0) == bytesStore.readLong(offset+16) && bytesStore.readLong(offset+0) == bytesStore.readLong(offset+40)) 
       && 
       ( bytesStore.readLong(offset+8) == bytesStore.readLong(offset+24) && bytesStore.readLong(offset+8) == bytesStore.readLong(offset+32)); 
    } 

    @Override 
    public long getKey1() 
    { 
     return bytesStore.readLong(offset+0); 
    } 

    @Override 
    public long getKey2() 
    { 
     return bytesStore.readLong(offset+8); 
    } 

    @Override 
    public String getPrintableText() 
    { 
     StringBuilder builder = new StringBuilder(); 
     builder.append(bytesStore.readLong(offset+0)); 
     builder.append(' '); 
     builder.append(bytesStore.readLong(offset+8)); 
     builder.append(' '); 
     builder.append(bytesStore.readLong(offset+16)); 
     builder.append(' '); 
     builder.append(bytesStore.readLong(offset+24)); 
     builder.append(' '); 
     builder.append(bytesStore.readLong(offset+32)); 
     builder.append(' '); 
     builder.append(bytesStore.readLong(offset+40)); 
     return builder.toString(); 
    } 
} 

コード

更新TestDataKeyForChronicleMapを含むように

そしてTestDataMapForChronicleMap

import java.io.IOException; 

import net.openhft.chronicle.bytes.BytesStore; 
import net.openhft.chronicle.map.ChronicleMap; 

public final class TestDataMapForChronicleMap implements TestDataMap 
{ 
    private ChronicleMap<TestDataKeyForChronicleMap,TestDataForChronicleMap> map; 
    private TestDataKeyForChronicleMap key = new TestDataKeyForChronicleMap(); 

    public TestDataMapForChronicleMap(long aMaxNoOfRecords) throws IOException 
    { 
     map = ChronicleMap.of(TestDataKeyForChronicleMap.class, TestDataForChronicleMap.class) 
       .name("TestDataMapForChronicleMap") 
       .entries(aMaxNoOfRecords) 
       .putReturnsNull(true) 
       .create(); 
     BytesStore bytesStore = BytesStore.wrap(new byte[16]); 
     key.bytesStore(bytesStore, 0, bytesStore.capacity()); 
    } 

    /** 
    * put test data into the map 
    * @param aData 
    */ 
    public void put(final TestData aData) 
    { 
     key.setKey(aData.getKey1(), aData.getKey2()); 
     map.put(key, (TestDataForChronicleMap)aData); 
    } 

    /** 
    * get test data from the map 
    */ 
    public TestData get(final TestData aData) 
    { 
     key.setKey(aData.getKey1(), aData.getKey2()); 
     return map.getUsing(key, (TestDataForChronicleMap)aData); 
    } 



/** 
    * remove the test data from the map 
    */ 
    public boolean remove(final TestData aData) 
    { 
     key.setKey(aData.getKey1(), aData.getKey2()); 
     return map.remove(key) != null; 
    } 

    /** 
    * get if the map contains the test data 
    */ 
    public boolean contains(final TestData aData) 
    { 
     key.setKey(aData.getKey1(), aData.getKey2()); 
     return map.containsKey(key); 
    } 

    /** 
    * dispose the map and releases all the resources 
    * @param shouldRemoveFiles true will remove all the existing memory mapped files from the system 
    */ 
    public void dispose(final boolean shouldRemoveFiles) 
    { 
     map.close(); 
    } 

    /** 
    * get size 
    * @return size of the map 
    */ 
    public long getSize() 
    { 
     return map.size(); 
    } 

    /** 
    * clear all the values from the map 
    */ 
    public void clear() 
    { 
     map.clear(); 
    } 

    @Override 
    public boolean getZeroCopy(final TestData aData) 
    { 
     key.setKey(aData.getKey1(), aData.getKey2()); 
     return map.getUsing(key, (TestDataForChronicleMap)aData) != null; 
    } 

    @Override 
    public TestData createTestData() 
    { 
     TestDataForChronicleMap data = new TestDataForChronicleMap(); 
     BytesStore bytesStore = BytesStore.wrap(new byte[48]); 
     data.bytesStore(bytesStore, 0, bytesStore.capacity()); 
     return data; 
    } 

    @Override 
    public TestData createTestDataForZeroCopy() 
    { 
     //return createTestData(); 
     return null; 
    } 

    @Override 
    public boolean needNewData() 
    { 
     return false; 
    } 

    @Override 
    public void dispose() 
    { 
     map.close(); 
    } 

    /** 
    * get heap memory 
    */ 
    public long getOffHeapMemory() 
    { 
     return map.offHeapMemoryUsed(); 
    } 
} 

TESTDATAコード

/** 
* TestData has the following layout 
* long key1 
* long key2 
* long value1 (value = key1) 
* long value2 (value = key2) 
* long value3 (value = key2) 
* long value4 (value = key1) 
*/ 
public interface TestData 
{ 
    /** 
    * set key 
    * @param aKey1 key 1 
    * @param aKey2 key 2 
    */ 
    public void setKey(long aKey1, long aKey2); 

    /** 
    * set data 
    * @param aKey1 key 1 
    * @param aKey2 key 2 
    */ 
    public void setData(long aKey1, long aKey2); 

    /** 
    * check if the data is correct 
    */ 
    public boolean isCorrect(); 

    /** 
    * get key 1 
    * @return key 1 
    */ 
    public long getKey1(); 

    /** 
    * get key 2 
    * @return key 2 
    */ 
    public long getKey2(); 

    /** 
    * to string 
    */ 
    public String getPrintableText(); 
} 

答えて

0

どうやらあなたは、ループ内の同じキーに対して、または反復キーの値を入れます。各Map.put()では、Map契約に従って前の値が返されます(オブジェクトが作成されるはずです)。

これを避ける最も簡単な方法は、putReturnsNull(true)をChronicleMap設定に追加することですが、ChronicleMapMapに違反します。キーの値については

static <K, V> void justPut(ChronicleMap<K, V> map, K key, V value) { 
    try (ExternalMapQueryContext<K, V, ?> c = map.queryContext(key)) { 
     c.updateLock().lock(); 
     MapEntry<K, V> entry = c.entry(); 
     if (entry != null) { 
      c.replaceValue(entry, value); 
     } else { 
      c.insert(c.absentEntry(), value); 
     } 
    } 
} 
+0

は、ループ内で異なっているが、キーのインスタンスは同じですが、私は唯一のByteableを実装することを多分事実が、しませんでした:

もう一つの方法は、コンテキストを使用することですByteableコンテンツを使用して比較する対応するequalsメソッドを提供します。私はputから戻り値を必要としないので、putReturnsNull(true)を使用します。ありがとう。 –

+0

これは奇妙です。 TestDataKeyForChronicleMapのソース全体とput()でループを公開できますか? – leventov

+0

putとhashCodeはputReturnsNull(true)を使用して状況を助けるようには見えません。私はマップ契約を満たすためにChronicleMapが呼び出されるたびにデータの新しいインスタンスを作成しなければならないと仮定します。 TestDataKeyForChronicleMapのソースコードと、 –

関連する問題