///<summary>ファイル2個をマージするやつ</summary> static void MargeSortUnit(long SortMask, string InputPathA, string InputPathB, string OutputPath) { using (BufferedLongWriter writer = new BufferedLongWriter(OutputPath)) using (BufferedLongReader readerA = new BufferedLongReader(InputPathA)) using (BufferedLongReader readerB = new BufferedLongReader(InputPathB)) { //2つのファイルを並行して読んでいく //残りの書込回数をこれで数える(境界条件対策 long restA = readerA.Length / sizeof(long), restB = readerB.Length / sizeof(long); long lastA = 0, lastB = 0, maskedA = 0, maskedB = 0; void ReadA() { if (readerA.Readable()) { lastA = readerA.Read(); maskedA = lastA & SortMask; } else { maskedA = long.MaxValue; } //maskされてないMax→もう読めない } void ReadB() { if (readerB.Readable()) { lastB = readerB.Read(); maskedB = lastB & SortMask; } else { maskedB = long.MaxValue; } //maskされてないMax→もう読めない } ReadA(); ReadB(); do { if (maskedA < maskedB) { writer.Write(lastA); ReadA(); restA--; } else { writer.Write(lastB); ReadB(); restB--; } } while (restA > 0 || restB > 0); } //終わったら古いやつは消す File.Delete(InputPathA); File.Delete(InputPathB); }
///<summary>ブロックソートで一致する範囲だけ読み出す ///長さ2以上になるやつだけ返す</summary> public long[] ReadBlock() { long TempHash; do { TempList.Clear(); if (HasExtraHash) { TempHash = ExtraReadHash; HasExtraHash = false; } else if (reader.Readable()) { TempHash = reader.Read(); } else { return(null); } TempList.Add(TempHash); //MaskしたやつがMaskedKeyと一致しなかったら終了 long MaskedKey = TempHash & FullMask; while (reader.Readable()) { TempHash = reader.Read(); if ((TempHash & FullMask) == MaskedKey) { TempList.Add(TempHash); } //1個余計に読んだので記録しておく else { ExtraReadHash = TempHash; HasExtraHash = true; break; } } } while (TempList.Count < 2); return(TempList.ToArray()); }