|
3 | 3 | using System; |
4 | 4 | using System.IO; |
5 | 5 | using System.Threading; |
| 6 | +#nullable enable |
6 | 7 |
|
7 | 8 | namespace Lucene.Net.Store |
8 | 9 | { |
@@ -56,7 +57,7 @@ private void CheckCrashed() |
56 | 57 | } |
57 | 58 | } |
58 | 59 |
|
59 | | - private void CheckDiskFull(byte[] b, int offset, DataInput @in, long len) |
| 60 | + private void CheckDiskFull(byte[]? b, int offset, DataInput? @in, long len) |
60 | 61 | { |
61 | 62 | long freeSpace = dir.maxSize == 0 ? 0 : dir.maxSize - dir.GetSizeInBytes(); |
62 | 63 | long realUsage = 0; |
@@ -103,6 +104,48 @@ private void CheckDiskFull(byte[] b, int offset, DataInput @in, long len) |
103 | 104 | } |
104 | 105 | } |
105 | 106 |
|
| 107 | + // LUCENENET specific overload |
| 108 | + private void CheckDiskFull(ReadOnlySpan<byte> source) |
| 109 | + { |
| 110 | + long len = source.Length; |
| 111 | + long freeSpace = dir.maxSize == 0 ? 0 : dir.maxSize - dir.GetSizeInBytes(); |
| 112 | + long realUsage = 0; |
| 113 | + |
| 114 | + // Enforce disk full: |
| 115 | + if (dir.maxSize != 0 && freeSpace <= len) |
| 116 | + { |
| 117 | + // Compute the real disk free. this will greatly slow |
| 118 | + // down our test but makes it more accurate: |
| 119 | + realUsage = dir.GetRecomputedActualSizeInBytes(); |
| 120 | + freeSpace = dir.maxSize - realUsage; |
| 121 | + } |
| 122 | + |
| 123 | + if (dir.maxSize != 0 && freeSpace <= len) |
| 124 | + { |
| 125 | + if (freeSpace > 0) |
| 126 | + { |
| 127 | + realUsage += freeSpace; |
| 128 | + @delegate.WriteBytes(source.Slice(/*offset*/ 0, (int)freeSpace)); |
| 129 | + } |
| 130 | + if (realUsage > dir.maxUsedSize) |
| 131 | + { |
| 132 | + dir.maxUsedSize = realUsage; |
| 133 | + } |
| 134 | + string message = "fake disk full at " + dir.GetRecomputedActualSizeInBytes() + " bytes when writing " + name + " (file length=" + @delegate.Length; |
| 135 | + if (freeSpace > 0) |
| 136 | + { |
| 137 | + message += "; wrote " + freeSpace + " of " + len + " bytes"; |
| 138 | + } |
| 139 | + message += ")"; |
| 140 | + if (LuceneTestCase.Verbose) |
| 141 | + { |
| 142 | + Console.WriteLine(Thread.CurrentThread.Name + ": MDW: now throw fake disk full"); |
| 143 | + StackTraceHelper.PrintCurrentStackTrace(Console.Out); |
| 144 | + } |
| 145 | + throw new IOException(message); |
| 146 | + } |
| 147 | + } |
| 148 | + |
106 | 149 | protected override void Dispose(bool disposing) |
107 | 150 | { |
108 | 151 | if (disposing) |
@@ -141,6 +184,9 @@ public override void WriteByte(byte b) |
141 | 184 | WriteBytes(singleByte, 0, 1); |
142 | 185 | } |
143 | 186 |
|
| 187 | + // LUCENENET: For performance reasons, it is better to keep this duplication, for now. |
| 188 | + // At least until we have migrated many of the callers to call the ReadOnlySpan<char> overload |
| 189 | + // directly. |
144 | 190 | public override void WriteBytes(byte[] b, int offset, int len) |
145 | 191 | { |
146 | 192 | CheckCrashed(); |
@@ -169,6 +215,39 @@ public override void WriteBytes(byte[] b, int offset, int len) |
169 | 215 | } |
170 | 216 | } |
171 | 217 |
|
| 218 | + // LUCENENET: Use ReadOnlySpan<byte> instead of byte[] for better compatibility. |
| 219 | + public override void WriteBytes(ReadOnlySpan<byte> source) |
| 220 | + { |
| 221 | + int len = source.Length; |
| 222 | + CheckCrashed(); |
| 223 | + CheckDiskFull(source); |
| 224 | + |
| 225 | + if (dir.randomState.Next(200) == 0) |
| 226 | + { |
| 227 | + int half = len / 2; |
| 228 | + //@delegate.WriteBytes(b, offset, half); |
| 229 | + @delegate.WriteBytes(source.Slice(/*offset*/ 0, half)); |
| 230 | + Thread.Yield(); |
| 231 | + //@delegate.WriteBytes(b, offset + half, len - half); |
| 232 | + @delegate.WriteBytes(source.Slice(/*offset +*/ half, len - half)); |
| 233 | + } |
| 234 | + else |
| 235 | + { |
| 236 | + //@delegate.WriteBytes(b, offset, len); |
| 237 | + @delegate.WriteBytes(source); |
| 238 | + } |
| 239 | + |
| 240 | + dir.MaybeThrowDeterministicException(); |
| 241 | + |
| 242 | + if (first) |
| 243 | + { |
| 244 | + // Maybe throw random exception; only do this on first |
| 245 | + // write to a new file: |
| 246 | + first = false; |
| 247 | + dir.MaybeThrowIOException(name); |
| 248 | + } |
| 249 | + } |
| 250 | + |
172 | 251 | public override long Position => @delegate.Position; // LUCENENET specific: Renamed from getFilePointer() to match FileStream |
173 | 252 |
|
174 | 253 | [Obsolete("(4.1) this method will be removed in Lucene 5.0")] |
|
0 commit comments