Tuesday, December 10, 2013

Converting String to Integer without using a built in method

Converting String to Integer without using a built in method




public class TestStringtoInt {


public static void main(String []args){

String s="-s234.23";
char[]a=s.toCharArray();
int sum=0;
for(int i=0;i<a.length;i++){
int number=a[i]-'0';
sum=sum*10+number;
System.out.println(sum);

}


}



}

Object cloning Example in Java: create a list from existing list and have the new list modified for a single attribute.

Use case

You have a Book Class with several attributes, and you have to create a list from existing list and have the new list modified for a single attribute.



public class Book implements Cloneable{

private String bookName;
private String bookAuthor;
private String bookId;
public Book(String bookAuthor,String bookName,String bookId){
this.bookAuthor=bookAuthor;
this.bookName=bookName;
this.bookId=bookId;
}
public Book(){
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getBookAuthor() {
return bookAuthor;
}
public void setBookAuthor(String bookAuthor) {
this.bookAuthor = bookAuthor;
}
public String getBookId() {
return bookId;
}
public void setBookId(String bookId) {
this.bookId = bookId;
}
protected Object clone() throws CloneNotSupportedException {

    Book clone=(Book)super.clone();
       
    return clone;

  }

}

import java.util.ArrayList;
import java.util.Iterator;


public class TestFunctionality {
/** You have a Book Class with several attributes, and you have to create a list from existing list and have the new list modified for a 
* single attribute.
*  
*  
**/
public static void main(String []arg){
ArrayList <Book>bookArrayList=new ArrayList<Book>();
ArrayList <Book>bookArrayList1=new ArrayList<Book>();
Book b1=new Book("Sachi","AA123","CoreJava");
Book b2=new Book("Sachii","AA1234","CoreJavaa");
Book b3=new Book("Sachiii","AA12345","CoreJavaaaa");
bookArrayList.add(b1);
bookArrayList.add(b2);
bookArrayList.add(b3);
Iterator<Book> bookListIterator = bookArrayList.iterator();
while (bookListIterator.hasNext()){
Book b=new Book();
try {
b=(Book) bookListIterator.next().clone();
System.out.println(b.getBookAuthor());
b.setBookAuthor("SACH");
bookArrayList1.add(b);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
int length=bookArrayList1.size();
System.out.println("Length of the new list is " + length);
Iterator<Book> bookListIterator1 = bookArrayList1.iterator();
while (bookListIterator1.hasNext()){
System.out.println(bookListIterator1.next().getBookAuthor());
}
}
}



Linked list implementation In Java

Linked list implementation In Java 

package sachi.test.datastructures;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class LinkedList<AnyType> implements Iterable<AnyType>
{
   private Node<AnyType> head;

 /**
   *  Constructs an empty list
   */
   public LinkedList()
   {
      head = null;
   }
 /**
   *  Returns true if the list is empty
   *
   */
   public boolean isEmpty()
   {
      return head == null;
   }
 /**
   *  Inserts a new node at the beginning of this list.
   *
   */
   public void addFirst(AnyType item)
   {
      head = new Node<AnyType>(item, head);
   }
 /**
   *  Returns the first element in the list.
   *
   */
   public AnyType getFirst()
   {
      if(head == null) throw new NoSuchElementException();

      return head.data;
   }
 /**
   *  Removes the first element in the list.
   *
   */
   public AnyType removeFirst()
   {
      AnyType tmp = getFirst();
      head = head.next;
      return tmp;
   }
 /**
   *  Inserts a new node to the end of this list.
   *
   */
   public void addLast(AnyType item)
   {
      if( head == null)
         addFirst(item);
      else
      {
         Node<AnyType> tmp = head;
         while(tmp.next != null) tmp = tmp.next;

         tmp.next = new Node<AnyType>(item, null);
      }
   }
 /**
   *  Returns the last element in the list.
   *
   */
   public AnyType getLast()
   {
      if(head == null) throw new NoSuchElementException();

      Node<AnyType> tmp = head;
      while(tmp.next != null) tmp = tmp.next;

      return tmp.data;
   }
 /**
   *  Removes all nodes from the list.
   *
   */
   public void clear()
   {
      head = null;
   }
 /**
   *  Returns true if this list contains the specified element.
   *
   */
   public boolean contains(AnyType x)
   {
      for(AnyType tmp : this)
         if(tmp.equals(x)) return true;

      return false;
   }
 /**
   *  Returns the data at the specified position in the list.
   *
   */
   public AnyType get(int pos)
   {
      if (head == null) throw new IndexOutOfBoundsException();

      Node<AnyType> tmp = head;
      for (int k = 0; k < pos; k++) tmp = tmp.next;

      if( tmp == null) throw new IndexOutOfBoundsException();

      return tmp.data;
   }
 /**
   *  Returns a string representation
   *
   */
   public String toString()
   {
      StringBuffer result = new StringBuffer();
      for(Object x : this)
      result.append(x + " ");

      return result.toString();
   }
 /**
   *  Inserts a new node after a node containing the key.
   *
   */
   public void insertAfter(AnyType key, AnyType toInsert)
   {
      Node<AnyType> tmp = head;

      while(tmp != null && !tmp.data.equals(key)) tmp = tmp.next;

      if(tmp != null)
         tmp.next = new Node<AnyType>(toInsert, tmp.next);
   }
 /**
   *  Inserts a new node before a node containing the key.
   *
   */
   public void insertBefore(AnyType key, AnyType toInsert)
   {
      if(head == null) return;

      if(head.data.equals(key))
      {
         addFirst(toInsert);
         return;
      }

      Node<AnyType> prev = null;
      Node<AnyType> cur = head;

      while(cur != null && !cur.data.equals(key))
      {
         prev = cur;
         cur = cur.next;
      }
      //insert between cur and prev
      if(cur != null)
         prev.next = new Node<AnyType>(toInsert, cur);
   }
 /**
   *  Removes the first occurrence of the specified element in this list.
   *
   */
   public void remove(AnyType key)
   {
      if(head == null)
         throw new RuntimeException("cannot delete");

      if( head.data.equals(key) )
      {
         head = head.next;
         return;
      }

      Node<AnyType> cur  = head;
      Node<AnyType> prev = null;

      while(cur != null && !cur.data.equals(key) )
      {
         prev = cur;
         cur = cur.next;
      }

      if(cur == null)
         throw new RuntimeException("cannot delete");

      //delete cur node
      prev.next = cur.next;
   }
 /**
   *  Returns a deep copy of the list
   *  Complexity: O(n^2)
   */
   public  LinkedList<AnyType> copy1()
   {
      LinkedList<AnyType> twin = new LinkedList<AnyType>();
      Node<AnyType> tmp = head;
      while(tmp != null)
      {
         twin.addLast( tmp.data );
         tmp = tmp.next;
      }

      return twin;
   }
 /**
   *  Returns a deep copy of the list
   *  Complexity: O(n)
   */
   public LinkedList<AnyType> copy2()
   {
      LinkedList<AnyType> twin = new LinkedList<AnyType>();
      Node<AnyType> tmp = head;
      while(tmp != null)
      {
         twin.addFirst( tmp.data );
         tmp = tmp.next;
      }

      return twin.reverse();
   }
 /**
   *  Reverses the list
   *  Complewxity: O(n)
   */
   public LinkedList<AnyType> reverse()
   {
      LinkedList<AnyType> list = new LinkedList<AnyType>();
      Node<AnyType> tmp = head;
      while(tmp != null)
      {
         list.addFirst( tmp.data );
         tmp = tmp.next;
      }
      return list;
   }
 /**
   *  Returns a deep copy of the immutable list
   *  It uses a tail reference.
   *  Complexity: O(n)
   */
   public LinkedList<AnyType> copy3()
   {
      LinkedList<AnyType> twin = new LinkedList<AnyType>();
      Node<AnyType> tmp = head;
      if(head==null) return null;
      twin.head = new Node<AnyType>(head.data, null);
      Node<AnyType> tmpTwin = twin.head;
      while(tmp.next != null)
      {
         tmp = tmp.next;
         tmpTwin.next = new Node<AnyType>(tmp.data, null);
         tmpTwin = tmpTwin.next;
      }

      return twin;
   }

 /*******************************************************
 *
 *  The Node class
 *
 ***
   *  Helper class used to implement list chain. As this is a private helper
   *  class it is acceptable to have public instance variables. Instances of
   *  this class are never made available to client code of the list.
   *
 ********************************************************/
   private static class Node<AnyType>
   {
      private AnyType data;
      private Node<AnyType> next;

      public Node(AnyType data, Node<AnyType> next)
      {
         this.data = data;
         this.next = next;
      }
   }

 /*******************************************************
 *
 *  The Iterator class
 *Iterator class for List to allow each list element to be
   *  visited in sequence. The iterator class is nested in the list class
   *  and is non-static meaning it has access to the state of the
   *  list object being iterated. The iterator is also public so iterator
   *  objects can be used by client code. As the class is nested, clients
   *  need to use the name LinkedList.Iterator to refer to the iterator
   *  class.
 ********************************************************/

   public Iterator<AnyType> iterator()
   {
      return new LinkedListIterator();
   }

   private class LinkedListIterator  implements Iterator<AnyType>
   {
      private Node<AnyType> nextNode;

      public LinkedListIterator()
      {
         nextNode = head;
      }

      public boolean hasNext()
      {
         return nextNode != null;
      }

      public AnyType next()
      {
         if (!hasNext()) throw new NoSuchElementException();
         AnyType res = nextNode.data;
         nextNode = nextNode.next;
         return res;
      }

      public void remove() { throw new UnsupportedOperationException(); }
   }



/*****   Include the main() for testing and debugging  *****/


   public static void main(String[] args)
   {
      LinkedList<String> list = new LinkedList <String>();
      list.addFirst("p");
      list.addFirst("a");
      list.addFirst("e");
      list.addFirst("h");
      System.out.println(list);
      list.insertAfter("e","f");
      System.out.println(list);

LinkedList<String> twin = list.copy3();
      System.out.println(twin);

      System.out.println(list.get(0));
// System.out.println(list.get(4));   //exception

      list.addLast("s");
      Iterator itr = list.iterator();
      while(itr.hasNext())
         System.out.print(itr.next() + " ");
      System.out.println();

      for(Object x : list)
         System.out.print(x + " ");
      System.out.println();

      list.insertAfter("e", "ee");
      System.out.println(list);
      System.out.println(list.getLast());

      list.insertBefore("h", "yy");
      System.out.println(list);

      list.remove("p");
      System.out.println(list);
}
}







Monday, December 9, 2013

Data Consistency in Cassandra

Understanding Data Consistency in Cassandra

To understand the data consistency in Cassandra we need to understand the points below.

1. Overview Cassandra reads/writes.
2. Details of how writes are performed in Cassandra.
3. The CAP theorem.
4. Tunable data consistency
5. Choosing a data consistency strategy for writes.
6. Choosing a data consistency strategy for  reads.
7. Example.


-Overview Cassandra reads/writes.

Cassandra is a peer to peer architecture , it does not have the concept of master or salve. All the nodes in cluster, may be in different rack, may be in different datacenter all are treated as the same so the data can be written to any node and can be read from any node. Cassandra automatically takes care of partitioning and replicating the data through out the cluster in any rack or any datacenter.


-Details of how writes are performed in Cassandra.

Writes in Cassandra are considered to be extremely fast in the industry today. When data is written to Cassandra the data is persisted in a commit log for durability. The same data is then moved to a in memory table called the memtable. Once the memtable is  full the data is moved to the disc called the SSTables. Writes in Cassandra are atomic at row level, all columns are written or  updated or not written at all. RDBMS style transaction are not supported. Based on a benchmark independently it has ben recorded that Cassandra has
a. 4x better writes.
b. 2x better reads.
c. 12x better in reads/updates.


-The CAP theorem

In distributed database system you can have two of three things.

-you can have strong consistency which mean reading and writing the latest copy of the data.
-you can have Strong availability of the data which means if one node goes done  which has the data you still have other nodes which has the data to server the request.
-You can loose messages between couple of the nodes but still the system operate well.

Cassandra is known for having strong availability an partition tolerance but its provides tunable data consistency


-Tunable data consistency

In Cassandra you have the flexibility to choose the data consistency, strong or eventual. The data consistency can be defined in Cassandra per operation basis.

-Data consistency strategy for writes

There are various strategy for writes.
1. Any: A write must succeed on any available node.
2. One: A write must succeed on any node responsible for that row.
3. Quorum: A write must succeed on a quorum of replica nodes which is determined by (replicationFactor/2)+1.
4. Local_Quorum: A write must succeed on a quorum of replica nodes in the same datacenter as the coordinator node.
5. Each_Quorum: A write must succeed on a quorum of replica nodes in all data centers.
6. All: A write must succeed on all replica nodes for a row key.


-Hinted Handoffs

Hinted Handoff is a methodology implemented in Cassandra when performing writes to a row for all replicas for that row. If all replica nodes are not available then a hint is stored one of the nodes to update the downed nodes with the row once the node are available. If no replica nodes are available then use of any consistency level will instruct the coordinator node to store the hint and the row data which is passed to replica node once its is available.


-Data consistency strategy for Reads

There are various strategy for reads in Cassandra
1. One: reads the closest node holding the data.
2. Quorum: Returns a result from a Quorum of servers with the most recent timestamp for the data.
3. Local_Quorum: Returns the result from a Quorum of the servers with most recent timestamp for the data in the same data center as the coordinator node.
4. Each_Quorum: Returns the result from a Quorum of servers with the most recent timestamp in all data centers.
5. All: Returns the result from all replica nodes for the key.


-Read Repair

To ensure the data consistency while reading Cassandra performs read repair. suppose i am reading a data which is stale in one of the node, Cassandra issues a repair to other node which has the data the most recent data is updated on the node which has issued the repair so the next time when request comes it will give the latest data.


USING CONSISTENCY clause can be used to provide the consistency level on the operation to be executed.


Understanding the architecture of Cassandra

Whats is Cassandra ?

Some of us know about Cassandra and some of may not know what Cassandra is ?. Well Cassandra is a high performance , fault tolerant , extremely scalable and distributed database management system. It is not relational or we can say it as a post relational database solution. It can serve as realtime data store for online / transactional application and also can be used for read intensive database for business intelligence systems.

Overview of Cassandra Architecture.

Cassandra was a thoughtful innovation keeping in mind that failure is the key to success i.e there may be hardware failure or system crashes and data is important. It is a peer to peer design database management system, there is no concept of master or slave. Being a peer to peer architecture you can read / write to any Cassandra node in a cluster, all the nodes are treated as the same. Data is partitioned throughout the nodes and it ensure the system to be fault tolerant by replication the data though custom data replication.

Each node in cassandra communicates with each other through gossip protocol, which exchanges the information across the cluster in intervals. 

When data is written to Cassandra to assure the data durability it logs all the data to a commit log. The data in the commit log is then written to a in memory data structure call the memtable. Once the memtable is full the data is written to the disk called the SSTable.

The data is contained within a schema which is based on google big table , its a row oriented column structured design. It has the concept of keyspace which is similar to that of a relational database, The column family is the core object to manage data which is again very similar to relational database management system but the scheme is more flexible and dynamic in nature. A row in a column family can be indexed by its key and also other columns can be indexed as well.


Why would you use Cassandra ??

1. Scaling to gigabyte or petabyte.
2. By adding nodes linear performance can be achieved.
3. No single point of failure.
4. Data is distributed and replication of data is easy.
5. Capability to run in multiple datacenter and cloud.
6. Specially in Cassandra there is no need of a caching layer.
7. Tunable data consistency.
8. Schema design is flexible.
9. SQL like queries.
10. Support key languages and runs on commodity hardware or software.
11. Data compression with no performance penalty.