Advertisement
Guest User

Untitled

a guest
Jan 21st, 2018
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 16.22 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Reflection;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace ConsoleApp1
  11. {
  12.    
  13.     class Program
  14.     {
  15.  
  16.         static void Main(string[] args)
  17.         {
  18.             int hashFunctions =2;
  19.           //  int[] array = { 47, 50,55,1,2,3,4,5,6,7,8,8,9,10,11,12,13,14,200,300,43254,654,6757,4324,4324324,343,5646,57,6,87,9,890,80,5544,6546,65867,8 ,435,65,7,87,8,789,80,90,345,5,435,435};
  20.             int[] array = { 50, 47, 100, 60 };
  21.             CuckooHash hash = new CuckooHash(array.Length,hashFunctions);
  22.             int size = array.Length;
  23.             hash.HashArray(array,size);
  24.             while (hash.requiresRehashes)
  25.             {
  26.                 size = size*2;
  27.                 hash = new CuckooHash(size, hashFunctions);
  28.                // hash.Rehash();
  29.                 hash.HashArray(array,size);
  30.             }
  31.  
  32.             hash.ShowResult();
  33.             Console.ReadKey();
  34.         }
  35.     }
  36.  
  37.  
  38.     class CuckooHash
  39.     {
  40.         int max;
  41.         int hashFunctionCount;
  42.         int[,] hashtable;
  43.         int[] tempValues;
  44.         public bool requiresRehashes;
  45.  
  46.  
  47.         ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
  48.         UniversalHashingFamily hash;
  49.         public CuckooHash(int max, int hashfunctionCount)
  50.         {
  51.             this.max = max;
  52.             this.hashFunctionCount = hashfunctionCount;
  53.             tempValues = new int[hashfunctionCount];
  54.             hash = new UniversalHashingFamily(hashfunctionCount);
  55.             requiresRehashes = false;
  56.         }
  57.         private void InitHashTable()
  58.         {
  59.            
  60.             hashtable = new int[hashFunctionCount, max];
  61.  
  62.  
  63.             Parallel.For(0, max, i =>
  64.             {
  65.                 Parallel.For(0, hashFunctionCount, j =>
  66.                 {
  67.                     hashtable[j, i] = 0;
  68.                 });
  69.             });
  70.             //for (int i = 0; i < max; i++)
  71.             //{
  72.             //    for (int j = 0; j < hashFunctionCount; j++)
  73.             //    {
  74.             //        hashtable[j, i] = 0;
  75.             //    }
  76.             //}
  77.  
  78.         }
  79.  
  80.         public void Rehash()
  81.         {
  82.          hash.GenerateNewFunctions();
  83.         }
  84.         public void HashArray(int[] array,int size)
  85.         {
  86.             requiresRehashes = false;
  87.             InitHashTable();
  88.             int cnt = 0;
  89.  
  90.             Parallel.For(0, array.Length, i =>
  91.             {
  92.                 cnt = 0;
  93.                 PlaceToHash(array[i], 0, cnt, size);
  94.             });
  95.  
  96.             //for (int i = 0; i < array.Length; i++)
  97.             //{
  98.             //    cnt = 0;
  99.             //    PlaceToHash(array[i], 0, cnt, size);
  100.             //}
  101.         }
  102.  
  103.         void PlaceToHash(int value,int tableId,int timesBeenCalled,int cycleCount)
  104.         {
  105.             locker.EnterReadLock();
  106.             if(timesBeenCalled == cycleCount)
  107.             {
  108.                 Console.WriteLine("Unpositioned:"+value);
  109.                 requiresRehashes = true;
  110.                 locker.ExitReadLock();
  111.                 return;
  112.             }
  113.             for (int i = 0; i < hashFunctionCount; i++)
  114.             {
  115.                 tempValues[i] = HashLocal(i, value);
  116.                 if (hashtable[i,tempValues[i]] == value)
  117.                 {
  118.                     locker.ExitReadLock();
  119.                     return;
  120.                 }
  121.             }
  122.            
  123.             if(hashtable[tableId,tempValues[tableId]] != 0)
  124.             {
  125.                 int swapedValue = hashtable[tableId, tempValues[tableId]];
  126.                 hashtable[tableId, tempValues[tableId]] = value;
  127.                 locker.ExitReadLock();
  128.                 PlaceToHash(swapedValue, (tableId + 1) % hashFunctionCount, timesBeenCalled + 1, cycleCount);
  129.                
  130.             }
  131.             else
  132.             {
  133.                 hashtable[tableId, tempValues[tableId]] = value;
  134.              locker.ExitReadLock();
  135.             }
  136.         }
  137.  
  138.  
  139.         public void ShowResult()
  140.         {
  141.             for (int i = 0; i < hashFunctionCount; i++)
  142.             {
  143.                 Console.WriteLine("Table " + (i + 1).ToString());
  144.                 for (int j = 0; j < max; j++)
  145.                 {
  146.                     Console.Write(" "+hashtable[i, j]+" ");
  147.                 }
  148.                 Console.WriteLine();
  149.             }
  150.         }
  151.  
  152.  
  153.         public int HashLocal(int id, int key)
  154.         {
  155.             switch (id)
  156.             {
  157.                 case 0:
  158.                     return key % max;
  159.                 case 1:
  160.                     return (key / max) % max;
  161.                 case 2:
  162.                     return (key * max)%max;
  163.                 default:
  164.                     return 0;
  165.             }
  166.  
  167.         }
  168.     }
  169.  
  170.     /// <summary>
  171.     /// Provides a list of the first 10,000 primes.
  172.     /// This class is a singleton, and read the primes from the file @"Data\PrimesList_10K.csv".
  173.     /// </summary>
  174.     public sealed class PrimesList
  175.     {
  176.         //
  177.         // Singleton implementation with an attempted thread-safety using double-check locking
  178.         // internal datastorage singleton container
  179.         private static PrimesList _instance;
  180.  
  181.         // lock for thread-safety laziness
  182.         private static readonly object Mutex = new object();
  183.  
  184.         //
  185.         // INSTANCE VARIABLES
  186.         private static string _primesDocPath = string.Empty;
  187.         private readonly static List<int> _primes = new List<int>();
  188.  
  189.         // Picked the HashPrime to be (101) because it is prime, and if the ‘hashSize - 1’ is not a multiple of this HashPrime, which is
  190.         // enforced in _getUpperBoundPrime, then expand function has the potential of being every value from 1 to hashSize - 1.
  191.         // The choice is largely arbitrary.
  192.         public const int HASH_PRIME = 101;
  193.  
  194.  
  195.         /// <summary>
  196.         /// Empty private constructor.
  197.         /// </summary>
  198.         private PrimesList() { }
  199.  
  200.         /// <summary>
  201.         /// Returns the singleton instance of this class.
  202.         /// </summary>
  203.         public static PrimesList Instance
  204.         {
  205.             get
  206.             {
  207.                 if (_instance == null)
  208.                 {
  209.                     lock (Mutex)
  210.                     {
  211.                         if (_instance == null)
  212.                         {
  213.                             _instance = new PrimesList();
  214.                             _initializeData();
  215.                         }
  216.                     }
  217.                 }
  218.  
  219.                 return _instance;
  220.             }
  221.         }
  222.  
  223.         /// <summary>
  224.         /// Initializes the primes document path and list.
  225.         /// </summary>
  226.         private static void _initializeData()
  227.         {
  228.             _primesDocPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"Data/PrimesDocument_10K.csv");
  229.             string[] lines = File.ReadAllLines(_primesDocPath);
  230.  
  231.             foreach (var line in lines)
  232.             {
  233.                 // Split the line by commas and convert the collection to a list.
  234.                 var numbersAsStrings = line.Split(',').ToList<string>();
  235.  
  236.                 // defensive check against empty strings.
  237.                 numbersAsStrings.RemoveAll(item => string.IsNullOrEmpty(item) == true);
  238.  
  239.                 if (numbersAsStrings.Count > 0)
  240.                 {
  241.                     // cast them into integers and add them to the primes list
  242.                     var numbers = numbersAsStrings.Select(item => Convert.ToInt32(item)).ToList<int>();
  243.                     _primes.AddRange(numbers);
  244.                 }
  245.             }
  246.         }
  247.  
  248.         /// <summary>
  249.         /// Return count of primes.
  250.         /// </summary>
  251.         public int Count
  252.         {
  253.             get { return _primes.Count; }
  254.         }
  255.  
  256.         /// <summary>
  257.         /// Returns prime number at the specified index.
  258.         /// </summary>
  259.         public int this[int index]
  260.         {
  261.             get
  262.             {
  263.                 if (index < 0 || index >= _primes.Count)
  264.                     throw new ArgumentOutOfRangeException();
  265.  
  266.                 return _primes[index];
  267.             }
  268.         }
  269.  
  270.         /// <summary>
  271.         /// Checks if a number is a Prime Number.
  272.         /// </summary>
  273.         public bool IsPrime(int candidate)
  274.         {
  275.             if ((candidate & 1) != 0)
  276.             {
  277.                 int limit = (int)Math.Sqrt(candidate);
  278.  
  279.                 for (int divisor = 3; divisor <= limit; divisor += 2)
  280.                 {
  281.                     if ((candidate % divisor) == 0)
  282.                         return false;
  283.                 }
  284.  
  285.                 return true;
  286.             }
  287.  
  288.             return (candidate == 2);
  289.         }
  290.  
  291.         /// <summary>
  292.         /// Returns the next biggest prime number.
  293.         /// </summary>
  294.         /// <param name="number"></param>
  295.         /// <returns></returns>
  296.         public int GetNextPrime(int number)
  297.         {
  298.             if (number < 0)
  299.                 throw new ArgumentException("Number should be greater than or equal to 0.");
  300.  
  301.             for (int i = 0; i < _primes.Count; i++)
  302.             {
  303.                 if (_primes[i] >= number)
  304.                     return _primes[i];
  305.             }
  306.  
  307.             // Outside of our predefined table. Compute the prime the hard way.
  308.             for (int i = (number | 1); i < Int32.MaxValue; i += 2)
  309.             {
  310.                 if (IsPrime(i) && ((i - 1) % HASH_PRIME != 0))
  311.                     return i;
  312.             }
  313.  
  314.             return number;
  315.         }
  316.  
  317.         /// <summary>
  318.         /// Returns the next minimum prime number.
  319.         /// </summary>
  320.         public int GetPreviousPrime(int number)
  321.         {
  322.             if (number < 0)
  323.                 throw new ArgumentException("Number should be greater than or equal to 0.");
  324.  
  325.             for (int i = 0; i < _primes.Count; i++)
  326.             {
  327.                 if (_primes[i] >= number)
  328.                     return _primes[i];
  329.             }
  330.  
  331.             // Outside of our predefined table. Compute the prime the hard way.
  332.             for (int i = (number | 1); i < Int32.MaxValue; i += 2)
  333.             {
  334.                 if (IsPrime(i) && ((i - 1) % HASH_PRIME != 0))
  335.                     return i;
  336.             }
  337.  
  338.             return number;
  339.         }
  340.  
  341.         /// <summary>
  342.         /// Returns the list of primes
  343.         /// </summary>
  344.         public List<int> GetAll
  345.         {
  346.             get { return _primes; }
  347.         }
  348.  
  349.         /// <summary>
  350.         /// Copy the primes list to an array, starting from a specified index.
  351.         /// </summary>
  352.         public void CopyTo(int[] array, int index = 0)
  353.         {
  354.             if (array == null)
  355.                 array = new int[_primes.Count];
  356.  
  357.             if (array.Length <= index)
  358.                 throw new ArgumentOutOfRangeException();
  359.  
  360.             int count = array.Length - index;
  361.             int arrayIndex = index;
  362.  
  363.             if (count - _primes.Count > 0)
  364.                 count = _primes.Count;
  365.  
  366.             for (int i = 0; i < count; i++)
  367.             {
  368.                 array[arrayIndex] = _primes[i];
  369.                 arrayIndex++;
  370.             }
  371.         }
  372.  
  373.     }
  374.  
  375.     /// <summary>
  376.     /// Implements a family of Universal Hash Functions
  377.     /// </summary>
  378.     public class UniversalHashingFamily
  379.         {
  380.             // A large prime, arbitrarily chosen
  381.             // In decimal = 2,146,435,069;
  382.             private const int BIG_PRIME = 0x7FEFFFFD;
  383.  
  384.             private Random _randomizer { get; set; }
  385.             private int _numberOfHashFunctions { get; set; }
  386.             private int[] _firstMultipliersVector { get; set; }
  387.             private int[] _secondMultipliersVector { get; set; }
  388.             private static readonly PrimesList _primes = PrimesList.Instance;
  389.  
  390.             /// <summary>
  391.             /// Initializes the family with a specified number of hash functions.
  392.             /// </summary>
  393.             public UniversalHashingFamily(int numberOfHashFunctions)
  394.             {
  395.                 if (numberOfHashFunctions <= 0)
  396.                     throw new ArgumentOutOfRangeException("Number of hash functions should be greater than zero.");
  397.  
  398.                 _randomizer = new Random();
  399.                 _numberOfHashFunctions = numberOfHashFunctions;
  400.                 _firstMultipliersVector = new int[_numberOfHashFunctions];
  401.                 _secondMultipliersVector = new int[_numberOfHashFunctions];
  402.  
  403.                 GenerateNewFunctions();
  404.             }
  405.  
  406.             /// <summary>
  407.             /// Returns number of member hash functions.
  408.             /// </summary>
  409.             public int NumberOfFunctions
  410.             {
  411.                 get { return _numberOfHashFunctions; }
  412.             }
  413.  
  414.             /// <summary>
  415.             /// Generates new hash functions with new randomized multipliers.
  416.             /// </summary>
  417.             public void GenerateNewFunctions()
  418.             {
  419.                 // Clear the multipliers vectors
  420.                 Array.Clear(_firstMultipliersVector, 0, _firstMultipliersVector.Length);
  421.                 Array.Clear(_secondMultipliersVector, 0, _secondMultipliersVector.Length);
  422.  
  423.                 int randomMin = 0;
  424.                 int randomMax = _primes.Count - 1;
  425.  
  426.                 for (int i = 0; i < _numberOfHashFunctions; i++)
  427.                 {
  428.                     // Get only the primes that are smaller than the biggest-chosen prime.
  429.                     int randomIndex = _randomizer.Next(randomMin, randomMax);
  430.          
  431.                     while (_primes[randomIndex] >= BIG_PRIME)
  432.                         randomIndex = _randomizer.Next(randomMin, randomMax);
  433.        
  434.                 _firstMultipliersVector[i] = _primes[randomIndex];
  435.  
  436.                     // make sure the next prime we choose is different than the first one and less than the biggest-prime.
  437.                     randomIndex = _randomizer.Next(randomMin, randomMax);
  438.  
  439.                     while (_primes[randomIndex] >= BIG_PRIME || _primes[randomIndex] == _firstMultipliersVector[i])
  440.                         randomIndex = _randomizer.Next(randomMin, randomMax);
  441.  
  442.                     _secondMultipliersVector[i] = _primes[randomIndex];
  443.                 }
  444.             }
  445.  
  446.             /// <summary>
  447.             /// Returns hash value of a string, given the specified number of the hash function to use.
  448.             /// </summary>
  449.             /// <param name="preHashedKey">Int pre-hash code of an object.</param>
  450.             /// <param name="whichHashFunction">Non-zero, non-negative integer that specified the number of the hash function to use.</param>
  451.             /// <returns></returns>
  452.             public int UniversalHash(int preHashedKey, int whichHashFunction)
  453.             {
  454.                 if (whichHashFunction <= 0 || whichHashFunction > _numberOfHashFunctions)
  455.                     throw new ArgumentOutOfRangeException("WhichHashFunction parameter should be greater than zero or equal to the number of Hash Functions.");
  456.           //  preHashedKey = 0;
  457.                 int a = _firstMultipliersVector[whichHashFunction - 1];
  458.                 int b = _secondMultipliersVector[whichHashFunction - 1];
  459.  
  460.             return ((a * preHashedKey) + b); //% BIG_PRIME;
  461.             }
  462.  
  463.             /// <summary>
  464.             /// Returns hash value of a string, given the specified number of the hash function to use.
  465.             /// </summary>
  466.             /// <param name="key">string key.</param>
  467.             /// <param name="whichHashFunction">Non-zero, non-negative integer that specified the number of the hash function to use.</param>
  468.             public int UniversalHash(string key, int whichHashFunction)
  469.             {
  470.                 if (string.IsNullOrEmpty(key))
  471.                     throw new ArgumentException("Key is either an empty string or null.");
  472.  
  473.                 int prehash = 0;
  474.                 var characters = key.ToCharArray();
  475.                 int n = characters.Length;
  476.  
  477.                 for (int i = 0; i < n; ++i)
  478.                 {
  479.                     prehash = prehash + (characters[i] ^ (n - 1));
  480.                 }
  481.  
  482.                 return UniversalHash(prehash, whichHashFunction);
  483.             }
  484.         }
  485.    
  486. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement