///// <summary> ///// ///// </summary> //private struct addword_info_t //{ // public char* wordPart; // public BaseMorphoFormNative baseMorphoForm; // public MorphoTypeNative morphoType; // public MorphoAttributePair? nounType; //} ///// добавление слова и всех его форм в словарь ///// basePtr - marshaled-слово ///// _base - слово ///// morphoType - морфотип ///// nounType - тип сущетсвительного //public void ____AddWord____( char* basePtr, MorphoTypeNative morphoType, ref MorphoAttributePair? nounType ) //{ // var baseMorphoForm = new BaseMorphoFormNative( basePtr, morphoType ); // var aw = new addword_info_t() // { // wordPart = basePtr, // baseMorphoForm = baseMorphoForm, // morphoType = morphoType, // nounType = nounType, // }; // AddWordPart( ref aw ); //} ///// добавление части слова ///// wordPart - оставшася часть слова ///// baseMorphoForm - базовая форма //private void AddWordPart( ref addword_info_t aw ) //{ // var first_char = _UPPER_INVARIANT_MAP[ *aw.wordPart ]; // if ( first_char == '\0' ) // /// сохранение характеристик // { // // sort & merge after insert - may be faster/better (30.04.2014)!!!! // //* // var len = aw.morphoType.MorphoFormEndingUpperAndMorphoAttributes.Length; // var tuples = default(SortedListIntPtrKey< pair_t[] >.tuple_t[]); // var tuplesOffset = default(int); // if ( !HasEndings() ) // { // tuplesOffset = 0; // tuples = new SortedListIntPtrKey< pair_t[] >.tuple_t[ len ]; // } // else // { // tuplesOffset = _Endings.Count; // tuples = new SortedListIntPtrKey< pair_t[] >.tuple_t[ len + tuplesOffset ]; // for ( int i = 0; i < tuplesOffset; i++ ) // { // tuples[ i ] = _Endings.Array[ i ]; // } // } // for ( int i = 0; i < len; i++ ) // { // var p = aw.morphoType.MorphoFormEndingUpperAndMorphoAttributes[ i ]; // var pairs_current_len = p.MorphoAttributes.Length; // var pairs_current = new pair_t[ pairs_current_len ]; // for ( int j = 0; j < pairs_current_len; j++ ) // { // var ma = MorphoAttributePair.GetMorphoAttribute( aw.morphoType, p.MorphoAttributes[ j ], ref aw.nounType ); // pairs_current[ j ] = new pair_t( aw.baseMorphoForm, ma ); // } // tuples[ i + tuplesOffset ] = new SortedListIntPtrKey< pair_t[] >.tuple_t() { Key = p.EndingUpper, Value = pairs_current }; // } // ShellSortAscending( tuples ); // MergeSorted ( ref tuples ); // _Endings.SetArray ( tuples ); // //*/ // #region previous-1. commented // /* // if ( !HasEndings() ) // { // _Endings = new SortedListIntPtrKey< pair_t[] >( aw.morphoType.MorphoFormEndingUpperAndMorphoAttributes.Length ); // } // for ( int i = 0, len = aw.morphoType.MorphoFormEndingUpperAndMorphoAttributes.Length; i < len; i++ ) // { // var p = aw.morphoType.MorphoFormEndingUpperAndMorphoAttributes[ i ]; // #region commented // /* // var pairs_current = from morphoAttribute in p.MorphoAttributes // let ma = MorphoAttributePair.GetMorphoAttribute( morphoType, morphoAttribute, nounType ) // select // new pair_t( baseMorphoForm, ma ); // * / // #endregion // var pairs_current_len = p.MorphoAttributes.Length; // var index = _Endings.IndexOfKeyCore( p.EndingUpper ); // if ( index < 0 ) // { // var pairs_current = new pair_t[ pairs_current_len ]; // for ( int j = 0; j < pairs_current_len; j++ ) // { // var ma = MorphoAttributePair.GetMorphoAttribute( aw.morphoType, p.MorphoAttributes[ j ], aw.nounType ); // pairs_current[ j ] = new pair_t( aw.baseMorphoForm, ma ); // } // _Endings.Insert( ~index, p.EndingUpper, pairs_current ); // } // else // { // pair_t pair_exists; // for ( int j = 0; j < pairs_current_len; j++ ) // { // var ma = MorphoAttributePair.GetMorphoAttribute( aw.morphoType, p.MorphoAttributes[ j ], aw.nounType ); // var pair = new pair_t( aw.baseMorphoForm, ma ); // if ( !tempBufferPairs.TryGetValue( pair, out pair_exists ) ) // { // tempBufferPairs.Add( pair, pair ); // } // else // { // pair_exists.BaseMorphoForm.AppendMorphoFormEndings( pair.BaseMorphoForm ); // } // } // var pairs = _Endings.GetValue( index ); // for ( int j = 0, pairs_len = pairs.Length; j < pairs_len; j++ ) // { // var pair = pairs[ j ]; // if ( !tempBufferPairs.TryGetValue( pair, out pair_exists ) ) // { // tempBufferPairs.Add( pair, pair ); // } // else // { // pair_exists.BaseMorphoForm.AppendMorphoFormEndings( pair.BaseMorphoForm ); // } // } // pairs = null; // var pairs_new = tempBufferPairs_ToArrayAndClear(); //var pairs_new = tempBufferPairs.Keys.ToArray(); // _Endings.SetValue( index, pairs_new ); // } // } // */ // #endregion // #region previous-2. commented // /* // foreach ( var morphoForm in morphoType.MorphoForms ) // { // var endingUpper_ptr = new IntPtr( morphoForm.EndingUpper ); // LinkedList< pair_t > pairs; // if ( !tempBufferDict.TryGetValue( endingUpper_ptr, out pairs ) ) // { // pairs = PopLinkedList(); // tempBufferDict.Add( endingUpper_ptr, pairs ); // } // var morphoAttribute = MorphoAttributePair.GetMorphoAttribute( morphoType, morphoForm, nounType ); // pairs.AddLast( new pair_t( baseMorphoForm, morphoAttribute ) ); // } // if ( _Endings == null ) // { // _Endings = new SortedListIntPtrKey< pair_t[] >( tempBufferDict.Count ); // } // foreach ( var p in tempBufferDict ) // { // var index = _Endings.IndexOfKeyCore( p.Key ); // if ( index < 0 ) // { // _Endings.Insert( ~index, p.Key, p.Value.ToArray() ); // } // else // { // var pairs = _Endings.GetValue( index ); // #region version.1 // //* // pair_t pair_exists; // foreach ( var pair in pairs.Concat( p.Value ) ) // { // if ( !tempBufferPairs.TryGetValue( pair, out pair_exists ) ) // { // tempBufferPairs.Add( pair, pair ); // } // else // { // pair_exists.BaseMorphoForm.AppendMorphoFormEndings( pair.BaseMorphoForm ); // } // } // var pairs_new = tempBufferPairs.Keys.ToArray(); // _Endings.SetValue( index, pairs_new ); // tempBufferPairs.Clear(); // //* / // #endregion // #region version.2 // /* // var groups = pairs.Concat( p.Value ).GroupBy( _p => _p, pair_t_IEqualityComparer.Inst ); // var pairs_new = groups.Select( _g => // { // _g.Key.BaseMorphoForm.SetMorphoFormEndings( _g.Select( _p => _p.BaseMorphoForm ) ); // return (_g.Key); // }) // .ToArray(); // _Endings.SetValue( index, pairs_new ); // //* / // #endregion // } // PushLinkedList( p.Value ); // } // tempBufferDict.Clear(); // */ // #endregion // #region direct. commented // /* // if ( _Endings == null ) // { // _Endings = new SortedListIntPtrKey< pair_t[] >( DEFAULT_ENDINGS_CAPACITY ); // } // foreach ( var morphoForm in morphoType.MorphoForms ) // { // var morphoAttribute = MorphoAttributePair.GetMorphoAttribute( baseMorphoForm, morphoType, morphoForm, nounType ); // var pair = new pair_t( baseMorphoForm, morphoAttribute ); // pair_t[] pairs; // var endingUpper_ptr = new IntPtr( morphoForm.EndingUpper ); // if ( !_Endings.TryGetValue( endingUpper_ptr, out pairs ) ) // { // _Endings.Add( endingUpper_ptr, new[] { pair } ); // } // else // { // _Endings[ endingUpper_ptr ] = pairs.Concat( Enumerable.Repeat( pair, 1 ) ).ToArray(); // } // } // */ // #endregion // } // else // { // TreeDictionaryNative value; // if ( !_Slots.TryGetValue( first_char, out value ) ) // { // /// добавление новой буквы // value = new TreeDictionaryNative(); // _Slots.Add( first_char, value ); // } // aw.wordPart++; // value.AddWordPart( ref aw ); // } //} #endregion private static void ShellSortAscending(SortedListIntPtrKey <pair[]> .Tuple[] array) { for (int arrayLength = array.Length, gap = (arrayLength >> 1); 0 < gap; gap = (gap >> 1)) { for (int i = 0, len = arrayLength - gap; i < len; i++) //modified insertion sort { int j = i + gap; SortedListIntPtrKey <pair[]> .Tuple tmp = array[j]; while (gap <= j /*&& (CompareRoutine( tmp.Key, array[ j - gap ].Key ) < 0)*/ /*(tmp < array[ j - gap ])*/) { var k = j - gap; var t = array[k]; if (0 <= SortedListIntPtrKey <pair[]> .CompareRoutine(tmp.Key, t.Key)) { break; } array[j] = t; j = k; } array[j] = tmp; } } }
private static void MergeSorted(ref SortedListIntPtrKey <pair[]> .Tuple[] array) { var emptyCount = 0; var i_prev = 0; var t_prev = array[0]; var arrayLength = array.Length; var pair_exists = default(pair); for (int i = 1; i < arrayLength; i++) { var t_curr = array[i]; //comparing native-strings, given that duplicates have the same addresses if (t_prev.Key == t_curr.Key) /*full comparing native-strings (same addresses & char-to-char compare)*/ /*if ( SortedListIntPtrKey< pair_t[] >.CompareRoutine( t_prev.Key, t_curr.Key ) == 0 )*/ { array[i].Key = IntPtr.Zero; emptyCount++; var pairs = t_curr.Value; for (int j = 0, ln = pairs.Length; j < ln; j++) { var pair = pairs[j]; if (!tempBufferPairs.TryAddOrGetExists(pair, ref pair_exists)) { pair_exists.BaseMorphoForm.AppendMorphoFormEndings(pair.BaseMorphoForm); } } pairs = t_prev.Value; for (int j = 0, ln = pairs.Length; j < ln; j++) { var pair = pairs[j]; if (!tempBufferPairs.TryAddOrGetExists(pair, ref pair_exists)) { pair_exists.BaseMorphoForm.AppendMorphoFormEndings(pair.BaseMorphoForm); } } var pairs_new = tempBufferPairs_ToArrayAndClear(); array[i_prev].Value = pairs_new; } else { t_prev = t_curr; i_prev = i; } } if (emptyCount != 0) { var array_new = new SortedListIntPtrKey <pair[]> .Tuple[arrayLength - emptyCount]; for (int i = 0, j = 0; i < arrayLength; i++) { var t_curr = array[i]; if (t_curr.Key != IntPtr.Zero) { array_new[j++] = t_curr; } } array = array_new; } }
/// добавление слова и всех его форм в словарь /// wordBase - marshaled-слово /// morphoType - морфотип /// nounType - тип сущетсвительного public void AddWord(char *wordBase, MorphoTypeNative morphoType, ref MorphoAttributePair?nounType) { var baseMorphoForm = new BaseMorphoFormNative(wordBase, morphoType); for (TreeDictionaryNative _this = this, _this_next; ;) { var first_char = _UPPER_INVARIANT_MAP[*wordBase]; #region [.сохранение характеристик if end-of-word.] if (first_char == '\0') { // sort & merge after insert - may be faster/better (30.04.2014)!!!! //* var len = morphoType.MorphoFormEndingUpperAndMorphoAttributes.Length; SortedListIntPtrKey <pair[]> .Tuple[] tuples; int tuplesOffset; if (!_this.HasEndings()) { tuplesOffset = 0; tuples = new SortedListIntPtrKey <pair[]> .Tuple[len]; } else { tuplesOffset = _this._Endings.Count; tuples = new SortedListIntPtrKey <pair[]> .Tuple[len + tuplesOffset]; for (int i = 0; i < tuplesOffset; i++) { tuples[i] = _this._Endings.Array[i]; } } for (int i = 0; i < len; i++) { var p = morphoType.MorphoFormEndingUpperAndMorphoAttributes[i]; var pairs_current_len = p.MorphoAttributes.Length; var pairs_current = new pair[pairs_current_len]; for (int j = 0; j < pairs_current_len; j++) { var ma = MorphoAttributePair.GetMorphoAttribute(morphoType, p.MorphoAttributes[j], ref nounType); pairs_current[j] = new pair(baseMorphoForm, ma); } tuples[i + tuplesOffset] = new SortedListIntPtrKey <pair[]> .Tuple() { Key = p.EndingUpper, Value = pairs_current }; } ShellSortAscending(tuples); MergeSorted(ref tuples); _this._Endings.SetArray(tuples); //*/ return; } #endregion if (!_this._Slots.TryGetValue(first_char, out _this_next)) { /// добавление новой буквы _this_next = new TreeDictionaryNative(); _this._Slots.Add(first_char, _this_next); } _this = _this_next; wordBase++; } }