예제 #1
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public void read(RECORD record, org.neo4j.io.pagecache.PageCursor primaryCursor, org.neo4j.kernel.impl.store.record.RecordLoad mode, int recordSize) throws java.io.IOException
        public override void Read(RECORD record, PageCursor primaryCursor, RecordLoad mode, int recordSize)
        {
            int   primaryStartOffset = primaryCursor.Offset;
            sbyte headerByte         = primaryCursor.Byte;
            bool  inUse            = isInUse(headerByte);
            bool  doubleRecordUnit = has(headerByte, HeaderBitRecordUnit);

            record.UseFixedReferences = false;
            if (doubleRecordUnit)
            {
                bool firstRecordUnit = has(headerByte, HeaderBitFirstRecordUnit);
                if (!firstRecordUnit)
                {
                    // This is a record unit and not even the first one, so you cannot go here directly and read it,
                    // it may only be read as part of reading the primary unit.
                    record.clear();
                    // Return and try again
                    primaryCursor.CursorException = "Expected record to be the first unit in the chain, but record header says it's not";
                    return;
                }

                // This is a record that is split into multiple record units. We need a bit more clever
                // data structures here. For the time being this means instantiating one object,
                // but the trade-off is a great reduction in complexity.
                long       secondaryId     = Reference.decode(primaryCursor);
                long       pageId          = pageIdForRecord(secondaryId, primaryCursor.CurrentPageSize, recordSize);
                int        offset          = offsetForId(secondaryId, primaryCursor.CurrentPageSize, recordSize);
                PageCursor secondaryCursor = primaryCursor.OpenLinkedCursor(pageId);
                if ((!secondaryCursor.Next()) | offset < 0)
                {
                    // We must have made an inconsistent read of the secondary record unit reference.
                    // No point in trying to read this.
                    record.clear();
                    primaryCursor.CursorException = IllegalSecondaryReferenceMessage(pageId);
                    return;
                }
                secondaryCursor.Offset = offset + HeaderByte;
                int primarySize = recordSize - (primaryCursor.Offset - primaryStartOffset);
                // We *could* sanity check the secondary record header byte here, but we won't. If it is wrong, then we most
                // likely did an inconsistent read, in which case we'll just retry. Otherwise, if the header byte is wrong,
                // then there is little we can do about it here, since we are not allowed to throw exceptions.

                int        secondarySize = recordSize - HeaderByte;
                PageCursor composite     = CompositePageCursor.compose(primaryCursor, primarySize, secondaryCursor, secondarySize);
                DoReadInternal(record, composite, recordSize, headerByte, inUse);
                record.SecondaryUnitId = secondaryId;
            }
            else
            {
                record.UseFixedReferences = IsUseFixedReferences(headerByte);
                DoReadInternal(record, primaryCursor, recordSize, headerByte, inUse);
            }

            // Set cursor offset to next record to prepare next read in case of scanning.
            primaryCursor.Offset = primaryStartOffset + recordSize;
        }
예제 #2
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public void write(RECORD record, org.neo4j.io.pagecache.PageCursor primaryCursor, int recordSize) throws java.io.IOException
        public override void Write(RECORD record, PageCursor primaryCursor, int recordSize)
        {
            if (record.inUse())
            {
                // Let the specific implementation provide the additional header bits and we'll provide the core format bits.
                sbyte headerByte = HeaderBits(record);
                assert(headerByte & 0x7) == 0 : "Format-specific header bits (" + headerByte +
                ") collides with format-generic header bits";
                headerByte = set(headerByte, IN_USE_BIT, record.inUse());
                headerByte = set(headerByte, HeaderBitRecordUnit, record.requiresSecondaryUnit());
                if (record.requiresSecondaryUnit())
                {
                    headerByte = set(headerByte, HeaderBitFirstRecordUnit, true);
                }
                else
                {
                    headerByte = set(headerByte, HeaderBitFixedReference, !record.UseFixedReferences);
                }
                primaryCursor.PutByte(headerByte);

                if (record.requiresSecondaryUnit())
                {
                    // Write using the normal adapter since the first reference we write cannot really overflow
                    // into the secondary record
                    long       secondaryUnitId = record.SecondaryUnitId;
                    long       pageId          = pageIdForRecord(secondaryUnitId, primaryCursor.CurrentPageSize, recordSize);
                    int        offset          = offsetForId(secondaryUnitId, primaryCursor.CurrentPageSize, recordSize);
                    PageCursor secondaryCursor = primaryCursor.OpenLinkedCursor(pageId);
                    if (!secondaryCursor.Next())
                    {
                        // We are not allowed to write this much data to the file, apparently.
                        record.clear();
                        return;
                    }
                    secondaryCursor.Offset = offset;
                    secondaryCursor.PutByte(( sbyte )(IN_USE_BIT | HeaderBitRecordUnit));
                    int        recordSizeWithoutHeader = recordSize - HeaderByte;
                    PageCursor composite = CompositePageCursor.compose(primaryCursor, recordSizeWithoutHeader, secondaryCursor, recordSizeWithoutHeader);

                    Reference.encode(secondaryUnitId, composite);
                    DoWriteInternal(record, composite);
                }
                else
                {
                    DoWriteInternal(record, primaryCursor);
                }
            }
            else
            {
                MarkAsUnused(primaryCursor, record, recordSize);
            }
        }