Exemplo n.º 1
0
        public RowsetHolder(ColumnInfo[] columnTypes, Memory <byte> storage, bool init)
        {
            System.Diagnostics.Debug.Assert(BitConverter.IsLittleEndian, "Rowset holder fixed assumes that we are running on little endian");

            this.rowSize  = GetRowSize(columnTypes);
            this.storage  = storage;
            this.rowCount = 0;

            // bit for every row.
            // align on upper boundary.
            this.reservedPresenceBitmaskCount = (ushort)UtilStructures.IntCeil.CeilDiv(storage.Length, (rowSize * 8));

            // TODO: In this implementation each value in tuple can't be bigger than 256 bytes.
            // Since this is only for fixed data this should be fine.
            this.reservedColumnTupleOffsetsCount = (ushort)(columnTypes.Length * sizeof(ushort));

            if (init)
            {
                // set bitmask to 0.
                for (int i = 0; i < this.reservedPresenceBitmaskCount; i++)
                {
                    this.storage.Span[i] = 0;
                }

                int pos = this.reservedPresenceBitmaskCount;
                this.storage.Span[pos] = 0;
                for (int i = 0; i < columnTypes.Length - 1; i++)
                {
                    this.storage.Span[pos + 1] = (byte)(this.storage.Span[pos] + columnTypes[i].GetSize());
                    pos++;
                }
            }
            else
            {
                // Set row count.
                this.rowCount = BitArray.CountSet(storage.Span.Slice(0, this.reservedPresenceBitmaskCount));
            }

            // Align so start is divisible by 4.
            // TODO: Need to measure perf.
            int dataStartUnAligned = this.reservedPresenceBitmaskCount + this.reservedColumnTupleOffsetsCount;

            this.dataStartPosition = (ushort)(((dataStartUnAligned + 4 - 1) / 4) * 4);

            maxRowCount = (ushort)((storage.Length - dataStartPosition) / rowSize);
        }