public bool Create(ushort[] fields) { uint i; if (fields == null) { return(false); } DBFTable parent = _parent; if (fields.Any(m => m > parent.Header.Field.Length)) { return(false); } Clear(); _indexFields = fields; _items = new DBFIndexItem[_parent.Record.Length]; var tempIndex = new DBFIndexItem[_parent.Record.Length]; for (i = 0; i < _parent.Record.Length; i++) { _items[i].RecNum = i; string sKey = string.Empty; // ReSharper disable LoopCanBeConvertedToQuery foreach (int m in fields) { sKey = sKey + _parent.Record[i].Field[m]; } // ReSharper restore LoopCanBeConvertedToQuery // ReSharper disable ConvertIfStatementToConditionalTernaryExpression if (DBFIndexItem.ItemHandler == null) { _items[i].Key = sKey; } // ReSharper restore ConvertIfStatementToConditionalTernaryExpression else { _items[i].Key = DBFIndexItem.ItemHandler(sKey); //""; } } //первичная сортировка for (i = 0; i < _items.Length - 1; i += 2) { if (_items[i].Key == _items[i + 1].Key) { tempIndex[i] = _items[i]; tempIndex[i + 1] = _items[i + 1]; } else { tempIndex[i] = _items[i + 1]; tempIndex[i + 1] = _items[i]; } } if (i < _items.Length) { tempIndex[i] = _items[i]; } //инициализация DBFIndexItem[] pa = tempIndex; DBFIndexItem[] pb = _items; uint blockSize = 2; //основная сортировка while (blockSize < _items.Length) //perform while block size are less then array size { i = 0; //setting base itemses for left block uint k = 0; while (i < _items.Length) { uint j; if ((i + blockSize) >= _items.Length) { for (j = 0; j < (_items.Length - i); j++) { pb[k + j] = pa[i + j]; } k += (uint)(_items.Length - i); break; } uint lSize = blockSize; uint rSize; if ((i + blockSize + blockSize) < _items.Length) { rSize = blockSize; } else { rSize = (uint)(_items.Length - i - blockSize); //set length of right block } j = i + lSize; //set base items for right block while ((lSize > 0) && (rSize > 0)) //starting merging of blocks { if (pa[i].Key.CompareTo(pa[j].Key) <= 0) { pb[k] = pa[i]; i++; lSize--; } else { pb[k] = pa[j]; j++; rSize--; } k++; } if (rSize == 0) { for (uint t = 0; t < lSize; t++) { pb[k + t] = pa[i + t]; } i += lSize; k += lSize; } if (lSize == 0) { for (uint t = 0; t < rSize; t++) { pb[k + t] = pa[j + t]; } j += rSize; k += rSize; } i += blockSize; } blockSize *= 2; //double size of block var cb = pb; pb = pa; pa = cb; //switch input and output arrays } //if( _items != pa ) _items = pa; return(true); }
public bool Create( ushort[] fields ) { uint i; if( fields == null ) return false; DBFTable parent = _parent; if (fields.Any(m => m > parent.Header.Field.Length)) return false; Clear(); _indexFields = fields; _items = new DBFIndexItem[_parent.Record.Length]; var tempIndex = new DBFIndexItem[_parent.Record.Length]; for( i = 0; i < _parent.Record.Length; i++ ) { _items[i].RecNum = i; string sKey = string.Empty; // ReSharper disable LoopCanBeConvertedToQuery foreach( int m in fields ) sKey = sKey + _parent.Record[i].Field[m]; // ReSharper restore LoopCanBeConvertedToQuery // ReSharper disable ConvertIfStatementToConditionalTernaryExpression if( DBFIndexItem.ItemHandler == null ) _items[i].Key = sKey; // ReSharper restore ConvertIfStatementToConditionalTernaryExpression else _items[i].Key = DBFIndexItem.ItemHandler(sKey);//""; } //первичная сортировка for( i = 0; i < _items.Length - 1; i += 2 ) if( _items[i].Key == _items[i + 1].Key ) { tempIndex[i] = _items[i]; tempIndex[i + 1] = _items[i + 1]; } else { tempIndex[i] = _items[i + 1]; tempIndex[i + 1] = _items[i]; } if( i < _items.Length ) tempIndex[i] = _items[i]; //инициализация DBFIndexItem[] pa = tempIndex; DBFIndexItem[] pb = _items; uint blockSize = 2; //основная сортировка while( blockSize < _items.Length ) //perform while block size are less then array size { i = 0; //setting base itemses for left block uint k = 0; while( i < _items.Length ) { uint j; if( (i + blockSize) >= _items.Length ) { for( j = 0; j < (_items.Length - i); j++ ) pb[k + j] = pa[i + j]; k += (uint)(_items.Length - i); break; } uint lSize = blockSize; uint rSize; if( (i + blockSize + blockSize) < _items.Length ) rSize = blockSize; else rSize = (uint)(_items.Length - i - blockSize); //set length of right block j = i + lSize; //set base items for right block while( (lSize > 0) && (rSize > 0) ) //starting merging of blocks { if( pa[i].Key.CompareTo(pa[j].Key) <= 0 ) { pb[k] = pa[i]; i++; lSize--; } else { pb[k] = pa[j]; j++; rSize--; } k++; } if( rSize == 0 ) { for( uint t = 0; t < lSize; t++ ) pb[k + t] = pa[i + t]; i += lSize; k += lSize; } if( lSize == 0 ) { for( uint t = 0; t < rSize; t++ ) pb[k + t] = pa[j + t]; j += rSize; k += rSize; } i += blockSize; } blockSize *= 2; //double size of block var cb = pb; pb = pa; pa = cb; //switch input and output arrays } //if( _items != pa ) _items = pa; return true; }