What data structure should I use to implement a BTree? Why?
You can create a btree node using following class.. it is having 7 keys and 8 pointers. u can change it according to the definition of btree node and perform operations on it
class BTNode
{
BTNode pointers[];
String keys[];
int numKeys;
boolean leaf;
public BTNode() // constructor to initialize values
{
leaf=true;
numKeys=0;
keys=new String[7];
pointers=new BTNode[8];
}
}
class Node {
int data;
Node left;
Node right;
}
class BNode {
Node[] nodes;
}
This way you will have pointers to every node of the BNode to point to the right and left subtree....
I implemented BTree in a few days ago with LinkedList (delete O(1), insert O(1)). I will show you my code. Here is my BNode structure:
public class BTree {
private int order;
private BNode root;
public BTree(int order) {
this.order = order;
}
public void insert(int value){}
public boolean delete(int value){}
public boolean contains(int value){}
public void print(){}
}
class BNode{
private LinkedList<Integer> values;
private LinkedList<BNode> children;
public BNode(){
init(values);
init(children); // every bnode with order k has k+1 children
}
}
Related
I have a Room database and RecyclerView that shows a list of CardViews. One of the database columns holds Sort Index values so the CardViews can easily be sorted and moved within the RecyclerView list. I have a Dao call to update the Sort Index values whenever a CardView is moved, deleted or added.
Room requires CRUD on a background thread and the syntax I have in the AsyncTask() in the respository that calls the Dao method is wrong. I am trying to pass the individual "int" sortOrders and the "int" sortIds. What am I missing here? Or would " Executor mExecutor = Executors.newSingleThreadExecutor();" be a better solution here?
MainActivity
int sortId = -1;
int sortOrder = -1;
...
mViewModel.updateSortOrder(sortOrder, sortId);
ViewModel
...
public void updateSortOrder(int sortOrder, int sortId) {
repository.updateSortOrder(sortOrder, sortId);
}
Repository
...
public void updateSortOrder(int sortOrder, int sortId) {
new UpdateSortOrderColAsyncTask(quickcardDao).execute(sortOrder, sortId);
}
**I think this is where the syntax is not correct**
private static class UpdateSortOrderColAsyncTask extends AsyncTask<Integer, Void, Void> {
private QuickcardDao asyncTaskDao;
UpdateSortOrderColAsyncTask(QuickcardDao dao) {
asyncTaskDao = dao;
}
#Override
protected Void doInBackground(final Integer... params) {
asyncTaskDao.updateSortorder(params[0]);
return null;
}
}
Dao
#Query("UPDATE cards SET cardSortorder = :sortOrder WHERE cardId = :sortId")
void updateSortorder(int sortOrder, int sortId);
How does sort happens in mapreduce before the output is passed from mapper to reducer. If my output key from mapper is of type IntWritable, does it uses the comparator defined in IntWritable class or compareTo method in the class, if yes how the call is made. If not how the sort is performed, how the call is made?
Map job outputs are first collected and then sent to the Partitioner, responsible for determining to which Reducer the data will be sent (it's not yet grouped by reduce() call though). The default Partitioner uses the hashCode() method of the Key and a modulo with the number of Reducers to do that.
After that, the Comparator will be called to perform a sort on the Map outputs. Flow looks like that:
Collector --> Partitioner --> Spill --> Comparator --> Local Disk (HDFS) <-- MapOutputServlet
Each Reducer will then copy the data from the mapper that has been assigned to it by the partitioner, and pass it through a Grouper that will determine how records are grouped for a single Reducer function call:
MapOutputServlet --> Copy to Local Disk (HDFS) --> Group --> Reduce
Before a function call, the records will also go through a Sorting phase to determine in which order they arrive to the reducer. The Sorter (WritableComparator()) will call the compareTo() (WritableComparable() interface) method of the Key.
To give you a better idea, here is how you would implement a basic compareTo(), grouper and sorter for a custom composite key:
public class CompositeKey implements WritableComparable<CompositeKey> {
IntWritable primaryField = new IntWritable();
IntWritable secondaryField = new IntWritable();
public CompositeKey(IntWritable p, IntWritable s) {
this.primaryField.set(p);
this.secondaryField = s;
}
public void write(DataOutput out) throws IOException {
this.primaryField.write(out);
this.secondaryField.write(out);
}
public void readFields(DataInput in) throws IOException {
this.primaryField.readFields(in);
this.secondaryField.readFields(in);
}
// Called by the partitionner to group map outputs to same reducer instance
// If the hash source is simple (primary type or so), a simple call to their hashCode() method is good enough
public int hashCode() {
return this.primaryField.hashCode();
}
#Override
public int compareTo(CompositeKey other) {
if (this.getPrimaryField().equals(other.getPrimaryField())) {
return this.getSecondaryField().compareTo(other.getSecondaryField());
} else {
return this.getPrimaryField().compareTo(other.getPrimaryField());
}
}
}
public class CompositeGroupingComparator extends WritableComparator {
public CompositeGroupingComparator() {
super(CompositeKey.class, true);
}
#Override
public int compare(WritableComparable a, WritableComparable b) {
CompositeKey first = (CompositeKey) a;
CompositeKey second = (CompositeKey) b;
return first.getPrimaryField().compareTo(second.getPrimaryField());
}
}
public class CompositeSortingComparator extends WritableComparator {
public CompositeSortingComparator() {
super (CompositeKey.class, true);
}
#Override
public int compare (WritableComparable a, WritableComparable b){
CompositeKey first = (CompositeKey) a;
CompositeKey second = (CompositeKey) b;
return first.compareTo(second);
}
}
After Mapper framework takes care about comparing for us for all the default datatypes like IntWritable, DoubleWritable e.t.c ... But if you have a user defined keytype you need to implement WritableComparable Interface.
WritableComparables can be compared to each other, typically via Comparators. Any type which is to be used as a key in the Hadoop Map-Reduce framework should implement this interface.
Note that hashCode() is frequently used in Hadoop to partition keys. It's important that your implementation of hashCode() returns the same result across different instances of the JVM. Note also that the default hashCode() implementation in Object does not satisfy this property.
Example:
public class MyWritableComparable implements WritableComparable {
// Some data
private int counter;
private long timestamp;
public void write(DataOutput out) throws IOException {
out.writeInt(counter);
out.writeLong(timestamp);
}
public void readFields(DataInput in) throws IOException {
counter = in.readInt();
timestamp = in.readLong();
}
public int compareTo(MyWritableComparable o) {
int thisValue = this.value;
int thatValue = o.value;
return (thisValue < thatValue ? -1 : (thisValue==thatValue ? 0 : 1));
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + counter;
result = prime * result + (int) (timestamp ^ (timestamp >>> 32));
return result
}
}
From :https://hadoop.apache.org/docs/current/api/org/apache/hadoop/io/WritableComparable.html
I need to create a pivot project considering a list of three levels:
public class Value
{
private DateTime DayMonth;
private float value;
private float variation;
[...]
}
public class Element
{
private String description;
private List<Value> values;
private List<Element> elements;
[...]
}
public class User
{
private String name;
private List<Element> elements;
[...]
}
What I need is to make pivot pages for each of the diferent Value.DayMonth of each element. So, when I visualize the data, I can see the value e variation of each element, and if I want to see these indicators for another day of the month I just go to the next page.
I have a few entity beans with sets of other entities as attributes. I want to sort them and guarantee that at every insertion they will remain sorted.
I tried this way:
#Entity
#Table(name = "Document")
public class Document implements Serializable, Comparable<Document> {
...
#ManyToOne
private Project relativeProject;
...
#Override
public int compareTo(Document d) {
long data1 = getDate().getTimeInMillis();
long data2 = d.getDate().getTimeInMillis();
if(data1 > data2)
return 1;
else
if(data2 < data1)
return -1;
else
return 0;
}
#Override
public boolean equals(Object d) {
return (getIdDocument() == ((Document)d).getIdDocument());
}
#Override
public int hashCode() {
return Long.valueOf(getIdDocument()).hashCode();
}
}
#Entity
#Table(name="Project")
public class Project implements Serializable, Comparable<Project> {
...
#OneToMany(mappedBy="relativeProject", fetch = FetchType.EAGER)
#Sort(type = SortType.NATURAL)
private SortedSet<Document> formedByDocuments;
public Progetto() {
this.formedByDocuments = new TreeSet<Document>();
}
...
}
But it does not work. The problem is that, even if in the database there are all needed entries, when a session bean returns a Project there will miss some Document. Moreover, entries are not sorted at all in the database.
If I do not sort at all (using HashSet) and republish the project, everything works fine and I get all the elements in a set (but not sorted, of course).
Can someone help me to find out what's wrong with my sorting?
I'm assuming getIdDocument() returns an object and not a primitive.
In that case, you need to use equals and not ==
public boolean equals(Object d) {
return (getIdDocument().equals((Document)d).getIdDocument());
}
Edit:
Looks like the problem is in the second if(data2 < data1) statement of the compareTo() method. This should be if(data1 < data2)
Can a single Mapper class produce multiple key-value pairs (of same type) in a single run?
We output the key-value pair in the mapper like this:
context.write(key, value);
Here's a trimmed down (and exemplified) version of the Key:
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.ObjectWritable;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
public class MyKey extends ObjectWritable implements WritableComparable<MyKey> {
public enum KeyType {
KeyType1,
KeyType2
}
private KeyType keyTupe;
private Long field1;
private Integer field2 = -1;
private String field3 = "";
public KeyType getKeyType() {
return keyTupe;
}
public void settKeyType(KeyType keyType) {
this.keyTupe = keyType;
}
public Long getField1() {
return field1;
}
public void setField1(Long field1) {
this.field1 = field1;
}
public Integer getField2() {
return field2;
}
public void setField2(Integer field2) {
this.field2 = field2;
}
public String getField3() {
return field3;
}
public void setField3(String field3) {
this.field3 = field3;
}
#Override
public void readFields(DataInput datainput) throws IOException {
keyTupe = KeyType.valueOf(datainput.readUTF());
field1 = datainput.readLong();
field2 = datainput.readInt();
field3 = datainput.readUTF();
}
#Override
public void write(DataOutput dataoutput) throws IOException {
dataoutput.writeUTF(keyTupe.toString());
dataoutput.writeLong(field1);
dataoutput.writeInt(field2);
dataoutput.writeUTF(field3);
}
#Override
public int compareTo(MyKey other) {
if (getKeyType().compareTo(other.getKeyType()) != 0) {
return getKeyType().compareTo(other.getKeyType());
} else if (getField1().compareTo(other.getField1()) != 0) {
return getField1().compareTo(other.getField1());
} else if (getField2().compareTo(other.getField2()) != 0) {
return getField2().compareTo(other.getField2());
} else if (getField3().compareTo(other.getField3()) != 0) {
return getField3().compareTo(other.getField3());
} else {
return 0;
}
}
public static class MyKeyComparator extends WritableComparator {
public MyKeyComparator() {
super(MyKey.class);
}
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return compareBytes(b1, s1, l1, b2, s2, l2);
}
}
static { // register this comparator
WritableComparator.define(MyKey.class, new MyKeyComparator());
}
}
And this is how we tried to output both keys in the Mapper:
MyKey key1 = new MyKey();
key1.settKeyType(KeyType.KeyType1);
key1.setField1(1L);
key1.setField2(23);
MyKey key2 = new MyKey();
key2.settKeyType(KeyType.KeyType2);
key2.setField1(1L);
key2.setField3("abc");
context.write(key1, value1);
context.write(key2, value2);
Our job's output format class is: org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat
I'm stating this because in other output format classes I've seen the output not appending and just committing in their implementation of write method.
Also, we are using the following classes for Mapper and Context:
org.apache.hadoop.mapreduce.Mapper
org.apache.hadoop.mapreduce.Context
Writing to the context multiple times in one map task is perfectly fine.
However, you may have several problems with your key class. Whenever you implement WritableComparable for a key, you should also implement equals(Object) and hashCode() methods. These aren't part of the WritableComparable interface, since they are defined in Object, but you must provide implementations.
The default partitioner uses the hashCode() method to decide which reducer each key/value pair goes to. If you don't provide a sane implementation, you can get strange results.
As a rule of thumb, whenever you implement hashCode() or any sort of comparison method, you should provide an equals(Object) method as well. You will have to make sure it accepts an Object as the parameter, as this is how it is defined in the Object class (whose implementation you are probably overriding).