/// <summary> /// This method is called before the result of a mutating operation /// represented by the specified entry object is committed into the /// underlying cache. /// </summary> /// <remarks> /// An implementation of this method can evaluate the change by /// analyzing the original and the new value, and can perform any of /// the following: /// <list type="bullet"> /// <item> /// override the requested change by setting /// <see cref="IInvocableCacheEntry.Value"/> to a different value; /// </item> /// <item> /// undo the pending change by resetting the entry value to the /// original value obtained from /// <see cref="ICacheTriggerEntry.OriginalValue"/> /// </item> /// <item> /// remove the entry from the underlying cache by calling /// <see cref="IInvocableCacheEntry.Remove"/> /// </item> /// <item> /// reject the pending change by throwing an <see cref="Exception"/>, /// which will prevent any changes from being committed, and will /// result in the exception being thrown from the operation that /// attempted to modify the cache; or /// </item> /// <item> /// do nothing, thus allowing the pending change to be committed to /// the underlying cache. /// </item> /// </list> /// </remarks> /// <param name="entry"> /// An <see cref="ICacheTriggerEntry"/> object that represents the /// pending change to be committed to the cache, as well as the /// original state of the entry. /// </param> public virtual void Process(ICacheTriggerEntry entry) { if (entry.IsPresent && !InvocableCacheHelper.EvaluateEntry(m_filter, entry)) { switch (m_action) { case ActionCode.Rollback: default: throw new ArgumentException("Rejecting " + entry + " by trigger " + this); case ActionCode.Ignore: object value = entry.OriginalValue; if (value != null || entry.IsOriginalPresent) { entry.SetValue(value, true); } else { entry.Remove(true); } break; case ActionCode.Remove: entry.Remove(true); break; } } }
/// <summary> /// Process an <see cref="IInvocableCacheEntry"/>. /// </summary> /// <param name="entry"> /// The <b>IInvocableCacheEntry</b> to process. /// </param> /// <returns> /// The result of the processing, if any. /// </returns> public override object Process(IInvocableCacheEntry entry) { if (InvocableCacheHelper.EvaluateEntry(m_filter, entry)) { return(m_processor.Process(entry)); } return(null); }
/// <summary> /// Apply the test to an <see cref="ICacheEntry"/>. /// </summary> /// <param name="entry"> /// The <b>ICacheEntry</b> to evaluate; never <c>null</c>. /// </param> /// <returns> /// <b>true</b> if the test passes, <b>false</b> otherwise. /// </returns> public new virtual bool EvaluateEntry(ICacheEntry entry) { IValueExtractor extractor = ValueExtractor; return(EvaluateExtracted(entry is IQueryCacheEntry ? ((IQueryCacheEntry)entry).Extract(extractor) : InvocableCacheHelper.ExtractFromEntry(extractor, entry))); }
/// <summary> /// Process an <see cref="IInvocableCacheEntry"/>. /// </summary> /// <param name="entry"> /// The <b>IInvocableCacheEntry</b> to process. /// </param> /// <returns> /// The result of the processing, if any. /// </returns> public override object Process(IInvocableCacheEntry entry) { if (entry.IsPresent && InvocableCacheHelper.EvaluateEntry(m_filter, entry)) { entry.Remove(false); return(null); } return(m_return ? entry.Value : null); }
/// <summary> /// Process an <see cref="IInvocableCacheEntry"/>. /// </summary> /// <param name="entry"> /// The <b>IInvocableCacheEntry</b> to process. /// </param> /// <returns> /// The result of the processing, if any. /// </returns> public override object Process(IInvocableCacheEntry entry) { if (InvocableCacheHelper.EvaluateEntry(m_filter, entry)) { entry.SetValue(m_value, false); return(null); } return(m_return ? entry.Value : null); }
/// <summary> /// Extract the "old" value from the specified entry. /// </summary> /// <param name="entry"> /// The entry to extract the "old" value from. /// </param> /// <returns> /// The extracted "old" value, or NO_VALUE if the extraction failed. /// </returns> protected Object ExtractOldValue(CacheEntry entry) { try { return(InvocableCacheHelper.ExtractOriginalFromEntry(ValueExtractor, entry)); } catch (Exception) { return(NO_VALUE); } }
/// <summary> /// Process an <see cref="IInvocableCacheEntry"/>. /// </summary> /// <param name="entry"> /// The <b>IInvocableCacheEntry</b> to process. /// </param> /// <returns> /// The result of the processing, if any. /// </returns> public override object Process(IInvocableCacheEntry entry) { IDictionary dictionary = m_dictionary; object key = entry.Key; if (dictionary.Contains(key) && InvocableCacheHelper.EvaluateEntry(m_filter, entry)) { entry.SetValue(dictionary[key], false); } return(null); }
/// <summary> /// Extract the value from the passed entry. /// </summary> /// <remarks> /// The underlying extractors are applied sequentially, so a result /// of a previous extractor serves as a target object for a next one. /// A value of <code>null</code> prevents any further extractions and /// is returned immediately. /// </remarks> /// <param name="entry"> /// An Entry object to extract a desired value from /// </param> /// <returns>The extracted value</returns> public override object ExtractFromEntry(ICacheEntry entry) { IValueExtractor[] extractors = Extractors; object target = InvocableCacheHelper.ExtractFromEntry(extractors[0], entry); for (int i = 1, c = extractors.Length; i < c && target != null; i++) { target = extractors[i].Extract(target); } return(target); }
/// <summary> /// Extract a collection of values from the passed entry using the /// underlying array of <b>IValueExtractor</b> objects. /// </summary> /// <param name="entry"> /// An entry to retrieve the collection of values from /// </param> /// <returns> /// An array containing extracted values /// </returns> public override object ExtractFromEntry(ICacheEntry entry) { IValueExtractor[] extractors = Extractors; int count = extractors.Length; object[] values = new object[count]; for (int i = 0; i < count; i++) { values[i] = InvocableCacheHelper.ExtractFromEntry(extractors[i], entry); } return(values); }
/// <summary> /// Apply the test to an <see cref="ICacheEntry"/>. /// </summary> /// <param name="entry"> /// The <b>ICacheEntry</b> to evaluate; never <c>null</c>. /// </param> /// <returns> /// <b>true</b> if the test passes, <b>false</b> otherwise. /// </returns> public override bool EvaluateEntry(ICacheEntry entry) { IFilter[] filters = m_filters; for (int i = 0, c = filters.Length; i < c; i++) { if (!(InvocableCacheHelper.EvaluateEntry(filters[i], entry))) { return(false); } } return(true); }
/// <summary> /// Process a collection of <see cref="IInvocableCacheEntry"/> /// objects. /// </summary> /// <param name="entries"> /// A read-only collection of <b>IInvocableCacheEntry</b> /// objects to process. /// </param> /// <returns> /// A dictionary containing the results of the processing, up to one /// entry for each <b>IInvocableCacheEntry</b> that was /// processed, keyed by the keys of the dictionary that were /// processed, with a corresponding value being the result of the /// processing for each key. /// </returns> public override IDictionary ProcessAll(ICollection entries) { IDictionary results = new LiteDictionary(); IFilter filter = m_filter; foreach (IInvocableCacheEntry entry in entries) { if (InvocableCacheHelper.EvaluateEntry(filter, entry)) { results[entry.Key] = Process(entry); } } return(results); }
/// <summary> /// Process a collection of <see cref="IInvocableCacheEntry"/> /// objects. /// </summary> /// <param name="entries"> /// A read-only collection of <b>IInvocableCacheEntry</b> /// objects to process. /// </param> /// <returns> /// An empty, immutable dictionary. /// </returns> public override IDictionary ProcessAll(ICollection entries) { IDictionary dictionary = m_dictionary; IFilter filter = m_filter; foreach (IInvocableCacheEntry entry in entries) { object key = entry.Key; if (dictionary.Contains(key) && InvocableCacheHelper.EvaluateEntry(filter, entry)) { entry.SetValue(dictionary[key], false); } } return(NullImplementation.GetDictionary()); }
/// <summary> /// Extract the "new" value from the specified entry. /// </summary> /// <param name="entry"> /// The entry to extract the "new" value from. /// </param> /// <returns> /// The extracted "new" value, or NO_VALUE if the extraction failed /// </returns> protected Object ExtractNewValue(ICacheEntry entry) { try { return(InvocableCacheHelper.ExtractFromEntry(ValueExtractor, entry)); } catch (Exception e) { CacheFactory.Log("An Exception occurred during index update for key " + entry.Key + ". The entry will be excluded from the index.\n", CacheFactory.LogLevel.Warn); CacheFactory.Log(e + ":\n" + e.StackTrace, CacheFactory.LogLevel.Warn); return(NO_VALUE); } }
/// <summary> /// Evaluate the given entry using this index's filter. If the entry /// does not pass the filter then it should be excluded from this /// index, making this a partial index. /// </summary> /// <param name="entry">The entry to evaluate.</param> /// <returns> /// <c>true</c> If the entry passes the filter, <b>false</b> otherwise. /// </returns> protected virtual bool EvaluateEntry(ICacheEntry entry) { try { if (InvocableCacheHelper.EvaluateEntry(Filter, entry)) { return(true); } } catch (Exception) { // COH-6447: don't drop the index upon exception } m_partial = true; return(false); }
/// <summary> /// Process a collection of <see cref="IInvocableCacheEntry"/> /// objects. /// </summary> /// <param name="entries"> /// A read-only collection of <b>IInvocableCacheEntry</b> /// objects to process. /// </param> /// <returns> /// A dictionary containing the results of the processing, up to one /// entry for each <b>IInvocableCacheEntry</b> that was /// processed, keyed by the keys of the dictionary that were /// processed, with a corresponding value being the result of the /// processing for each key. /// </returns> public override IDictionary ProcessAll(ICollection entries) { IDictionary results = new LiteDictionary(); IFilter filter = m_filter; foreach (IInvocableCacheEntry entry in entries) { if (entry.IsPresent && InvocableCacheHelper.EvaluateEntry(filter, entry)) { entry.Remove(false); } else if (m_return) { results[entry.Key] = entry.Value; } } return(results); }
/// <summary> /// Update this index in response to a delete operation on a cache. /// </summary> /// <param name="entry"> /// The entry representing the object being inserted. /// </param> protected override void DeleteInternal(ICacheEntry entry) { try { if (entry is CacheEntry && !InvocableCacheHelper.EvaluateOriginalEntry(Filter, (CacheEntry)entry)) { // the "original" entry would have been excluded; nothing to do return; } } catch (Exception) { // COH-6447: attempt the delete anyway because the filter may have // allowed this value previously and it may be in the index } base.DeleteInternal(entry); }
/// <summary> /// Process a collection of <see cref="IInvocableCacheEntry"/> /// objects. /// </summary> /// <param name="entries"> /// A read-only collection of <b>IInvocableCacheEntry</b> /// objects to process. /// </param> /// <returns> /// A dictionary containing the results of the processing, up to one /// entry for each <b>IInvocableCacheEntry</b> that was /// processed, keyed by the keys of the dictionary that were /// processed, with a corresponding value being the result of the /// processing for each key. /// </returns> public override IDictionary ProcessAll(ICollection entries) { IDictionary results = new LiteDictionary(); IFilter filter = m_filter; object value = m_value; bool ret = m_return; foreach (IInvocableCacheEntry entry in entries) { if (InvocableCacheHelper.EvaluateEntry(filter, entry)) { entry.SetValue(value, false); } else if (ret) { results[entry.Key] = entry.Value; } } return(results); }
/// <summary> /// Apply the test to an <see cref="ICacheEntry"/>. /// </summary> /// <param name="entry"> /// The <b>ICacheEntry</b> to evaluate; never <c>null</c>. /// </param> /// <returns> /// <b>true</b> if the test passes, <b>false</b> otherwise. /// </returns> public override bool EvaluateEntry(ICacheEntry entry) { IFilter[] filters = m_filters; return(InvocableCacheHelper.EvaluateEntry(filters[0], entry) ^ InvocableCacheHelper.EvaluateEntry(filters[1], entry)); }
/// <summary> /// Apply the test to an <see cref="ICacheEntry"/>. /// </summary> /// <param name="entry"> /// The <b>ICacheEntry</b> to evaluate; never <c>null</c>. /// </param> /// <returns> /// <b>true</b> if the test passes, <b>false</b> otherwise. /// </returns> public virtual bool EvaluateEntry(ICacheEntry entry) { return(CollectionUtils.Contains(m_keys, entry.Key) && InvocableCacheHelper.EvaluateEntry(m_filter, entry)); }
/// <summary> /// Apply the test to an <see cref="ICacheEntry"/>. /// </summary> /// <param name="entry"> /// The <b>ICacheEntry</b> to evaluate; never <c>null</c>. /// </param> /// <returns> /// <b>true</b> if the test passes, <b>false</b> otherwise. /// </returns> public virtual bool EvaluateEntry(ICacheEntry entry) { return(!InvocableCacheHelper.EvaluateEntry(m_filter, entry)); }