public void UpdateDataFromSources(IList <string> sourceList, DimensionSet sourceDimensions,
                                          KeyedDataStore <TInternal> sourceData)
        {
            if (this.Sealed)
            {
                throw new InvalidOperationException("Attempt to write to sealed bucket.");
            }

            foreach (var s in sourceList)
            {
                // Below we do some sanity checking to make sure that we're not ingesting data we were already given,
                // or ingesting data from a source that wasn't pre-declared as an input. Either of these would indicate
                // an upstream logic fault.
                var source = this.FindSource(s);
                if (source == null)
                {
                    throw new InvalidOperationException("Adding data from previously unknown source " + s);
                }

                if (source.Status != PersistedDataSourceStatus.Unknown)
                {
                    throw new InvalidOperationException("Double adding data from source " + s);
                }

                source.Status = PersistedDataSourceStatus.Available;
            }

            using (SharedLock.OpenExclusive(this.dataAccessLock))
            {
                this.Load();
                if (this.data == null || this.data.Empty)
                {
                    this.DimensionSet = sourceDimensions;
                    this.data         = sourceData;
                }
                else
                {
                    this.data.TakeData(sourceData);
                    sourceData.Dispose();
                }

                this.dirty = true;
            }
        }
        private void ReadFromStorage(string filename, bool sourcesOnly)
        {
            KeyedDataStore <TInternal> readData = null;

            try
            {
                Events.Write.BeginLoadingData(filename);
                using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    using (var reader = new PersistedDataReader(stream, this.memoryStreamManager, this.DimensionSet))
                    {
                        // We'll only ever write one set of data, so we only try to read one.
                        if (reader.ReadDataHeader())
                        {
                            this.MergeSourceStatus(reader.Header.Sources);

                            if (sourcesOnly)
                            {
                                return;
                            }

                            if (typeof(TInternal) != reader.DataType)
                            {
                                throw new InvalidDataException(
                                          string.Format(
                                              "this.start={0},this.end={1}, hdr.start={2}, hdr.end={3}, this.type={4}, hdr.type={5}",
                                              this.StartTicks, this.EndTicks, reader.StartTime.Ticks,
                                              reader.EndTime.Ticks,
                                              typeof(TInternal), reader.DataType));
                            }

                            readData = reader.LoadData <TInternal>();
                            if (this.DimensionSet.Equals(reader.DimensionSet) &&
                                (this.data == null || this.data.Empty))
                            {
                                this.DimensionSet = reader.DimensionSet;
                                if (this.data != null)
                                {
                                    this.data.Dispose();
                                }
                                this.data = readData;
                                readData  = null;
                            }
                            else
                            {
                                if (this.data == null)
                                {
                                    this.data = new KeyedDataStore <TInternal>(this.DimensionSet,
                                                                               this.memoryStreamManager,
                                                                               "read data");
                                }
                                this.data.TakeData(readData);
                                this.data.Merge();
                            }
                        }
                    }
                }
            }
            catch (FileNotFoundException)
            {
                Events.Write.SealedDataFileMissing(filename);
            }
            catch (PersistedDataException ex)
            {
                Events.Write.PersistedDataException(ex);
                Events.Write.DiscardingIncompleteData(filename);
                if (this.data != null)
                {
                    this.data.Dispose();
                }
                this.data = null;
            }
            catch (OutOfMemoryException)
            {
                // TODO: this code is here to deal with file corruption issues, once checksums have been added and
                // are fully available it must be removed.
                File.Delete(filename);
                throw;
            }
            finally
            {
                if (readData != null)
                {
                    readData.Dispose();
                }
            }

            // if data is still null, some error happened loading the file (empty, missing, corrupt).
            // Just start over with clean data.
            if (this.data == null)
            {
                if (File.Exists(this.Filename))
                {
                    File.Delete(this.Filename);
                }

                this.data = new KeyedDataStore <TInternal>(this.DimensionSet, this.memoryStreamManager,
                                                           "placeholder for invalid data.");
            }

            Events.Write.EndLoadingData(filename);
        }