HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Trie key/value store implementation comparing with HashMap

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
comparingwithvaluestoretrieimplementationhashmapkey

Problem

I have implemented a Trie-based concurrent key/value store using hashcode similar to HashMap.
It is something like, if your hashcode is 50 (110010) then
create a TRIE with array size of 4 (two binary bits), the first value is 10 which is 2,10- [][][X][] --> 00- [X][][][] --> 11- [][][][X] will be represented.
HERE The first array third element will point to second array; and second array first element will point to third array, finally your entry(key/value pair) will be placed in the third array fourth element. This will be a unique path to access my KeyValuePair through hashcode.

This is on the intention that this Trie won't require rehashing & Masking(shrinking hash to fit within fixed array, which is cause for collision). I am considering this as an alternative to ConcurrentHashMap in Java.

```
import java.util.concurrent.atomic.AtomicReferenceArray;

public class TrieMap {
public static int SIZEOFEDGE = 4;
public static int OSIZE = 5000;
}

abstract class Node {
public Node getLink(String key, int hash, int level){
throw new UnsupportedOperationException();
}
public Node createLink(int hash, int level, String key, String val) {
throw new UnsupportedOperationException();
}
public Node removeLink(String key, int hash, int level){
throw new UnsupportedOperationException();
}
}

class Vertex extends Node {
String key;
volatile String val;
volatile Vertex next;

public Vertex(String key, String val) {
this.key = key;
this.val = val;
}

@Override
public boolean equals(Object obj) {
Vertex v = (Vertex) obj;
return this.key.equals(v.key);
}

@Override
public int hashCode() {
return key.hashCode();
}

@Override
public String toString() {
return key +"@"+key.hashCode();
}
}

class Edge extends Node {
volatile AtomicReferenceArray array; //This is needed to ensure array elements ar

Solution

This abstract class:

abstract class Node {
    public Node getLink(String key, int hash, int level){
        throw new UnsupportedOperationException();
    }
    public Node createLink(int hash, int level, String key, String val) {
        throw new UnsupportedOperationException();
    }
    public Node removeLink(String key, int hash, int level){
        throw new UnsupportedOperationException();
    }
}


What's the point of an abstract class if it acts like an interface?

interface Node {

    public Node getLink(String key, int hash, int level);
    public Node createLink(int hash, int level, String key, String val);
    public Node removeLink(String key, int hash, int level);

}


Noting your comment:


What's the point of an abstract class if it acts like an interface? This will avoid adding UnsupportedOperationException method on each subclass which don't implements. In this case Vertex no need to implement it to say i am not supported.

Well, it is often bad practice to do what you are doing there, and that is why List, and other interfaces are interfaces. I have many List implementation that don't implement all the methods (there are at least 20), and I use UnsupportedOperationException there. If a method is unsupported, do it down the hierarchy; don't do it at the base class.

Which means instead of:

class Vertex extends Node {


and:

class Edge extends Node {


You have:

class Vertex implements Node {


and:

class Edge implements Node {


You consistently have:

} else {


and

}
  else


Choose one, and stick to it. The first option is recommended, as it follows standard Java conventions.

else if((returnVal instanceof Vertex)) {


Double parentheses are not necessary, and actually clutter code:

else if (returnVal instanceof Vertex) {


String key;
volatile String val;
volatile Vertex next;


This in its current state is bad practice. A get/set is better than default-level variables:

private String key;
private volatile String val;
private volatile Vertex next;

// ...

public String getKey() {
    return key;
}

public void setKey(String key) {
    this.key = key;
}

// same thing with other variables


Same thing here:

volatile AtomicReferenceArray array; //This is needed to ensure array elements are volatile


To:

private volatile AtomicReferenceArray array; //This is needed to ensure array elements are volatile

// ...

public AtomicReferenceArray getArray() {
    return array;
}

public void setArray(AtomicReferenceArray array) {
    this.array = array;
}


Here:

}

class Base10ToBaseX {


No need to have so much space between classes:

}

class Base10ToBaseX {

Code Snippets

abstract class Node {
    public Node getLink(String key, int hash, int level){
        throw new UnsupportedOperationException();
    }
    public Node createLink(int hash, int level, String key, String val) {
        throw new UnsupportedOperationException();
    }
    public Node removeLink(String key, int hash, int level){
        throw new UnsupportedOperationException();
    }
}
interface Node {

    public Node getLink(String key, int hash, int level);
    public Node createLink(int hash, int level, String key, String val);
    public Node removeLink(String key, int hash, int level);

}
class Vertex extends Node {
class Edge extends Node {
class Vertex implements Node {

Context

StackExchange Code Review Q#112535, answer score: 5

Revisions (0)

No revisions yet.