-1

I am using LongIntParallelHashMultimap java code which I got as my previous question's answer here. I save the map in the disk and load it in to memory. However, after loading the map in memory, when I execute the get method the code stops it's execution and goes into never ending loop. Can anybody help me why is this happening and how to solve this ? Any hints will be helpful for me.

My code can be found here and also given in the below:

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);
      }
    }
 }
Community
  • 1
  • 1
Arpssss
  • 3,850
  • 6
  • 36
  • 80
  • Have you debugged it? What part of the code causes the infinite loop? – talnicolas Apr 16 '12 at 13:39
  • @talnicolas, yah. countHits method part. – Arpssss Apr 16 '12 at 13:40
  • 2
    No, really! Don't you feel like formatting your code a bit? – Boris Strandjev Apr 16 '12 at 13:41
  • You stop when you get to a key which is `NULL` but you don't appear to set that value anywhere so it never stops. – Peter Lawrey Apr 16 '12 at 13:43
  • @BorisStrandjev, you mean adding comments. Or structuring it properly. – Arpssss Apr 16 '12 at 13:43
  • Have you considered using the memory mapped file in place (instead of copying them back and forth to an array) once you have this working? – Peter Lawrey Apr 16 '12 at 13:45
  • @Arpssss I mean like indenting the lines correctly at least. If you use Eclipse for development a simple Ctrl + A, Alt + Shift + F should do. So simple thing and it will make your code so much easier to understand. Btw I want to add it is not me that downvoted you. – Boris Strandjev Apr 16 '12 at 13:45
  • @PeterLawrey, I can't get it. Can you kindly illustrate it ? – Arpssss Apr 16 '12 at 13:46
  • Sorry, I missed that you are initialising the keys. – Peter Lawrey Apr 16 '12 at 13:47
  • In your get() and countHits() methods, your while loop will never end if every element of your keys array is not -1L. Have you checked all the values of your keys array AFTER to load it from disk? – GetSet Apr 16 '12 at 13:49
  • @PeterLawrey, but I have to save the Map in the disk for latter use. So, what should I do thus I have not to create Map again ? – Arpssss Apr 16 '12 at 13:51
  • @GetSet, OK. I checked it. No, not all the elements of the key array is -1L. I have to save the Map in the disk for latter use. So, what should I do thus I have not to create Map again ? I have to store only values array not keys array. Right ? – Arpssss Apr 16 '12 at 14:00

2 Answers2

2

Steping through the code with my debugger I can see that your load() sets the keys[] twice when you should be setting the keys[] and values[] (copy and paste error)

When I change the second load the test appears to run fine.


If you want to access the keys and values without creating a copy you can start with

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();
}
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

I am little bit stupid thus make such kind silly mistakes. Modified code is here:

http://textuploader.com/?p=6&id=xkAHw. Thanks.

Arpssss
  • 3,850
  • 6
  • 36
  • 80