/// <summary> /// Removes key and value pairs from the cache. The keys are specified as parameter. /// Moreover it take a removal reason and a boolean specifying if a notification should /// be raised. /// </summary> /// <param name="keys">keys of the entry.</param> /// <param name="removalReason">reason for the removal.</param> /// <param name="notify">boolean specifying to raise the event.</param> /// <returns>list of removed keys</returns> public override Hashtable Remove(object[] keys, ItemRemoveReason removalReason, bool notify, bool isUserOperation, OperationContext operationContext) { Hashtable table = new Hashtable(); EventContext eventContext = null; EventId eventId = null; OperationID opId = operationContext.OperatoinID; for (int i = 0; i < keys.Length; i++) { try { operationContext.RemoveValueByField(OperationContextFieldName.EventContext); if (notify) { //generate EventId eventId = new EventId(); eventId.EventUniqueID = opId.OperationId; eventId.OperationCounter = opId.OpCounter; eventId.EventCounter = i; eventContext = new EventContext(); eventContext.Add(EventContextFieldName.EventID, eventId); operationContext.Add(OperationContextFieldName.EventContext, eventContext); } CacheEntry e = Remove(keys[i], removalReason, notify, null, LockAccessType.IGNORE_LOCK, operationContext); if (e != null) { table[keys[i]] = e; } } catch (StateTransferException e) { table[keys[i]] = e; } finally { operationContext.RemoveValueByField(OperationContextFieldName.EventContext); } } if (_context.PerfStatsColl != null) { _context.PerfStatsColl.SetCacheSize(Size); } return table; }
/// <summary> /// Adds key and value pairs to the cache. If any of the specified keys /// already exists in the cache; it is updated, otherwise a new item is /// added to the cache. /// </summary> /// <param name="keys">keys of the entries.</param> /// <param name="cacheEntry">the cache entries.</param> /// <returns>returns keys that are added or updated successfully and their status.</returns> public sealed override Hashtable Insert(object[] keys, CacheEntry[] cacheEntries, bool notify, OperationContext operationContext) { Hashtable table = new Hashtable(); EventContext eventContext = null; EventId eventId = null; OperationID opId = operationContext.OperatoinID; for (int i = 0; i < keys.Length; i++) { try { operationContext.RemoveValueByField(OperationContextFieldName.EventContext); if (notify) { //generate EventId eventId = new EventId(); eventId.EventUniqueID = opId.OperationId; eventId.OperationCounter = opId.OpCounter; eventId.EventCounter = i; eventContext = new EventContext(); eventContext.Add(EventContextFieldName.EventID, eventId); operationContext.Add(OperationContextFieldName.EventContext, eventContext); } CacheInsResultWithEntry result = Insert(keys[i], cacheEntries[i], notify, null, LockAccessType.IGNORE_LOCK, operationContext); table.Add(keys[i], result); } catch (Exception e) { table[keys[i]] = e; } finally { operationContext.RemoveValueByField(OperationContextFieldName.EventContext); } } if (_context.PerfStatsColl != null) { _context.PerfStatsColl.SetCacheSize(Size); } return table; }
/// <summary> /// Retrieve the objects from the cache. /// An array of keys is passed as parameter. /// </summary> /// <param name="keys">keys of the entries.</param> /// <returns>key and entry pairs.</returns> public sealed override Hashtable Get(object[] keys, OperationContext operationContext) { Hashtable entries = new Hashtable(); CacheEntry e = null; for (int i = 0; i < keys.Length; i++) { try { if(operationContext != null) { operationContext.RemoveValueByField(OperationContextFieldName.EventContext); OperationID opId = operationContext.OperatoinID; //generate EventId EventId eventId = EventId.CreateEventId(opId); eventId.EventUniqueID = opId.OperationId; eventId.OperationCounter = opId.OpCounter; eventId.EventCounter = i; EventContext eventContext = new EventContext(); eventContext.Add(EventContextFieldName.EventID, eventId); operationContext.Add(OperationContextFieldName.EventContext, eventContext); } e = Get(keys[i], operationContext); if (e != null) { entries[keys[i]] = e; } } catch (StateTransferException se) { entries[keys[i]] = se; } } return entries; }
/// <summary> /// Adds key and value pairs to the cache. Throws an exception or returns the /// list of keys that failed to add in the cache. /// </summary> /// <param name="keys">keys of the entries.</param> /// <param name="cacheEntries">the cache entries.</param> /// <returns>List of keys that are added or that alredy exists in the cache and their status.</returns> public sealed override Hashtable Add(object[] keys, CacheEntry[] cacheEntries, bool notify, OperationContext operationContext) { Hashtable table = new Hashtable(); EventContext eventContext = null; EventId eventId = null; OperationID opId = operationContext.OperatoinID; for (int i = 0; i < keys.Length; i++) { try { operationContext.RemoveValueByField(OperationContextFieldName.EventContext); if (notify) { //generate EventId eventId = new EventId(); eventId.EventUniqueID = opId.OperationId; eventId.OperationCounter = opId.OpCounter; eventId.EventCounter = i; eventContext = new EventContext(); eventContext.Add(EventContextFieldName.EventID, eventId); operationContext.Add(OperationContextFieldName.EventContext, eventContext); } CacheAddResult result = Add(keys[i], cacheEntries[i], notify, operationContext); table[keys[i]] = result; } catch (Exceptions.StateTransferException se) { table[keys[i]] = se; } catch (Exception inner) { table[keys[i]] = new OperationFailedException(inner.Message, inner); } finally { operationContext.RemoveValueByField(OperationContextFieldName.EventContext); } } if (_context.PerfStatsColl != null) { _context.PerfStatsColl.SetCacheSize(Size); } return table; }
private Hashtable ClusteredInsert(object[] keys, CacheEntry[] cacheEntries, bool notify, OperationContext operationContext) { Hashtable targetNodes = null; Hashtable result = new Hashtable(); Hashtable tmpResult = null; ArrayList totalKeys = new ArrayList(keys); ArrayList totalEntries = new ArrayList(cacheEntries); ArrayList keysToInsert = new ArrayList(keys); Address targetNode = null; object[] currentKeys = null; CacheEntry[] currentValues = null; Dictionary<object, CacheEntry> fullEntrySet = new Dictionary<object, CacheEntry>(); Hashtable totalAddedKeys = new Hashtable(); Hashtable totalInsertedKeys = new Hashtable(); Hashtable totalRemainingKeys = new Hashtable(); if (_internalCache == null) throw new InvalidOperationException(); do { targetNodes = GetTargetNodes(keysToInsert); if (targetNodes != null && targetNodes.Count == 0) { foreach (object key in keysToInsert) { result[key] = new OperationFailedException("No target node available to accommodate the data."); } return result; } IDictionaryEnumerator ide = targetNodes.GetEnumerator(); Hashtable keyList = null; //We select one node at a time for Add operation. while (ide.MoveNext()) { targetNode = ide.Key as Address; keyList = (Hashtable) ide.Value; if (targetNode != null && keyList != null) { currentKeys = new object[keyList.Count]; currentValues = new CacheEntry[keyList.Count]; int j = 0; foreach (object key in keyList.Keys) { int index = totalKeys.IndexOf(key); if (index != -1) { currentKeys[j] = totalKeys[index]; currentValues[j] = totalEntries[index] as CacheEntry; if (!fullEntrySet.ContainsKey((string) totalKeys[index])) fullEntrySet.Add((string) totalKeys[index], (CacheEntry) totalEntries[index]); j++; } } try { if (targetNode.Equals(Cluster.LocalAddress)) { tmpResult = Local_Insert(currentKeys, currentValues, Cluster.LocalAddress, notify, operationContext); } else { tmpResult = Clustered_Insert(targetNode, currentKeys, currentValues, operationContext); } } catch (Runtime.Exceptions.SuspectedException se) { //we redo the operation if (Context.NCacheLog.IsInfoEnabled) Context.NCacheLog.Info("PartitionedServerCache.SafeAdd", targetNode + " left while addition"); tmpResult = new Hashtable(); for (int i = 0; i < currentKeys.Length; i++) { tmpResult[currentKeys[i]] = new GeneralFailureException(se.Message, se); } } catch (Runtime.Exceptions.TimeoutException te) { if (Context.NCacheLog.IsInfoEnabled) Context.NCacheLog.Info("PartitionedServerCache.SafeAdd", targetNode + " operation timed out"); tmpResult = new Hashtable(); for (int i = 0; i < currentKeys.Length; i++) { tmpResult[currentKeys[i]] = new GeneralFailureException(te.Message, te); } } catch (BucketTransferredException ex) { tmpResult = new Hashtable(); for (int i = 0; i < currentKeys.Length; i++) { tmpResult[currentKeys[i]] = new OperationFailedException(ex.Message, ex); } } if (tmpResult != null && tmpResult.Count > 0) { IDictionaryEnumerator ie = tmpResult.GetEnumerator(); while (ie.MoveNext()) { if (ie.Value is StateTransferException) { totalRemainingKeys[ie.Key] = null; } else { if (ie.Value is Exception) { result[ie.Key] = ie.Value; } else if (ie.Value is CacheInsResultWithEntry) { CacheInsResultWithEntry res = ie.Value as CacheInsResultWithEntry; switch (res.Result) { case CacheInsResult.Failure: result[ie.Key] = new OperationFailedException( "Generic operation failure; not enough information is available."); break; case CacheInsResult.NeedsEviction: result[ie.Key] = new OperationFailedException( "The cache is full and not enough items could be evicted."); break; case CacheInsResult.Success: totalAddedKeys[ie.Key] = null; break; case CacheInsResult.SuccessOverwrite: totalInsertedKeys[ie.Key] = ie.Value; result[ie.Key] = ie.Value; break; } } } } } } } keysToInsert = new ArrayList(totalRemainingKeys.Keys); totalRemainingKeys.Clear(); } while (keysToInsert.Count > 0); object generateQueryInfo = operationContext.GetValueByField(OperationContextFieldName.GenerateQueryInfo); if (generateQueryInfo == null) { operationContext.Add(OperationContextFieldName.GenerateQueryInfo, true); } if (totalInsertedKeys.Count > 0) { IDictionaryEnumerator ide = totalInsertedKeys.GetEnumerator(); while (ide.MoveNext()) { object key = ide.Key; CacheInsResultWithEntry insResult = ide.Value as CacheInsResultWithEntry; if (notify) { CacheEntry currentEntry = fullEntrySet[(string) ide.Key]; object value = insResult.Entry.Value; if (value is CallbackEntry) { RaiseCustomUpdateCalbackNotifier(ide.Key, currentEntry, insResult.Entry, operationContext); } } } } if (generateQueryInfo == null) { operationContext.RemoveValueByField(OperationContextFieldName.GenerateQueryInfo); } return result; }