예제 #1
0
        /// <summary>
        /// Add the next set of values; return the ID that was allocated.
        /// </summary>
        /// <remarks>
        /// This only supports appending all the sets of values ID by ID in order.
        /// TODO: allow more flexible building.
        /// </remarks>
        public virtual TId Add(ReadOnlySpan <TValue> multiValues)
        {
            if (SingleValues.Count > 0)
            {
                Offsets.Add(Offsets[Count - 1] + SingleValues[Count - 1]);
            }
            else
            {
                Offsets.Add(0);
            }

            SingleValues.Add(multiValues.Length);

            MultiValues.AddRange(multiValues);

            return(default(TId).ToId(Count));
        }
예제 #2
0
            /// <summary>
            /// All relationships have been added; sort them all and build the final relation table.
            /// </summary>
            public void Complete()
            {
                m_list.AsSpan().Sort((tuple1, tuple2) =>
                {
                    int fromIdCompare = tuple1.fromId.FromId().CompareTo(tuple2.fromId.FromId());
                    if (fromIdCompare != 0)
                    {
                        return(fromIdCompare);
                    }
                    return(tuple1.toId.FromId().CompareTo(tuple2.toId.FromId()));
                });

                // and bin them by groups
                int listIndex = 0;
                SpannableList <TToId> buffer = new SpannableList <TToId>();
                int listCount = m_list.Count;

                Table.SetMultiValueCapacity(listCount);

                foreach (TFromId id in Table.BaseTableOpt.Ids)
                {
                    if (listIndex >= m_list.Count)
                    {
                        // ran outta entries, rest all 0
                        break;
                    }

                    // Count up how many are for id.
                    int count = 0;
                    buffer.Clear();

                    // create a to-ID that will never equal any other ID (even default)
                    TToId lastToId = default(TToId).ToId(-1);

                    while (listIndex + count < m_list.Count)
                    {
                        var(fromId, toId) = m_list[listIndex + count];
                        if (fromId.Equals(id))
                        {
                            // drop duplicates (silently...)
                            // TODO: are duplicates here a logic bug? Because they do happen in practice.
                            if (!toId.Equals(lastToId))
                            {
                                buffer.Add(toId);
                            }
                            count++;
                            lastToId = toId;
                            continue;
                        }
                        // ok we're done
                        break;
                    }

                    Table.Add(buffer.AsSpan());
                    listIndex += count;
                }
            }
예제 #3
0
        /// <summary>
        /// Add the next set of values; return the ID that was allocated.
        /// </summary>
        /// <remarks>
        /// This only supports appending all the sets of values ID by ID in order.
        /// TODO: allow more flexible building.
        /// </remarks>
        public virtual TId Add(ReadOnlySpan <TValue> multiValues)
        {
            if (BaseTableOpt != null && SingleValues.Count == BaseTableOpt.Count)
            {
                throw new Exception("Can't add to end of a table that has already been filled");
            }

            if (SingleValues.Count > 0)
            {
                Offsets.Add(Offsets[Count - 1] + SingleValues[Count - 1]);
            }
            else
            {
                Offsets.Add(0);
            }

            SingleValues.Add(multiValues.Length);

            MultiValues.AddRange(multiValues);

            return(default(TId).CreateFrom(Count));
        }