/// <summary> /// Creates a LabelFile object. /// </summary> /// <param name="CollectionName">Name of collection.</param> /// <param name="TimeoutMilliseconds">Timeout, in milliseconds, to wait for access to the database layer.</param> /// <param name="Encrypted">If the files should be encrypted or not.</param> /// <param name="Provider">Reference to the files provider.</param> /// <returns>LabelFile object.</returns> public static async Task <LabelFile> Create(string CollectionName, int TimeoutMilliseconds, bool Encrypted, FilesProvider Provider) { string FileName = Provider.GetFileName(CollectionName); string LabelsFileName = FileName + ".labels"; bool LabelsExists = File.Exists(LabelsFileName); LabelFile Result = new LabelFile(LabelsFileName, CollectionName, TimeoutMilliseconds, Encrypted); uint LastCode = 0; uint Code = 1; await GetKeys(Result, Provider); if (LabelsExists) { long Len = await Result.GetLength(); long Pos = 0; while (Pos < Len) { try { KeyValuePair <string, long> P = await Result.ReadLabel(Pos); Result.codesByLabel[P.Key] = Code; Result.labelsByCode[Code] = P.Key; LastCode = Code; Code++; Pos = P.Value; } catch (Exception) { await Result.Truncate(Pos); Len = Pos; } } } else { string NamesFileName = FileName + ".names"; if (File.Exists(NamesFileName)) { SortedDictionary <uint, string> NewCodes = null; using (StringDictionary Names = await StringDictionary.Create(NamesFileName, string.Empty, CollectionName, Provider, false)) { foreach (KeyValuePair <string, object> Rec in await Names.ToArrayAsync()) { if (Rec.Value is ulong Code2 && Code2 <= uint.MaxValue && !Result.labelsByCode.ContainsKey(Code = (uint)Code2)) { if (NewCodes is null) { NewCodes = new SortedDictionary <uint, string>(); } Result.codesByLabel[Rec.Key] = Code; Result.labelsByCode[Code] = Rec.Key; NewCodes[Code] = Rec.Key; } } } while (!(NewCodes is null)) { LastCode++; if (NewCodes.TryGetValue(LastCode, out string Label)) { await Result.WriteLabel(Label); NewCodes.Remove(LastCode); if (NewCodes.Count == 0) { NewCodes = null; } } else { await Result.WriteLabel(LastCode.ToString()); } } File.Delete(NamesFileName); } } return(Result); }