public virtual void AcquireWriterLock(IDataModelTransaction dataModelTransaction) { // This is a helper method and really just combines three frequently used operations to make the server-side code cleaner to read. this.AcquireWriterLock(dataModelTransaction.TransactionId, this.LockTimeout); dataModelTransaction.AddLock(this); // This will insure that we haven't attempted to lock a deleted row. This is a helper function to make the server-side transactions easier to write // and, thus, there's the potential to make mistakes that the generated data model would not make. if (this.RowState == DataRowState.Detached) { throw new LockException(String.Format(CultureInfo.CurrentCulture, Properties.Resources.DeletedAfterLockedError, this.GetType())); } }
private void SearchByProbableSocialSecurity(RowLockingWrapper <CreditCardRow> creditCardRowToFind, RowLockingWrapper <ConsumerRow> consumerRowToFind, object ccNum, object ssnNum, object lastName, List <MatchResult> results, IDataModelTransaction dataModelTransaction, Decimal matchThreshold) { Dictionary <IRow, MatchInfo> probableMap = this.socialMatcher.FindProbable(ssnNum, consumerRowToFind, true, dataModelTransaction); if (probableMap == null) { return; } probableMap.Remove(consumerRowToFind.Row); GetMatchResultsForSocial(creditCardRowToFind, consumerRowToFind, ccNum, lastName, results, probableMap.Values, dataModelTransaction, matchThreshold); }
public virtual void AcquireReaderLock(IDataModelTransaction dataModelTransaction) { // Use the internal method to acquire the read lock. this.AcquireReaderLock(dataModelTransaction.TransactionId, this.LockTimeout); // This can now be added to the list of rows locked by the transaction. dataModelTransaction.AddLock(this); // This will insure that we haven't attempted to lock a deleted row. This is a helper function to make the server-side transactions easier to write // and, thus, there's the potential to make mistakes that the generated data model would not make. if (this.RowState == DataRowState.Detached) { throw new LockException(String.Format(CultureInfo.CurrentCulture, Properties.Resources.DeletedAfterLockedError, this.GetType())); } }
/// <summary> /// Acquires a reader lock for this record. /// </summary> /// <param name="dataModelTransaction">The transaction context for this operation.</param> //[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public virtual void AcquireReaderLock(IDataModelTransaction dataModelTransaction) { global::System.Guid transactionId = dataModelTransaction.TransactionId; try { global::System.Threading.Monitor.Enter(this.rowRoot); this.readerWaiters = (this.readerWaiters + 1); if ((this.writer != transactionId)) { for ( ; (this.writer != global::System.Guid.Empty); ) { if (false == global::System.Threading.Monitor.Wait(this.rowRoot, this.LockTimeout)) { try { EventLog.Information("AcquireReaderLock DEGRADE from TIMEOUT\r\n {0} Current Stack: {1} \r\n{2}", this.GetRowDebugDescription(), UnhandledExceptionHelper.GetStackString(), this.GetCurrentLockStacks(false)); } catch { } break; } } int index = this._readers.BinarySearch(transactionId); if ((index < 0)) { InsertToReaderList(transactionId, index); } } } finally { this.readerWaiters = (this.readerWaiters - 1); global::System.Threading.Monitor.Exit(this.rowRoot); } dataModelTransaction.AddLock(this); if ((this.RowState == global::System.Data.DataRowState.Detached)) { throw new global::System.Exception("The " + this.GetType().FullName + " record was deleted after it was locked"); } }
private void SearchByExactSocialSecurity(RowLockingWrapper <CreditCardRow> creditCardRowToFind, RowLockingWrapper <ConsumerRow> consumerRowToFind, object ccNum, object ssnNum, object lastName, List <MatchResult> results, IDataModelTransaction dataModelTransaction, Decimal matchThreshold) { List <MatchInfo> snMiList = this.socialMatcher.FindExact(ssnNum, consumerRowToFind, dataModelTransaction); if (snMiList != null) { //remove the input row for (int i = snMiList.Count - 1; i >= 0; i--) { if (snMiList[i].row == consumerRowToFind.Row) { snMiList.RemoveAt(i); } } } GetMatchResultsForSocial(creditCardRowToFind, consumerRowToFind, ccNum, lastName, results, snMiList, dataModelTransaction, matchThreshold); }
//private System.Data.DataColumn dobNameColumn; /// <summary> /// /// </summary> /// <param name="creditCardTable"></param> /// <param name="consumerTable"></param> /// <param name="creditCardRowList"></param> /// <param name="consumerRowList"></param> /// <param name="dataModelTransaction"></param> public CardSocialLastNameFuzzyMatcher(CreditCardDataTable creditCardTable, ConsumerDataTable consumerTable, List <RowLockingWrapper <CreditCardRow> > creditCardRowList, List <RowLockingWrapper <ConsumerRow> > consumerRowList, IDataModelTransaction dataModelTransaction) { //get the credit card number column this.creditCardColumn = creditCardTable.OriginalAccountNumberColumn; //create the matcher for the credit card number. //will support Exact and Parts lookup types (validation is implicit) this.cardMatcher = ColumnFuzzyMatcher.CreateFuzzyMatcher(new MatcherCreateArgs(16, DataCharType.DigitsOnly, SupportedLookupType.ExactLookup | SupportedLookupType.UseDataMasksForProbable, ExtendedStorageTypes.ConvertToValue | ExtendedStorageTypes.ConvertToValueList, this.creditCardColumn)); //load up the matcher foreach (RowLockingWrapper <CreditCardRow> curCreditCardRow in creditCardRowList) { curCreditCardRow.AcquireReaderLock(); try { this.cardMatcher.AddTableRowToMap(curCreditCardRow); } finally { curCreditCardRow.ReleaseReaderLock(); } } this.ssnColumn = consumerTable.SocialSecurityNumberColumn; this.socialMatcher = ColumnFuzzyMatcher.CreateFuzzyMatcher(new MatcherCreateArgs(9, DataCharType.DigitsOnly, SupportedLookupType.ExactLookup | SupportedLookupType.UseDataMasksForProbable, ExtendedStorageTypes.ConvertToValue | ExtendedStorageTypes.ConvertToValueList, this.ssnColumn)); //no parts for these this.lastNameColumn = consumerTable.LastNameColumn; this.lastNameMatcher = ColumnFuzzyMatcher.CreateFuzzyMatcher(new MatcherCreateArgs(12, DataCharType.String, SupportedLookupType.ValidateOnly, ExtendedStorageTypes.ConvertToValue | ExtendedStorageTypes.ConvertToValueList, this.lastNameColumn)); this.firstNameColumn = consumerTable.FirstNameColumn; this.firstNameMatcher = ColumnFuzzyMatcher.CreateFuzzyMatcher(new MatcherCreateArgs(12, DataCharType.String, SupportedLookupType.ValidateOnly, ExtendedStorageTypes.ConvertToValue | ExtendedStorageTypes.ConvertToValueList, this.firstNameColumn)); foreach (RowLockingWrapper <ConsumerRow> consumerRow in consumerRowList) { consumerRow.AcquireReaderLock(); try { this.firstNameMatcher.AddTableRowToMap(consumerRow); this.lastNameMatcher.AddTableRowToMap(consumerRow); this.socialMatcher.AddTableRowToMap(consumerRow); } finally { consumerRow.ReleaseReaderLock(); } } //this.dobMatcher = ColumnFuzzyMatcher.CreateFuzzyMatcher(ColumnFuzzyMatcher.DataCharType.DateTime, // ColumnFuzzyMatcher.SupportedLookupType.ValidateOnly, // ds.Consumer.LastNameColumn); //this.dobMatcher.AddTableRowsToMap(); }
private void GetMatchResultsForSocial(RowLockingWrapper <CreditCardRow> creditCardRowToFind, RowLockingWrapper <ConsumerRow> consumerRowToFind, object ccNum, object lastName, List <MatchResult> results, IEnumerable <MatchInfo> snMiList, IDataModelTransaction dataModelTransaction, Decimal matchThreshold) { if (snMiList == null) { return; } //!!!RM what is faster using the .Consumer row //or using the ConsumerRow Fuz Matcher foreach (MatchInfo snMi in snMiList) { ConsumerRow miConsumerRow = (ConsumerRow)snMi.row; RowLockingWrapper <ConsumerRow> miConsumerRowWrapper = new RowLockingWrapper <ConsumerRow>(miConsumerRow, dataModelTransaction); MatchInfo ssnLnMi = this.lastNameMatcher.Validate(lastName, miConsumerRowWrapper, dataModelTransaction); MatchInfo ssnFnMi = null; miConsumerRowWrapper.AcquireReaderLock(); if (miConsumerRow.RowState == DataRowState.Deleted || miConsumerRow.RowState == DataRowState.Detached) { continue; } try { CreditCardRow[] ccRows = miConsumerRow.GetCreditCardRows_NoLockCheck(); if (ccRows.Length > 0) { foreach (CreditCardRow snCcRow in ccRows) { RowLockingWrapper <CreditCardRow> snCcRowWrappper = new RowLockingWrapper <CreditCardRow>(snCcRow, dataModelTransaction); MatchInfo ssnCcMi = this.cardMatcher.Validate(ccNum, snCcRowWrappper, dataModelTransaction); MatchResult mr = new MatchResult(consumerRowToFind.TypedRow, creditCardRowToFind.TypedRow, ssnCcMi, snMi, ssnLnMi); //if(mr.Strength < 1M) //{ if (ssnFnMi == null) { consumerRowToFind.AcquireReaderLock(); try { ssnFnMi = this.firstNameMatcher.Validate(consumerRowToFind.Row[this.firstNameColumn], miConsumerRowWrapper, dataModelTransaction); } finally { consumerRowToFind.ReleaseReaderLock(); } } mr.AddFirstNameMatchInfo(ssnFnMi); //} if (mr.Strength >= matchThreshold) { results.Add(mr); } } } else { MatchResult mr = new MatchResult(consumerRowToFind.TypedRow, creditCardRowToFind.TypedRow, null, snMi, ssnLnMi); consumerRowToFind.AcquireReaderLock(); try { mr.AddFirstNameMatchInfo(this.firstNameMatcher.Validate(consumerRowToFind.Row[this.firstNameColumn], miConsumerRowWrapper, dataModelTransaction)); } finally { consumerRowToFind.ReleaseReaderLock(); } if (mr.Strength >= matchThreshold) { results.Add(mr); } } } finally { miConsumerRowWrapper.ReleaseReaderLock(); } } }
private void GetMatchResultsForCreditCard(RowLockingWrapper <CreditCardRow> creditCardRowToFind, RowLockingWrapper <ConsumerRow> consumerRowToFind, object ssnNum, object lastName, List <MatchResult> results, IEnumerable <MatchInfo> ccMiList, IDataModelTransaction dataModelTransaction, Decimal matchThreshold) { if (ccMiList == null) { return; } //!!!RM what is faster using the .Consumer row //or using the ConsumerRow Fuz Matcher foreach (MatchInfo ccMi in ccMiList) { ConsumerRow miConsumerRow; if (dataModelTransaction != null) { ((CreditCardRow)ccMi.row).AcquireReaderLock(dataModelTransaction.TransactionId, ((CreditCardRow)ccMi.row).LockTimeout); } if (ccMi.row.RowState == DataRowState.Deleted || ccMi.row.RowState == DataRowState.Detached) { if (dataModelTransaction != null) { ((CreditCardRow)ccMi.row).ReleaseReaderLock(dataModelTransaction.TransactionId); } continue; } try { miConsumerRow = ((CreditCardRow)ccMi.row).ConsumerRow; } finally { if (dataModelTransaction != null) { ((CreditCardRow)ccMi.row).ReleaseReaderLock(dataModelTransaction.TransactionId); } } if (miConsumerRow == null) { continue; } RowLockingWrapper <ConsumerRow> consumerRowWrapper = new RowLockingWrapper <ConsumerRow>(miConsumerRow, dataModelTransaction); consumerRowWrapper.AcquireReaderLock(); if (consumerRowWrapper.Row.RowState == DataRowState.Deleted || consumerRowWrapper.Row.RowState == DataRowState.Detached) { consumerRowWrapper.ReleaseReaderLock(); continue; } try { MatchInfo ccSsnMi = socialMatcher.Validate(ssnNum, consumerRowWrapper, dataModelTransaction); MatchInfo ccLnMi = this.lastNameMatcher.Validate(lastName, consumerRowWrapper, dataModelTransaction); MatchResult mr = new MatchResult(consumerRowToFind.TypedRow, creditCardRowToFind.TypedRow, ccMi, ccSsnMi, ccLnMi); //if(mr.Strength < 1M) //{ mr.AddFirstNameMatchInfo(this.firstNameMatcher.Validate(consumerRowToFind.Row[this.firstNameColumn], consumerRowWrapper, dataModelTransaction)); //} if (mr.Strength >= matchThreshold) { results.Add(mr); } } finally { consumerRowWrapper.ReleaseReaderLock(); } } }
/// <summary> /// /// </summary> /// <param name="creditCardRowToFind"></param> /// <param name="consumerRowToFind"></param> /// <param name="dataModelTransaction"></param> /// <param name="matchThreshold"></param> /// <returns></returns> public List <MatchResult> FindMatch(RowLockingWrapper <CreditCardRow> creditCardRowToFind, RowLockingWrapper <ConsumerRow> consumerRowToFind, IDataModelTransaction dataModelTransaction, Decimal matchThreshold) { //check exact object ccNum; creditCardRowToFind.AcquireReaderLock(); try { ccNum = creditCardRowToFind.Row[this.creditCardColumn]; } finally { creditCardRowToFind.ReleaseReaderLock(); } object ssnNum; object lastName; consumerRowToFind.AcquireReaderLock(); try { ssnNum = consumerRowToFind.Row[this.ssnColumn]; lastName = consumerRowToFind.Row[this.lastNameColumn]; } finally { consumerRowToFind.ReleaseReaderLock(); } List <MatchResult> results = new List <MatchResult>(); //search by exact CreditCard this.SearchByExactCreditCard(creditCardRowToFind, consumerRowToFind, ccNum, ssnNum, lastName, results, dataModelTransaction, matchThreshold); //System.Diagnostics.Trace.WriteLine( // string.Format("{0} CreditCard search: {1} {2} {3}", System.Threading.Thread.CurrentThread.Name, // ccNum, ssnNum, lastName)); //System.Diagnostics.Trace.Indent(); //foreach(MatchResult mr in results) // System.Diagnostics.Trace.WriteLine(mr.ToString()); //System.Diagnostics.Trace.Unindent(); //if have a ~100% result continue? int resultIndex = 0; for (; resultIndex < results.Count; resultIndex++) { MatchResult mr = results[resultIndex]; if (mr.Strength >= 1M) { results.Sort(); return(results); } } //search by exact SSN this.SearchByExactSocialSecurity(creditCardRowToFind, consumerRowToFind, ccNum, ssnNum, lastName, results, dataModelTransaction, matchThreshold); //System.Diagnostics.Trace.WriteLine( // string.Format("{0} SSN search: {1} {2} {3}", System.Threading.Thread.CurrentThread.Name, // ccNum, ssnNum, lastName)); //System.Diagnostics.Trace.Indent(); //foreach(MatchResult mr in results) // System.Diagnostics.Trace.WriteLine(mr.ToString()); //System.Diagnostics.Trace.Unindent(); //if have a ~100% result continue? could not have an exact match here //and not have had it in the cc, but could have a high % match for (; resultIndex < results.Count; resultIndex++) { MatchResult mr = results[resultIndex]; if (mr.Strength >= 1M) { results.Sort(); return(results); } } this.SearchByProbableSocialSecurity(creditCardRowToFind, consumerRowToFind, ccNum, ssnNum, lastName, results, dataModelTransaction, matchThreshold); //System.Diagnostics.Trace.WriteLine( // string.Format("{0} Probable CreditCard search: {1} {2} {3}", System.Threading.Thread.CurrentThread.Name, // ccNum, ssnNum, lastName)); //System.Diagnostics.Trace.Indent(); //foreach(MatchResult mr in results) // System.Diagnostics.Trace.WriteLine(mr.ToString()); //System.Diagnostics.Trace.Unindent(); this.SearchByProbableCreditCard(creditCardRowToFind, consumerRowToFind, ccNum, ssnNum, lastName, results, dataModelTransaction, matchThreshold); results.Sort(); //System.Diagnostics.Trace.WriteLine( // string.Format("{0} Probable CreditCard search: {1} {2} {3}", System.Threading.Thread.CurrentThread.Name, // ccNum, ssnNum, lastName)); //System.Diagnostics.Trace.Indent(); //foreach(MatchResult mr in results) // System.Diagnostics.Trace.WriteLine(mr.ToString()); //System.Diagnostics.Trace.Unindent(); if (results.Count == 0) { return(null); } return(results); }
///// <summary> ///// searches through rows in table for probable row matches. This uses the same algo as ///// the FindProbable() but does not require storage to populate maps with Data Masking ///// </summary> ///// <param name="value">value to lookup, will be converted to storage type</param> ///// <param name="extendedStorageRow">IExtendedStorageRow (can be null) that storage can store temp info into for quicker lookup/generation</param> ///// <param name="useValidateForStrength">run validation on looked up probable rows to get a better match strength</param> ///// <returns></returns> //public Dictionary<DataRow, MatchInfo> SearchForProbableUsingDataMasks(object value, IExtendedStorageRow extendedStorageRow, bool useValidateForStrength) //{ // throw new NotImplementedException(); // //return this.storage.SearchForProbableUsingDataMasks(value, extendedStorageRow, useValidateForStrength); //} ///// <summary> ///// searches through rows in table for row matches. This uses the validate() to calculate match strength as ///// but does not require storage to populate maps with DataMasks/// </summary> ///// <param name="value"></param> ///// <returns></returns> //public List<MatchInfo> SearchForProbableUsingValidate(object value) //{ // throw new NotImplementedException(); // //return this.storage.SearchForProbableUsingValidate(value); //} /// <summary> /// validate a value against a row. This is needed because when Finding probable the strength is not as accurate as /// the validation method. /// </summary> /// <param name="value">value to validate</param> /// <param name="row">row to check value against. (using sourceColumn)</param> /// <returns></returns> public MatchInfo Validate(object value, IRowLockingWrapper targetValidationRow, IDataModelTransaction dataModelTransaction) { return(this.storage.Validate(value, targetValidationRow, dataModelTransaction)); }
/// <summary> /// find rows that might match, or match some of the value /// </summary> /// <param name="value">value to lookup, will be converted to storage type</param> /// <param name="extendedStorageRow">IExtendedStorageRow (can be null) that storage can store temp info into for quicker lookup/generation</param> /// <param name="useValidateForStrength">run validation on looked up probable rows to get a better match strength</param> /// <returns></returns> public Dictionary <IRow, MatchInfo> FindProbable(object value, IRowLockingWrapper valueDataRow, bool useValidateForStrength, IDataModelTransaction dataModelTransaction) { return(this.storage.FindProbable(value, valueDataRow, useValidateForStrength, dataModelTransaction)); }
/// <summary> /// lookup exact match for value. returns list of matches or null /// </summary> /// <param name="value">value to lookup, will be converted to storage type</param> /// <param name="extendedStorageRow">IExtendedStorageRow (can be null) that storage can store temp info into for quicker lookup/generation</param> /// <returns></returns> public List <MatchInfo> FindExact(object value, IRowLockingWrapper valueDataRow, IDataModelTransaction dataModelTransaction) { return(this.storage.FindExact(value, valueDataRow, dataModelTransaction)); }
/// <summary> /// add all the rows in the table (defined by sourceColumn.Table.Rows) to the /// Matcher /// </summary> public void AddTableRowsToMap(IDataModelTransaction dataModelTransaction) { this.storage.AddTableRowsToMap(dataModelTransaction); }
/// <summary> /// Acquires a writer lock for this record. /// </summary> /// <param name="dataModelTransaction">The transaction context for this operation.</param> //[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public virtual void AcquireWriterLock(IDataModelTransaction dataModelTransaction) { global::System.Guid transactionId = dataModelTransaction.TransactionId; try { global::System.Threading.Monitor.Enter(this.rowRoot); this.writerWaiters = (this.writerWaiters + 1); if ((this.writer != transactionId)) { int index = this._readers.BinarySearch(transactionId); if ((index >= 0)) { this._readers.RemoveAt(index); if (EventLog.IsLoggingEnabledFor(EventLog.ErrorLogLevel.Verbose)) { this._readersStackTrace.RemoveAt(index); } } for ( ; ((this.writer != global::System.Guid.Empty) || (this._readers.Count != 0)); ) { try { try { global::System.Threading.Monitor.Enter(this.writerRoot); global::System.Threading.Monitor.Exit(this.rowRoot); if (false == global::System.Threading.Monitor.Wait(this.writerRoot, this.LockTimeout)) { try { EventLog.Information("AcquireWriterLock TIMEOUT\r\n {0} Current Stack: {1} \r\n{2}", this.GetRowDebugDescription(), UnhandledExceptionHelper.GetStackString(), this.GetCurrentLockStacks(false)); } catch { } throw new FluidTrade.Core.Utilities.DeadlockException("AcquireWriterLock TIMEOUT", null); } } finally { global::System.Threading.Monitor.Exit(this.writerRoot); } } finally { global::System.Threading.Monitor.Enter(this.rowRoot); } } this.writer = transactionId; } } finally { this.writerWaiters = (this.writerWaiters - 1); global::System.Threading.Monitor.Exit(this.rowRoot); } dataModelTransaction.AddLock(this); if ((this.RowState == global::System.Data.DataRowState.Detached)) { throw new global::System.Exception("The " + this.GetType().FullName + " record was deleted after it was locked"); } }
public RowLockingWrapper(TRow row, IDataModelTransaction dataModelTransaction) { this.row = row; this.dataModelTransaction = dataModelTransaction; }