Advertisement
Guest User

NwayCache

a guest
Aug 30th, 2016
434
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.13 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace NWayCache
  8. {
  9.     public class NWayCache<T1, T2>
  10.     {
  11.         private readonly int itemsPerSet;
  12.         private readonly int numItems;
  13.         private readonly int numSets;
  14.         private Dictionary<int, Set> cache = new Dictionary<int, Set>();
  15.         private Set[] cacheArray;
  16.         public NWayCache(int itemsPerSet, int numItems)
  17.         {
  18.             this.itemsPerSet = itemsPerSet;
  19.             this.numItems = numItems;
  20.             if (numItems % itemsPerSet != 0) throw new DataMisalignedException("Number of items must be divisible by items per set");
  21.             numSets = numItems / itemsPerSet;
  22.             cacheArray = new Set[numSets];
  23.             for (int i = 0; i < numSets; i++)
  24.             {
  25.                 cacheArray[i] = new Set(itemsPerSet);
  26.             }
  27.         }
  28.  
  29.         public void SetEvictionLRU()
  30.         {
  31.             for (int i = 0; i < cacheArray.Length; i++)
  32.                 cacheArray[i].SetEvictionLRU();
  33.         }
  34.         public void SetEvictionMRU()
  35.         {
  36.             for (int i = 0; i < cacheArray.Length; i++)
  37.                 cacheArray[i].SetEvictionMRU();
  38.         }
  39.         public void SetEvictionCustomIndex(int index)
  40.         {
  41.             for (int i = 0; i < cacheArray.Length; i++)
  42.             {
  43.                 cacheArray[i].SetEvictionCustomIndex(index);
  44.             }
  45.         }
  46.         public T2 GetItem(T1 key)
  47.         {
  48.             int itemHash = Math.Abs(key.GetHashCode());
  49.             int setNum = itemHash % numSets;
  50.             return cacheArray[setNum].GetItem(key);
  51.         }
  52.         public void AddItem(T1 key, T2 value)
  53.         {
  54.             int itemHash = Math.Abs(key.GetHashCode());
  55.             int setNum = itemHash % numSets;
  56.             cacheArray[setNum].addItem(key, value);
  57.         }
  58.  
  59.         private class Set
  60.         {
  61.             private Node head, tail;
  62.             private readonly int setSize;
  63.             private int replaceIndex;
  64.             private delegate void EvictionMethod(T1 key, T2 value);
  65.             private Dictionary<T1, Node> setData = new Dictionary<T1, Node>();
  66.             private EvictionMethod evict;
  67.  
  68.             public Set(int setSize)
  69.             {
  70.                 this.setSize = setSize;
  71.                 head = null;
  72.                 tail = null;
  73.                 evict = LruReplace;
  74.             }
  75.             public void SetEvictionLRU()
  76.             {
  77.                 evict = LruReplace;
  78.             }
  79.             public void SetEvictionMRU()
  80.             {
  81.                 evict = MruReplace;
  82.             }
  83.             public void SetEvictionCustomIndex(int index)
  84.             {
  85.                 if (index > setSize - 1) throw new IndexOutOfRangeException();
  86.                 replaceIndex = index;
  87.                 evict = CustomReplace;
  88.             }
  89.  
  90.             public void CustomReplace(T1 key, T2 value)
  91.             {
  92.                 Node temp = tail;
  93.                 for (int i = 0; i < replaceIndex; i++)
  94.                 {
  95.                     temp = temp.prev;
  96.                 }
  97.                 MoveToTail(temp);
  98.                 setData.Remove(temp.key);
  99.                 MruReplace(key, value);
  100.             }
  101.             public T2 GetItem(T1 key)
  102.             {
  103.                 if (setData.ContainsKey(key))
  104.                 {
  105.                     Node node = setData[key];
  106.                     MoveToTail(node);
  107.                     return node.value;
  108.                 }
  109.                 else return default(T2);
  110.  
  111.             }
  112.             private void MoveToTail(Node node)
  113.             {
  114.  
  115.                 if (node != tail)
  116.                 {
  117.                     node.prev.next = node.next;
  118.                     node.next.prev = node.prev;
  119.                     node.next = tail.next;
  120.                     tail.next = node;
  121.                     node.prev = tail;
  122.                     head = node.next;
  123.                     head.prev = node;
  124.                     tail = node;
  125.                 }
  126.             }
  127.             public void LruReplace(T1 key, T2 value)
  128.             {
  129.                 setData.Remove(head.key);
  130.                 Node node = new Node(key, value);
  131.                 tail.next = node;
  132.                 node.prev = tail;
  133.                 node.next = head.next;
  134.                 head = head.next;
  135.                 tail = node;
  136.                 head.prev = tail;
  137.             }
  138.             public void MruReplace(T1 key, T2 value)
  139.             {
  140.                 setData.Remove(tail.key);
  141.                 Node node = new Node(key, value);
  142.                 head.prev = node;
  143.                 node.next = head;
  144.                 tail.prev.next = node;
  145.                 node.prev = tail.prev;
  146.                 tail = node;
  147.             }
  148.             public void addItem(T1 key, T2 value)
  149.             {
  150.                 if (setData.Keys.Count >= setSize)
  151.                 {
  152.                     evict(key, value);
  153.                     setData.Add(key, tail);
  154.                 }
  155.                 else
  156.                 {
  157.                     Node node = new Node(key, value);
  158.                     if (head == null)
  159.                     {
  160.                         head = node;
  161.                         tail = head;
  162.                     }
  163.                     else
  164.                     {
  165.                         tail.next = node;
  166.                         node.prev = tail;
  167.                         node.next = head;
  168.                         head.prev = node;
  169.                         tail = node;
  170.                         head.prev = tail;
  171.                     }
  172.                     setData.Add(key, node);
  173.  
  174.  
  175.                 }
  176.             }
  177.             public int getSize() { return setSize; }
  178.  
  179.             private class Node
  180.             {
  181.                 public T1 key;
  182.                 public T2 value;
  183.                 public Node prev, next;
  184.                 public Node(T1 key, T2 value)
  185.                 {
  186.                     this.key = key;
  187.                     this.value = value;
  188.                     prev = null;
  189.                     next = null;
  190.                 }
  191.             }
  192.         }
  193.  
  194.     }
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement