2012-04-16 102 views
-1

我正在使用LongIntParallelHashMultimap java代碼,我得到了我以前的問題的答案here。我將地圖保存在磁盤中並將其加載到內存中。但是,在將內存加載到內存中後,當我執行get方法時,代碼會停止它的執行並進入永無止境的循環。有人能幫助我,爲什麼會發生這種情況,以及如何解決這個問題?任何提示都會對我有所幫助。Java代碼問題

我的代碼可以發現here並在下面給出:

import java.io.*; 
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.Arrays; 
import java.util.Random; 
import java.nio.*; 
import java.nio.channels.FileChannel; 
import java.io.RandomAccessFile ; 


public class Test{ 
public static void main(String args[]){ 

LongIntParallelHashMultimap abc = new LongIntParallelHashMultimap(10, "a.txt","b.txt"); 
Random randomGenerator = new Random(); 


for(int i = 1 ; i < 5 ; i++){ 
long b = (long) Math.floor(i/2) + 1 ; 
int c = randomGenerator.nextInt(); 
abc.put(b,c) ; 
} 

int[]tt = abc.get(1); 
System.out.println(tt[0]); 
abc.save(); 

abc.load(); 

int[]tt1 = abc.get(1); 
System.out.println(tt1[0]); 

} 
} 

class LongIntParallelHashMultimap { 

private static final long NULL = -1L ; 

private final long[] keys; 
private final int[] values; 
private int size; 
private int savenum = 0; 
private String str1 = ""; 
private String str2 = ""; 

public LongIntParallelHashMultimap(int capacity, String st1, String st2) { 
    keys = new long[capacity]; 
    values = new int[capacity]; 
    Arrays.fill(keys, NULL); 
    savenum = capacity ; 
    str1 = st1; 
    str2 = st2; 
} 

public void load(){ 
try{ 
FileChannel channel2 = new RandomAccessFile(str1, "r").getChannel(); 
MappedByteBuffer mbb2 = channel2.map(FileChannel.MapMode.READ_ONLY, 0,  channel2.size()); 
mbb2.order(ByteOrder.nativeOrder()); 
    assert mbb2.remaining() == savenum * 8; 
for (int i = 0; i < savenum; i++) { 
long l = mbb2.getLong(); 
keys[i] = l ; 
} 
channel2.close(); 

FileChannel channel3 = new RandomAccessFile(str2, "r").getChannel(); 
MappedByteBuffer mbb3 = channel3.map(FileChannel.MapMode.READ_ONLY, 0, channel3.size()); 
mbb3.order(ByteOrder.nativeOrder()); 
assert mbb3.remaining() == savenum * 8; 
for (int i = 0; i < savenum; i++) { 
long l = mbb3.getLong(); 
keys[i] = l ; 
} 
channel3.close(); 
} 

catch(Exception e){ 
     System.out.println(e) ; 
    } 
} 

public void put(long key, int value) { 
    int index = indexFor(key); 
    while (keys[index] != NULL) { 
     index = successor(index); 
    } 
    keys[index] = key; 
    values[index] = value; 
    ++size; 
} 

public int[] get(long key) { 
    int index = indexFor(key); 
    int count = countHits(key, index); 
    int[] hits = new int[count]; 
    int hitIndex = 0; 

    while (keys[index] != NULL) { 
     if (keys[index] == key) { 
      hits[hitIndex] = values[index]; 
      ++hitIndex; 
     } 
     index = successor(index); 
    } 

    return hits; 
} 

private int countHits(long key, int index) { 
    int numHits = 0; 
    while (keys[index] != NULL) { 
     if (keys[index] == key) ++numHits; 
     index = successor(index); 
    } 
    return numHits; 
} 

private int indexFor(long key) { 
return Math.abs((int) ((key * 5700357409661598721L) % keys.length)); 
} 

private int successor(int index) { 
    return (index + 1) % keys.length; 
} 

public int size() { 
    return size; 
} 

    public void save() { 
    try { 
     long l = 0 ; 
FileChannel channel = new RandomAccessFile(str1, "rw").getChannel(); 
MappedByteBuffer mbb = channel.map(FileChannel.MapMode.READ_WRITE, 0, savenum * 8); 
mbb.order(ByteOrder.nativeOrder()); 

for(int i = 0 ; i < savenum ; i++){ 
l = keys[i] ; 
    mbb.putLong(l); 
} 
channel.close(); 

FileChannel channel1 = new RandomAccessFile(str2, "rw").getChannel(); 
MappedByteBuffer mbb1 = channel1.map(FileChannel.MapMode.READ_WRITE, 0, savenum * 8); 
mbb1.order(ByteOrder.nativeOrder()); 

for(int i = 0 ; i < savenum ; i++){ 
l = values[i] ; 
mbb1.putLong(l); 
} 
channel1.close(); 
    } 
catch (Exception e){ 
    System.out.println("IOException : " + e); 
     } 
    } 
} 
+0

你有調試嗎?代碼的哪部分會導致無限循環? – talnicolas 2012-04-16 13:39:36

+0

@talnicolas,呀。 countHits方法部分。 – Arpssss 2012-04-16 13:40:35

+2

不,真的!你不想讓你的代碼格式化一點嗎? – 2012-04-16 13:41:55

回答

2

通過與我的調試器的代碼Steping我可以看到你的負載()設置keys[]的兩倍時,你應該設置keys[]values[](複製和粘貼錯誤)

當我改變第二次加載測試似乎運行良好。


如果您要訪問的鍵和值,而不創建副本,你可以用

private final LongBuffer keys; 
private final IntBuffer values; 
private int size; 
private int savenum = 0; 
private final FileChannel channel1; 
private final FileChannel channel2; 

public LongIntParallelHashMultimap(int capacity, String st1, String st2) throws IOException { 
    boolean newFile = !new File(st1).exists(); 

    channel1 = new RandomAccessFile(st1, "rw").getChannel(); 
    MappedByteBuffer mbb1 = channel1.map(FileChannel.MapMode.READ_WRITE, 0, capacity * 8); 
    mbb1.order(ByteOrder.nativeOrder()); 

    keys = mbb1.asLongBuffer(); 

    channel2 = new RandomAccessFile(st2, "rw").getChannel(); 
    MappedByteBuffer mbb2 = channel2.map(FileChannel.MapMode.READ_WRITE, 0, capacity * 4); 
    mbb2.order(ByteOrder.nativeOrder()); 

    values = mbb2.asIntBuffer(); 

    if (newFile) 
     for(int i=0;i<capacity;i++) 
      keys.put(i, NULL); 

    savenum = capacity; 
} 

public void close() throws IOException { 
    channel1.close(); 
    channel2.close(); 
} 
+0

請問您可以上傳修改後的代碼嗎? – Arpssss 2012-04-16 13:58:26

+0

我已經添加了一個例子開始。 – 2012-04-16 14:02:16

+1

再次感謝:)。 – Arpssss 2012-04-16 14:28:33