Exemple #1
0
 private ReadOnlySpan <char> AppendNewline(ReadOnlySpan <char> chars)
 {
     m_buffer.Clear();
     m_buffer.Fill(chars.Length + Environment.NewLine.Length, default);
     chars.CopyTo(m_buffer.AsSpan());
     Environment.NewLine.AsSpan().CopyTo(m_buffer.AsSpan().Slice(chars.Length));
     return(m_buffer.AsSpan());
 }
Exemple #2
0
        /// <summary>
        /// Load from file.
        /// </summary>
        public override void LoadFromFile(string directory, string name)
        {
            Offsets.Clear();
            MultiValues.Clear();

            base.LoadFromFile(directory, name);

            FileSpanUtilities.LoadFromFile(directory, InsertSuffix(name, "MultiValue"), MultiValues);

            Offsets.Fill(Count, default);
            CalculateOffsets();
        }
Exemple #3
0
        /// <summary>
        /// Load a list of unmanaged values from the given filename in the given directory.
        /// </summary>
        public static void LoadFromFile <TValue>(string directory, string name, SpannableList <TValue> values)
            where TValue : unmanaged
        {
            values.Clear();

            string path = Path.Combine(directory, name);

            using (Stream reader = File.OpenRead(path))
            {
                int[] lengthBuf = new int[1];
                reader.Read(MemoryMarshal.Cast <int, byte>(new Span <int>(lengthBuf)));
                int length = lengthBuf[0];

                values.Capacity = length;
                values.Fill(length, default);

                Span <TValue> valueSpan     = values.AsSpan();
                Span <byte>   byteValueSpan = MemoryMarshal.Cast <TValue, byte>(valueSpan);
                reader.Read(byteValueSpan);
            }
        }
Exemple #4
0
        /// <summary>
        /// Create a new RelationTable that is the inverse of this relation.
        /// </summary>
        /// <remarks>
        /// Very useful for calculating, for example, pip dependents based on pip dependencies, or
        /// per-file producers based on per-pip files produced.
        /// </remarks>
        public RelationTable <TToId, TFromId> Invert()
        {
            RelationTable <TToId, TFromId> result = new RelationTable <TToId, TFromId>(RelatedTable, BaseTableOpt);

            // We will use result.Values to accumulate the counts as usual.
            result.SingleValues.Fill(RelatedTable.Count, 0);
            // And we will use result.m_offsets to store the offsets as usual.
            result.Offsets.Fill(RelatedTable.Count, 0);

            int sum = 0;

            foreach (TFromId id in BaseTableOpt.Ids)
            {
                foreach (TToId relatedId in this[id])
                {
                    result.SingleValues[relatedId.FromId() - 1]++;
                    sum++;
                }
            }

            // Now we can calculate m_offsets.
            result.CalculateOffsets();

            // And we know the necessary size of m_relations.
            result.MultiValues.Capacity = sum;
            result.MultiValues.Fill(sum, default);

            // Allocate an array of positions to track how many relations we have filled in.
            SpannableList <int> positions = new SpannableList <int>(RelatedTable.Count + 1);

            positions.Fill(RelatedTable.Count + 1, 0);

            // And accumulate all the inverse relations.
            foreach (TFromId id in BaseTableOpt.Ids)
            {
                foreach (TToId relatedId in this[id])
                {
                    int relatedIdInt  = relatedId.FromId() - 1;
                    int idInt         = id.FromId() - 1;
                    int offset        = result.Offsets[relatedIdInt];
                    int position      = positions[relatedIdInt];
                    int relationIndex = result.Offsets[relatedIdInt] + positions[relatedIdInt];
                    result.MultiValues[relationIndex] = id;
                    positions[relatedIdInt]++;
                    if (positions[relatedIdInt] > result.SingleValues[relatedIdInt])
                    {
                        // this is a logic bug, should never happen
                        throw new Exception(
                                  $"RelationTable.Inverse: logic exception: positions[{relatedIdInt}] = {positions[relatedIdInt]}, result.SingleValues[{relatedIdInt}] = {result.SingleValues[relatedIdInt]}");
                    }
                    else if (positions[relatedIdInt] == result.SingleValues[relatedIdInt])
                    {
                        // all the relations for this ID are known. now, we have to sort them.
                        Span <TFromId> finalSpan =
                            result.MultiValues.AsSpan().Slice(result.Offsets[relatedIdInt], result.SingleValues[relatedIdInt]);
                        SpanUtilities.Sort(finalSpan, (id1, id2) => id1.FromId().CompareTo(id2.FromId()));
                    }
                }
            }

            // TODO: error check that there are no zero entries in m_relations

            return(result);
        }