예제 #1
0
        /// <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);
        }