/// <summary> /// Returns all the rows held in the page based on the specified schema /// </summary> /// <param name="schema">The table schema</param> /// <returns>A list of rows</returns> public RowStruct[] GetRows(TableSchema2 schema) { var rows = new RowStruct[_totalRows]; IterateOverData(ref rows); return(rows); }
/// <summary> /// Iterates over this page's _data and populates the supplied array with structs representing the rows /// </summary> /// <param name="rows">An array of RowStruct to populate</param> private void IterateOverData(ref RowStruct[] rows) { var dataSpan = new Span <byte>(_data); int currentOffset = DatabaseConstants.SIZE_OF_PAGE_PREAMBLE; int currentRowNum = 0; while (currentOffset < DatabaseConstants.PAGE_SIZE) { int rowId; bool isLocal; int sizeOfRow; RowPreamble.Parse(dataSpan.Slice(currentOffset, DatabaseConstants.SIZE_OF_ROW_PREAMBLE), out rowId, out isLocal); // check for end of data row identifier if (isLocal && rowId == DatabaseConstants.END_OF_ROW_DATA_ID) { break; } if (currentRowNum >= _totalRows) { break; } currentOffset += DatabaseConstants.SIZE_OF_ROW_PREAMBLE; if (isLocal) { var values = new RowValue2[_schema.Columns.Length]; // we need the size of the row to parse how far along we should go in the array (span). // we will however not adjust the offset since the method LocalRowBodyFromBinary includes parsing the rowSize prefix (an int32 size (4 bytes)). sizeOfRow = BitConverter.ToInt32(dataSpan.Slice(currentOffset, DatabaseConstants.SIZE_OF_ROW_SIZE)); int rowSize; // this isn't really needed, but it's a required param of the method below Row2.LocalRowBodyFromBinary(dataSpan.Slice(currentOffset, sizeOfRow), out rowSize, ref values, _schema.Columns); //rows.Add(new Row2(rowId, isLocal, _schema.Columns, _process.Id.Value, values, sizeOfRow)); rows[currentRowNum] = new RowStruct { IsLocal = isLocal, RowId = rowId, ParticipantId = Guid.Empty, RowSize = sizeOfRow, Values = values }; currentOffset += sizeOfRow; currentRowNum++; } else { sizeOfRow = DatabaseConstants.PARTICIPANT_ID_SIZE; Guid particpantId = DatabaseBinaryConverter.BinaryToGuid(dataSpan.Slice(currentOffset, sizeOfRow)); //rows.Add(new Row2(rowId, isLocal, particpantId, sizeOfRow, _schema.Columns)); rows[currentRowNum] = new RowStruct { IsLocal = isLocal, ParticipantId = particpantId, RowSize = sizeOfRow, RowId = rowId, Values = null }; currentOffset += sizeOfRow; currentRowNum++; } } }
/// <summary> /// Returns all rows from this tree in this container /// </summary> /// <param name="schema">The table schema to convert the rows to</param> /// <param name="dirtyRead">true if unprotected read, otherwise false</param> /// <returns>A list of rows</returns> public RowStruct[] GetAllRows(TableSchema2 schema, bool dirtyRead) { RowStruct[] result; int totalRows = 0; lock (_treeLock) { _tree.ForEach(item => { totalRows += item.Value.TotalRows; }); } result = new RowStruct[totalRows]; var resultSpan = new Span <RowStruct>(result); int i = 0; if (dirtyRead) { TreeDictionary <int, Page> item = _tree.DeepCopy(); foreach (var x in item) { RowStruct[] rows = x.Value.GetRows(schema); i += rows.Length; Array.Copy(rows, 0, result, i, rows.Length); } } else { lock (_treeLock) { foreach (var item in _tree) { RowStruct[] rows = item.Value.GetRows(schema); i += rows.Length; Array.Copy(rows, 0, result, i, rows.Length); } } } return(result); }