Design LRU cache

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












Description:



Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.



More details can be found here.



Code:



import java.util.Map;
import java.util.HashMap;

class Main
private static class LRUCache
private final int capacity;
private final Map<String, Entry> map;
private int currentCount;
private Entry head;
private Entry tail;

LRUCache(int capacity)
if (capacity <= 0)
throw new IllegalArgumentException("Capacity should be greater than 0: " + capacity);

this.map = new HashMap<>();
this.capacity = capacity;


/**
* Gets the value associated with the key and
* marks the key as most recent used.
*
* @param key The cache key
*
* @return The value if present or null.
*/
public Integer get(String key)
if (map.containsKey(key))
Entry entry = map.get(key);
remove(entry);
addToFront(entry);
return entry.val;

return null;


/**
* Puts the value associated with the key and
* marks the key as most recent.
*
* @param key The cache key
* @param val The cache value
*
* @return The value if present or null.
*/
public void put(String key, int val)
if (map.containsKey(key))
Entry entry = map.get(key);
remove(entry);
addToFront(entry);
else
currentCount++;
Entry entry = new Entry(key, val);
if (currentCount > capacity)
purge();

addToFront(entry);
map.put(key, entry);



/**
* Removes the entry from the list.
*/
private void remove(Entry entry)
if (entry.prev != null)
entry.prev.next = entry.next;
else
head = entry.next;


if (entry.next != null)
entry.next.prev = entry.prev;
else
tail = entry.prev;



/**
* Removes the last entry from the list.
*/
private void purge()
if (tail == null)
return;

Entry entry = tail;
if (head == tail)
head = tail = null;
else
entry.prev.next = null;
tail = entry.prev;
tail.next = null;

map.remove(entry.key);


/**
* Adds entry to the from of the list.
*/
private void addToFront(Entry entry)
entry.next = head;
if (head != null)
head.prev = entry;

head = entry;
if (tail == null)
tail = head;



public String toString()
Entry current = head;
StringBuilder s = new StringBuilder();
while (current != null)
s.append(current + " ");
current = current.next;

return s.toString();



private static class Entry
String key;
int val;
Entry next;
Entry prev;

Entry(String key, int val)
this.key = key;
this.val = val;


public String toString()
return key + ":" + val;



public static void main(String args)
try
LRUCache cache = new LRUCache(-3);
System.out.println("Test for -ve capacity failed");
catch (IllegalArgumentException ex)
System.out.println("Test for -ve capacity passed");


LRUCache cache = new LRUCache(3);
cache.put("foo", 1);
cache.put("bar", 2);
cache.put("zar", 3);
System.out.println(cache); // => zar -> bar -> foo
cache.put("doe", 4); // => purge, i.e. remove foo
System.out.println(cache); // => doe -> zar -> bar
cache.get("bar");
System.out.println(cache); // => bar -> doe -> zar
cache.get("doe");
System.out.println(cache); // => doe -> bar -> zar

try
LRUCache c = new LRUCache(1);
c.put("a", 1);
c.put("b", 2);
c.get("a");
System.out.println("Should pass");
catch (Exception e)
e.printStackTrace(System.out);





Note:



I have used the basic data structures to get more clarity for managing pointers.



Questions:



I am more interested in OOP and creating better abstractions,
any guidance in that direction would be great.







