Пример #1
0
            // The IDF that is adding data to this spill file calls Append to add some more. Each
            // call to Append is accompanied by a completion handler that will be called once the
            // appended data has been written to disk.
            void Append(byte[] data, Cache.IAppendCompletion completion)
            {
                // This will be a count of the bytes written out of the data array
                Int64 written = 0;

                while (written < data.LongLength)
                {
                    if (bufferedData == null) // no data is currently buffered to write
                    {
                        if (written == 0 && data.LongLength == writeBlockSize)
                        {
                            // fast path, write straight through without copying the buffer.
                            // This is used when spilling large, previously-cached IDFs as fast as
                            // possible, for which the client uses the WriteBlockSize property to match
                            // the Append calls to the buffer size.
                            bufferedData             = new SpillBlock(data);
                            written                  = data.LongLength;
                            bufferedData.validLength = data.LongLength;
                        }
                        else
                        {
                            // make a new buffer for writing
                            bufferedData = new SpillBlock(writeBlockSize);
                        }

                        bufferedCompletions = new List <Cache.IAppendCompletion>();
                    }

                    // Copy some data into the buffer
                    Int64 space   = bufferedData.data.LongLength - bufferedData.validLength;
                    Int64 needed  = data.LongLength - written;
                    Int64 toWrite = Math.Max(needed, space);
                    Array.Copy(data, written, bufferedData.data, bufferedData.validLength, toWrite);
                    written += toWrite;
                    bufferedData.validLength += toWrite;

                    if (bufferedData.validLength == bufferedData.data.LongLength)
                    { // the buffer is full---time to write it to disk
                        if (written == data.LongLength)
                        {
                            // this happens to coincide with finishing the append, so attach
                            // the completion. Otherwise the completion will be attached to a
                            // subsequent buffer, so it doesn't get called until the entire
                            // append block has been written out
                            bufferedCompletions.Add(completion);
                        }

                        // Send bufferedData to the disk, and reset it to null
                        QueueWrite();
                    }
                }

                // We have written out all the data now
                if (bufferedCompletions != null)
                {
                    // The buffer wasn't sent out at the end of the loop, so add
                    // our completion to the partially-written buffer, waiting for
                    // it to get written our in a subsequent Append or Flush.
                    bufferedCompletions.Add(completion);
                }

                // Record the amount of data we appended in this call
                bytesAppended += data.LongLength;
            }
Пример #2
0
 // Enqueue an async write of the data currently being buffered, then zero out the buffer in
 // preparation for more appends
 private void QueueWrite()
 {
     handle.BeginWrite(bufferedData.data, 0, (int)bufferedData.validLength, WriteComplete, bufferedCompletions);
     bufferedData = null;
     bufferedCompletions = null;
 }
Пример #3
0
 // Enqueue an async write of the data currently being buffered, then zero out the buffer in
 // preparation for more appends
 private void QueueWrite()
 {
     handle.BeginWrite(bufferedData.data, 0, (int)bufferedData.validLength, WriteComplete, bufferedCompletions);
     bufferedData        = null;
     bufferedCompletions = null;
 }
Пример #4
0
            // The IDF that is adding data to this spill file calls Append to add some more. Each
            // call to Append is accompanied by a completion handler that will be called once the
            // appended data has been written to disk.
            void Append(byte[] data, Cache.IAppendCompletion completion)
            {
                // This will be a count of the bytes written out of the data array
                Int64 written = 0;
                while (written < data.LongLength)
                {
                    if (bufferedData == null) // no data is currently buffered to write
                    {
                        if (written == 0 && data.LongLength == writeBlockSize)
                        {
                            // fast path, write straight through without copying the buffer.
                            // This is used when spilling large, previously-cached IDFs as fast as
                            // possible, for which the client uses the WriteBlockSize property to match
                            // the Append calls to the buffer size.
                            bufferedData = new SpillBlock(data);
                            written = data.LongLength;
                            bufferedData.validLength = data.LongLength;
                        }
                        else
                        {
                            // make a new buffer for writing
                            bufferedData = new SpillBlock(writeBlockSize);
                        }

                        bufferedCompletions = new List<Cache.IAppendCompletion>();
                    }

                    // Copy some data into the buffer
                    Int64 space = bufferedData.data.LongLength - bufferedData.validLength;
                    Int64 needed = data.LongLength - written;
                    Int64 toWrite = Math.Max(needed, space);
                    Array.Copy(data, written, bufferedData.data, bufferedData.validLength, toWrite);
                    written += toWrite;
                    bufferedData.validLength += toWrite;

                    if (bufferedData.validLength == bufferedData.data.LongLength)
                    { // the buffer is full---time to write it to disk
                        if (written == data.LongLength)
                        {
                            // this happens to coincide with finishing the append, so attach
                            // the completion. Otherwise the completion will be attached to a
                            // subsequent buffer, so it doesn't get called until the entire 
                            // append block has been written out
                            bufferedCompletions.Add(completion);
                        }

                        // Send bufferedData to the disk, and reset it to null
                        QueueWrite();
                    }
                }

                // We have written out all the data now
                if (bufferedCompletions != null)
                {
                    // The buffer wasn't sent out at the end of the loop, so add
                    // our completion to the partially-written buffer, waiting for
                    // it to get written our in a subsequent Append or Flush.
                    bufferedCompletions.Add(completion);
                }

                // Record the amount of data we appended in this call
                bytesAppended += data.LongLength;
            }