public void AddEntry(DataShiftingEntry entry) { if (entry == null) throw new ArgumentException("Null entry found", entry.ToString()); Entries.Add(entry); //add entry to list }
/// <summary> /// Re-arranges total and used elements in given dictionaries and returns the counter of minimum drives still containing data /// </summary> /// <param name="uDict"></param> /// <param name="tDict"></param> /// <param name="minimum"></param> private void Pack(ref Dictionary<int, int> uDict, ref Dictionary<int, int> tDict, out int minimum) { minimum = 0; // counter of minimum drives still containing data int i, j = 0; // loop counters List<KeyValuePair<int, int>> tList = tDict.OrderByDescending(v => v.Value).ToList<KeyValuePair<int, int>>(); HashSet<int> keysUsed = new HashSet<int>(); try { for (i = 0; i < tList.Count; i++) { int i_key = tList[i].Key; int used = uDict[i_key]; int total = tList[i].Value; int free = total - used; if (free > 0) // disk has some space free { keysUsed.Add(i_key); //store dictionary key currently processed for (j = 0; j < uDict.Count; j++) //read through dictionary of used sizes to { int currentUsed = uDict.ElementAt(j).Value; //store sender's current used size //arrange used data if current used size is not zero and not already utilized and/or compared against itself if (currentUsed != 0 && uDict.ElementAt(j).Key != i_key && !keysUsed.Contains(uDict.ElementAt(j).Key)) { if (currentUsed == free) //sender send all of its used data, no left free space for the receiver { uDict[i_key] += currentUsed; //add used index of the same key uDict[uDict.ElementAt(j).Key] = 0; //set sending used size to zero free = 0; //disk is full entry = new DataShiftingEntry(uDict.ElementAt(j).Key, currentUsed, i_key); //create log entry consolidationLog.AddEntry(entry); //add entry to log break; //exit the loop } else if (currentUsed < free) //sender send all if its used data, receiver has still free space { uDict[i_key] += currentUsed; //add used index of the same key uDict[uDict.ElementAt(j).Key] = 0; //set sending used size to zero free -= currentUsed; //disk is not full entry = new DataShiftingEntry(uDict.ElementAt(j).Key, currentUsed, i_key); //create log entry consolidationLog.AddEntry(entry); //add entry to log } else if (currentUsed > free) //receiver becomes full, while sender still has free space { uDict[i_key] += free; //add used index of the same key uDict[uDict.ElementAt(j).Key] -= free; //calculate sender's new used size entry = new DataShiftingEntry(uDict.ElementAt(j).Key, free, i_key); //create log entry consolidationLog.AddEntry(entry); //add entry to log free = 0; //disk is full break; //exit the loop } } } } } } catch (IndexOutOfRangeException ie) { ArgumentException argex = new ArgumentException("Index is out of range", ie); throw ie; } int[] _used = new int[uDict.Count]; foreach (KeyValuePair<int, int> pair in uDict) { _used[pair.Key] = pair.Value; //copy to array } // count minimum number of disk drives that still contain data minimum = countMin(_used); }