private IEnumerable <PartitionDate> LatestPartitionVersions(string defaultPath) { var di = new DirectoryInfo(defaultPath); var subDirs = di.EnumerateDirectories().Select(d => d.Name).OrderBy(s => s); PartitionDate?lastDate = null; foreach (var subDir in subDirs) { if (!subDir.StartsWith(MetadataConstants.TEMP_DIRECTORY_PREFIX)) { var dateFromName = PartitionManagerUtils.ParseDateFromDirName(subDir, _settings.PartitionType); var fullPath = Path.Combine(defaultPath, subDir); if (dateFromName.HasValue) { if (lastDate.HasValue && !lastDate.Value.Date.Equals(dateFromName.Value.Date)) { yield return(lastDate.Value); } lastDate = dateFromName; } else { Trace.TraceWarning("Invalid directory '{0}' for partition type '{1}'. " + "Will be ignored.", fullPath, _settings.PartitionType); } } } if (lastDate.HasValue) { yield return(lastDate.Value); } }
private IPartition GetAppendPartition0(DateTime dateTime, ITransactionContext tx) { if (tx.LastAppendTimestamp > dateTime) { throw new NFSdbInvalidAppendException( "Journal {0}. Attempt to insert a record out of order." + " Record with timestamp {1} cannot be inserted when" + " the last appended record's timestamp is {2}", _metadata.Settings.DefaultPath, dateTime, tx.LastAppendTimestamp); } int lastPartitionID; // 0 partition index / ID is symobol partition. if (tx.Partitions.Count > 1) { var lastPart = tx.Partitions.LastNotNull(); lastPartitionID = lastPart.PartitionID; if (lastPart.IsInsidePartition(dateTime)) { SwitchWritePartitionTo(tx, lastPart.PartitionID); return(lastPart); } } else { lastPartitionID = 0; } ClearPartitionsAfter(lastPartitionID, tx); lastPartitionID++; var startDate = PartitionManagerUtils.GetPartitionStartDate(dateTime, _metadata.Settings.PartitionType); var dirName = PartitionManagerUtils.GetPartitionDirName(dateTime, _metadata.Settings.PartitionType); var paritionDir = Path.Combine(_metadata.Settings.DefaultPath, dirName); // 0 reserved for symbols. var partition = CreateNewParition( new PartitionDate(startDate, 0, _settings.PartitionType), lastPartitionID, paritionDir, null); var lazy = new Lazy <IPartition>(() => partition); _partitions[startDate] = lazy; // Force create lazy value. tx.AddPartition(lazy.Value); SwitchWritePartitionTo(tx, lastPartitionID); return(partition); }
public Partition(IJournalMetadata metadata, ICompositeFileFactory memeorymMappedFileFactory, EFileAccess access, PartitionDate partitionDate, int partitionID, string path, IJournalServer journalServer, PartitionConfig config = null) { _memeorymMappedFileFactory = memeorymMappedFileFactory; _access = access; _journalServer = journalServer; _config = config; _metadata = metadata; _partitionDate = partitionDate; EndDate = PartitionManagerUtils.GetPartitionEndDate( partitionDate.Date, partitionDate.PartitionType); PartitionID = partitionID; DirectoryPath = path; }
private void ReconcilePartitionsWithTxRec(List <IPartition> partitions, TxRec txRec) { partitions.Clear(); var defaultPath = _settings.DefaultPath; // Symbols are the partition 0. partitions.Add(null); var nextPartitionID = 1; var subDirs = LatestPartitionVersions(defaultPath); foreach (var subDir in subDirs) { var fullPath = Path.Combine(defaultPath, subDir.Name); var startDate = subDir.Date; var partitionDir = subDir; PartitionConfig config = PartitionManagerUtils.ReadPartitionConfig(fullPath); if (config != null) { nextPartitionID = config.PartitionID; } if (txRec.IsCommited(startDate, nextPartitionID)) { var partitionID = nextPartitionID; var partition = _partitions.AddOrUpdate(startDate, // Add. sd => { var p = new Lazy <IPartition>(() => CreateNewParition(partitionDir, partitionID, fullPath, config)); if (config == null && Access == EFileAccess.ReadWrite) { p.Value.SaveConfig(); } return(p); }, // Update. (sd, existing) => { if (existing.Value.Version == subDir.Version) { return(existing); } existing.Value.MarkOverwritten(); var p = new Lazy <IPartition>(() => CreateNewParition(partitionDir, partitionID, fullPath, config)); if (config == null && Access == EFileAccess.ReadWrite) { p.Value.SaveConfig(); } return(p); }); partitions.SetToIndex(partitionID, partition.Value); nextPartitionID++; } else { Trace.TraceInformation( "Ignoring directory '{0}' for partition type '{1}' as fully rolled back partition.", fullPath, _settings.PartitionType); Lazy <IPartition> existingPartition; if (_partitions.TryRemove(startDate, out existingPartition)) { if (existingPartition.IsValueCreated) { existingPartition.Value.Dispose(); } } } } }