static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer);
//Add the feature string into list and get feature string id public long GetOrAddId(string strFeature) { while (ShrinkingLock == 1) { Thread.Sleep(5000); } //add item-adding lock Interlocked.Increment(ref AddLock); FeatureFreq newFFItem = new FeatureFreq(); newFFItem.strFeature = strFeature; newFFItem.value = 1; if (sortedEndIndex > 0) { FeatureFreq ff = arrayFeatureFreq.BinarySearch(0, sortedEndIndex, newFFItem); if (ff != null) { Interlocked.Increment(ref ff.value); //free item-adding lock Interlocked.Decrement(ref AddLock); return GetId(strFeature); } } long oldValue = Interlocked.Increment(ref arrayFeatureFreqSize) - 1; arrayFeatureFreq[oldValue] = newFFItem; //free item-adding lock Interlocked.Decrement(ref AddLock); //Check whether shrink process should be started uint memoryLoad = 0; if (oldValue % 10000000 == 0) { MEMORYSTATUSEX msex = new MEMORYSTATUSEX(); GlobalMemoryStatusEx(msex); memoryLoad = msex.dwMemoryLoad; } if (memoryLoad >= SHRINK_AVALI_MEM_LOAD) { if (Interlocked.CompareExchange(ref ShrinkingLock, 1, 0) == 0) { //Double check whether shrink should be started MEMORYSTATUSEX msex = new MEMORYSTATUSEX(); GlobalMemoryStatusEx(msex); if (msex.dwMemoryLoad >= SHRINK_AVALI_MEM_LOAD) { while (AddLock != 0) { Thread.Sleep(1000); } DateTime startDT = DateTime.Now; Console.WriteLine("Begin to shrink [Feature Size: {0}]...", arrayFeatureFreqSize); long newArrayFeatureFreqSize = Shrink(0, arrayFeatureFreqSize - 1, 0) + 1; GlobalMemoryStatusEx(msex); if (msex.dwMemoryLoad >= SHRINK_AVALI_MEM_LOAD - 1) { //Still have enough available memory, raise shrink threshold SHRINK_AVALI_MEM_LOAD = msex.dwMemoryLoad + 1; if (SHRINK_AVALI_MEM_LOAD >= 100) { //if use more than 100% memory, the performance will extremely reduce SHRINK_AVALI_MEM_LOAD = 100; } } arrayFeatureFreqSize = newArrayFeatureFreqSize; TimeSpan ts = DateTime.Now - startDT; Console.WriteLine("Shrink has been done!"); Console.WriteLine("[Feature Size:{0}, TimeSpan:{1}, Next Shrink Rate:{2}%]", arrayFeatureFreqSize, ts, SHRINK_AVALI_MEM_LOAD); } Interlocked.Decrement(ref ShrinkingLock); } } return GetId(strFeature); }