share|improve this question



























    up vote
    0
    down vote

    favorite












    Description:



    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.



    More details can be found here.



    Code:



    import java.util.Map;
    import java.util.HashMap;

    class Main
    private static class LRUCache
    private final int capacity;
    private final Map<String, Entry> map;
    private int currentCount;
    private Entry head;
    private Entry tail;

    LRUCache(int capacity)
    if (capacity <= 0)
    throw new IllegalArgumentException("Capacity should be greater than 0: " + capacity);

    this.map = new HashMap<>();
    this.capacity = capacity;


    /**
    * Gets the value associated with the key and
    * marks the key as most recent used.
    *
    * @param key The cache key
    *
    * @return The value if present or null.
    */
    public Integer get(String key)
    if (map.containsKey(key))
    Entry entry = map.get(key);
    remove(entry);
    addToFront(entry);
    return entry.val;

    return null;


    /**
    * Puts the value associated with the key and
    * marks the key as most recent.
    *
    * @param key The cache key
    * @param val The cache value
    *
    * @return The value if present or null.
    */
    public void put(String key, int val)
    if (map.containsKey(key))
    Entry entry = map.get(key);
    remove(entry);
    addToFront(entry);
    else
    currentCount++;
    Entry entry = new Entry(key, val);
    if (currentCount > capacity)
    purge();

    addToFront(entry);
    map.put(key, entry);



    /**
    * Removes the entry from the list.
    */
    private void remove(Entry entry)
    if (entry.prev != null)
    entry.prev.next = entry.next;
    else
    head = entry.next;


    if (entry.next != null)
    entry.next.prev = entry.prev;
    else
    tail = entry.prev;



    /**
    * Removes the last entry from the list.
    */
    private void purge()
    if (tail == null)
    return;

    Entry entry = tail;
    if (head == tail)
    head = tail = null;
    else
    entry.prev.next = null;
    tail = entry.prev;
    tail.next = null;

    map.remove(entry.key);


    /**
    * Adds entry to the from of the list.
    */
    private void addToFront(Entry entry)
    entry.next = head;
    if (head != null)
    head.prev = entry;

    head = entry;
    if (tail == null)
    tail = head;



    public String toString()
    Entry current = head;
    StringBuilder s = new StringBuilder();
    while (current != null)
    s.append(current + " ");
    current = current.next;

    return s.toString();



    private static class Entry
    String key;
    int val;
    Entry next;
    Entry prev;

    Entry(String key, int val)
    this.key = key;
    this.val = val;


    public String toString()
    return key + ":" + val;



    public static void main(String args)
    try
    LRUCache cache = new LRUCache(-3);
    System.out.println("Test for -ve capacity failed");
    catch (IllegalArgumentException ex)
    System.out.println("Test for -ve capacity passed");


    LRUCache cache = new LRUCache(3);
    cache.put("foo", 1);
    cache.put("bar", 2);
    cache.put("zar", 3);
    System.out.println(cache); // => zar -> bar -> foo
    cache.put("doe", 4); // => purge, i.e. remove foo
    System.out.println(cache); // => doe -> zar -> bar
    cache.get("bar");
    System.out.println(cache); // => bar -> doe -> zar
    cache.get("doe");
    System.out.println(cache); // => doe -> bar -> zar

    try
    LRUCache c = new LRUCache(1);
    c.put("a", 1);
    c.put("b", 2);
    c.get("a");
    System.out.println("Should pass");
    catch (Exception e)
    e.printStackTrace(System.out);





    Note:



    I have used the basic data structures to get more clarity for managing pointers.



    Questions:



    I am more interested in OOP and creating better abstractions,
    any guidance in that direction would be great.







    share|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      Description:



      Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.



      More details can be found here.



      Code:



      import java.util.Map;
      import java.util.HashMap;

      class Main
      private static class LRUCache
      private final int capacity;
      private final Map<String, Entry> map;
      private int currentCount;
      private Entry head;
      private Entry tail;

      LRUCache(int capacity)
      if (capacity <= 0)
      throw new IllegalArgumentException("Capacity should be greater than 0: " + capacity);

      this.map = new HashMap<>();
      this.capacity = capacity;


      /**
      * Gets the value associated with the key and
      * marks the key as most recent used.
      *
      * @param key The cache key
      *
      * @return The value if present or null.
      */
      public Integer get(String key)
      if (map.containsKey(key))
      Entry entry = map.get(key);
      remove(entry);
      addToFront(entry);
      return entry.val;

      return null;


      /**
      * Puts the value associated with the key and
      * marks the key as most recent.
      *
      * @param key The cache key
      * @param val The cache value
      *
      * @return The value if present or null.
      */
      public void put(String key, int val)
      if (map.containsKey(key))
      Entry entry = map.get(key);
      remove(entry);
      addToFront(entry);
      else
      currentCount++;
      Entry entry = new Entry(key, val);
      if (currentCount > capacity)
      purge();

      addToFront(entry);
      map.put(key, entry);



      /**
      * Removes the entry from the list.
      */
      private void remove(Entry entry)
      if (entry.prev != null)
      entry.prev.next = entry.next;
      else
      head = entry.next;


      if (entry.next != null)
      entry.next.prev = entry.prev;
      else
      tail = entry.prev;



      /**
      * Removes the last entry from the list.
      */
      private void purge()
      if (tail == null)
      return;

      Entry entry = tail;
      if (head == tail)
      head = tail = null;
      else
      entry.prev.next = null;
      tail = entry.prev;
      tail.next = null;

      map.remove(entry.key);


      /**
      * Adds entry to the from of the list.
      */
      private void addToFront(Entry entry)
      entry.next = head;
      if (head != null)
      head.prev = entry;

      head = entry;
      if (tail == null)
      tail = head;



      public String toString()
      Entry current = head;
      StringBuilder s = new StringBuilder();
      while (current != null)
      s.append(current + " ");
      current = current.next;

      return s.toString();



      private static class Entry
      String key;
      int val;
      Entry next;
      Entry prev;

      Entry(String key, int val)
      this.key = key;
      this.val = val;


      public String toString()
      return key + ":" + val;



      public static void main(String args)
      try
      LRUCache cache = new LRUCache(-3);
      System.out.println("Test for -ve capacity failed");
      catch (IllegalArgumentException ex)
      System.out.println("Test for -ve capacity passed");


      LRUCache cache = new LRUCache(3);
      cache.put("foo", 1);
      cache.put("bar", 2);
      cache.put("zar", 3);
      System.out.println(cache); // => zar -> bar -> foo
      cache.put("doe", 4); // => purge, i.e. remove foo
      System.out.println(cache); // => doe -> zar -> bar
      cache.get("bar");
      System.out.println(cache); // => bar -> doe -> zar
      cache.get("doe");
      System.out.println(cache); // => doe -> bar -> zar

      try
      LRUCache c = new LRUCache(1);
      c.put("a", 1);
      c.put("b", 2);
      c.get("a");
      System.out.println("Should pass");
      catch (Exception e)
      e.printStackTrace(System.out);





      Note:



      I have used the basic data structures to get more clarity for managing pointers.



      Questions:



      I am more interested in OOP and creating better abstractions,
      any guidance in that direction would be great.







      share|improve this question













      Description:



      Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.



      More details can be found here.



      Code:



      import java.util.Map;
      import java.util.HashMap;

      class Main
      private static class LRUCache
      private final int capacity;
      private final Map<String, Entry> map;
      private int currentCount;
      private Entry head;
      private Entry tail;

      LRUCache(int capacity)
      if (capacity <= 0)
      throw new IllegalArgumentException("Capacity should be greater than 0: " + capacity);

      this.map = new HashMap<>();
      this.capacity = capacity;


      /**
      * Gets the value associated with the key and
      * marks the key as most recent used.
      *
      * @param key The cache key
      *
      * @return The value if present or null.
      */
      public Integer get(String key)
      if (map.containsKey(key))
      Entry entry = map.get(key);
      remove(entry);
      addToFront(entry);
      return entry.val;

      return null;


      /**
      * Puts the value associated with the key and
      * marks the key as most recent.
      *
      * @param key The cache key
      * @param val The cache value
      *
      * @return The value if present or null.
      */
      public void put(String key, int val)
      if (map.containsKey(key))
      Entry entry = map.get(key);
      remove(entry);
      addToFront(entry);
      else
      currentCount++;
      Entry entry = new Entry(key, val);
      if (currentCount > capacity)
      purge();

      addToFront(entry);
      map.put(key, entry);



      /**
      * Removes the entry from the list.
      */
      private void remove(Entry entry)
      if (entry.prev != null)
      entry.prev.next = entry.next;
      else
      head = entry.next;


      if (entry.next != null)
      entry.next.prev = entry.prev;
      else
      tail = entry.prev;



      /**
      * Removes the last entry from the list.
      */
      private void purge()
      if (tail == null)
      return;

      Entry entry = tail;
      if (head == tail)
      head = tail = null;
      else
      entry.prev.next = null;
      tail = entry.prev;
      tail.next = null;

      map.remove(entry.key);


      /**
      * Adds entry to the from of the list.
      */
      private void addToFront(Entry entry)
      entry.next = head;
      if (head != null)
      head.prev = entry;

      head = entry;
      if (tail == null)
      tail = head;



      public String toString()
      Entry current = head;
      StringBuilder s = new StringBuilder();
      while (current != null)
      s.append(current + " ");
      current = current.next;

      return s.toString();



      private static class Entry
      String key;
      int val;
      Entry next;
      Entry prev;

      Entry(String key, int val)
      this.key = key;
      this.val = val;


      public String toString()
      return key + ":" + val;



      public static void main(String args)
      try
      LRUCache cache = new LRUCache(-3);
      System.out.println("Test for -ve capacity failed");
      catch (IllegalArgumentException ex)
      System.out.println("Test for -ve capacity passed");


      LRUCache cache = new LRUCache(3);
      cache.put("foo", 1);
      cache.put("bar", 2);
      cache.put("zar", 3);
      System.out.println(cache); // => zar -> bar -> foo
      cache.put("doe", 4); // => purge, i.e. remove foo
      System.out.println(cache); // => doe -> zar -> bar
      cache.get("bar");
      System.out.println(cache); // => bar -> doe -> zar
      cache.get("doe");
      System.out.println(cache); // => doe -> bar -> zar

      try
      LRUCache c = new LRUCache(1);
      c.put("a", 1);
      c.put("b", 2);
      c.get("a");
      System.out.println("Should pass");
      catch (Exception e)
      e.printStackTrace(System.out);





      Note:



      I have used the basic data structures to get more clarity for managing pointers.



      Questions:



      I am more interested in OOP and creating better abstractions,
      any guidance in that direction would be great.









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jun 21 at 8:51
























      asked Jun 20 at 14:25









      CodeYogi

      1,99932060




      1,99932060

























          active

          oldest

          votes











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f196897%2fdesign-lru-cache%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes










           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f196897%2fdesign-lru-cache%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation