Package org.apache.derby.iapi.store.raw

Examples of org.apache.derby.iapi.store.raw.RecordHandle


        else if (column instanceof RecordHandle)
        {
            // we are inserting an overflow pointer for a long column

            // casted reference to column to avoid repeated casting.
            RecordHandle overflowHandle = (RecordHandle) column;

            fieldStatus     = StoredFieldHeader.setOverflow(fieldStatus, true);
            headerLength    =
                StoredFieldHeader.write(
                    logicalDataOut, fieldStatus,
                    fieldDataLength, slotFieldSize);

            fieldDataLength +=
                CompressedNumber.writeLong(out, overflowHandle.getPageNumber());
            fieldDataLength +=
                CompressedNumber.writeInt(out, overflowHandle.getId());

        }
        else
        {
            // Serializable/Externalizable/Formattable
View Full Code Here


    {
        // If this is a head page, the recordHandle is the head row handle.
        // If this is not a head page, we are calling updateAtSlot inside some
        // convoluted loop that updates an overflow chain.  There is nothing we
        // can doing about it anyway.
        RecordHandle headRowHandle =
            isOverflowPage() ? null : getRecordHandleAtSlot(slot);
       
        // RESOLVE: djd/yyz what does a null row means? (sku)
        if (row == null)
        {
            owner.getActionSet().actionUpdate(
                t, this, slot, id, row, validColumns, -1,
                (DynamicByteArrayOutputStream) null, -1, headRowHandle);

            return;
        }

        // startColumn is the first column to be updated.
        int startColumn = RowUtil.nextColumn(row, validColumns, 0);
        if (startColumn == -1)
            return;

        if (SanityManager.DEBUG)
        {
            // make sure that if N bits are set in the validColumns that
            // exactly N columns are passed in via the row array.
            if (!isOverflowPage() && validColumns != null)
            {
                if (RowUtil.getNumberOfColumns(-1, validColumns) > row.length)
                    SanityManager.THROWASSERT("updating slot " + slot +
                         " on page " + getIdentity() + " " +
                          RowUtil.getNumberOfColumns(-1, validColumns) +
                          " bits are set in validColumns but only " +
                          row.length + " columns in row[]");
            }
        }


        // Keep track of row shrinkage in the head row piece.  If any row piece
        // shrinks, file a post commit work to clear all reserved space for the
        // entire row chain.
        boolean rowHasReservedSpace = false;

        StoredPage curPage = this;
        for (;;)
        {
            StoredRecordHeader rh = curPage.getHeaderAtSlot(slot);

            int startField          = rh.getFirstField();
            int endFieldExclusive   = startField + rh.getNumberFields();

            // curPage contains column[startField] to column[endFieldExclusive-1]

            // Need to cope with an update that is increasing the number of
            // columns.  If this occurs we want to make sure that we perform a
            // single update to the last portion of a record, and not an update
            // of the current columns and then an update to append a column.

            long nextPage        = -1;
            int  realStartColumn = -1;
            int  realSpaceOnPage = -1;

            if (!rh.hasOverflow() ||
                ((startColumn >= startField) &&
                 (startColumn <  endFieldExclusive)))
            {
                boolean                 hitLongColumn;
                int                     nextColumn      = -1;
                Object[]   savedFields     = null;
                DynamicByteArrayOutputStream  logBuffer       = null;

                do
                {
                    try
                    {
                        // Update this portion of the record.
                        // Pass in headRowHandle in case we are to update any
                        // long column and they need to be cleaned up by post
                        // commit processing.  We don't want to purge the
                        // columns right now because in order to reclaim the
                        // page, we need to remove them.  But it would be bad
                        // to remove them now because the transaction may not
                        // commit for a long time.  We can do both purging of
                        // the long column and page removal together in the
                        // post commit.
                        nextColumn =
                            owner.getActionSet().actionUpdate(
                                t, curPage, slot, id, row, validColumns,
                                realStartColumn, logBuffer,
                                realSpaceOnPage, headRowHandle);

                        hitLongColumn = false;

                    }
                    catch (LongColumnException lce)
                    {
   
                        if (lce.getRealSpaceOnPage() == -1)
                        {
                            // an update that has caused the row to increase
                            // in size *and* push some fields off the page
                            // that need to be inserted in an overflow page

                            // no need to make a copy as we are going to use
                            // this buffer right away
                            logBuffer = lce.getLogBuffer();

                            savedFields     =
                                (Object[]) lce.getColumn();
                           
                            realStartColumn = lce.getNextColumn();
                            realSpaceOnPage = -1;

                            hitLongColumn   = true;

                            continue;
                        }

                       
                        // we caught a real long column exception
                        // three things should happen here:
                        // 1. insert the long column into overflow pages.
                        // 2. append the overflow field header in the main chain.
                        // 3. continue the update in the main data chain.
                        logBuffer =
                            new DynamicByteArrayOutputStream(lce.getLogBuffer());

                        // step 1: insert the long column ... if this update
                        // operation rolls back, purge the after image column
                        // chain and reclaim the overflow page because the
                        // whole chain will be orphaned anyway.
                        RecordHandle longColumnHandle =
                            insertLongColumn(
                                curPage, lce, Page.INSERT_UNDO_WITH_PURGE);

                        // step 2: append overflow field header to log buffer
                        int overflowFieldLen = 0;
                        try
                        {
                            overflowFieldLen +=
                                appendOverflowFieldHeader(
                                    logBuffer, longColumnHandle);

                        }
                        catch (IOException ioe)
                        {
                            throw StandardException.newException(
                                SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
                        }

                        // step 3: continue the insert in the main data chain
                        // need to pass the log buffer, and start column to the
                        // next insert.
                        realStartColumn = lce.getNextColumn() + 1;
                        realSpaceOnPage = lce.getRealSpaceOnPage() - overflowFieldLen;
                        hitLongColumn = true;

                    }

                } while (hitLongColumn);


                // See if we completed all the columns that are on this page.
                int validColumnsSize =
                    (validColumns == null) ? 0 : validColumns.getLength();

                if (nextColumn != -1)
                {

                    if (SanityManager.DEBUG)
                    {
                        // note nextColumn might be less than the the first
                        // column we started updating. This is because the
                        // update might force the record header to grow and
                        // push fields before the one we are updating off the
                        // page and into this insert.

                        if ((nextColumn < startField) ||
                            (rh.hasOverflow() && (nextColumn >= endFieldExclusive)))
                        {
                            SanityManager.THROWASSERT(
                                "nextColumn out of range = " + nextColumn +
                                " expected between " +
                                startField + " and " + endFieldExclusive);
                        }
                    }

                    // Need to insert rows from nextColumn to endFieldExclusive
                    // onto a new overflow page.
                    // If the column is not being updated we
                    // pick it up from the current page. If it is being updated
                    // we take it from the new value.
                    int possibleLastFieldExclusive = endFieldExclusive;
                   
                    if (!rh.hasOverflow())
                    {
                        // we might be adding a field here
                        if (validColumns == null)
                        {
                            if (row.length > possibleLastFieldExclusive)
                                possibleLastFieldExclusive = row.length;
                        }
                        else
                        {
                            if (validColumnsSize > possibleLastFieldExclusive)
                                possibleLastFieldExclusive = validColumnsSize;
                        }
                    }


                    // use a sparse row
                    Object[] newRow =
                        new Object[possibleLastFieldExclusive];

                    FormatableBitSet  newColumnList =
                        new FormatableBitSet(possibleLastFieldExclusive);

                    ByteArrayOutputStream fieldStream = null;

                    for (int i = nextColumn; i < possibleLastFieldExclusive; i++)
                    {
                        if ((validColumns == null) ||
                            (validColumnsSize > i && validColumns.isSet(i)))
                        {
                            newColumnList.set(i);
                            // use the new value
                            newRow[i] = RowUtil.getColumn(row, validColumns, i);

                        }
                        else if (i < endFieldExclusive)
                        {
                            newColumnList.set(i);

                            // use the old value
                            newRow[i] = savedFields[i - nextColumn];
                        }
                    }

                    RecordHandle handle = curPage.getRecordHandleAtSlot(slot);

                    // If the portion we just updated is the last portion then
                    // there cannot be any updates to do.
                    if (rh.hasOverflow())
                    {
                        // We have to carry across the overflow information
                        // from the current record, if any.
                        nextPage = rh.getOverflowPage();
                        id = rh.getOverflowId();

                        // find the next starting column before unlatching page
                        startColumn =
                            RowUtil.nextColumn(
                                row, validColumns, endFieldExclusive);
                    }
                    else
                    {
                        startColumn = -1;
                        nextPage = 0;
                    }


                    // After the update is done, see if this row piece has
                    // shrunk in curPage if no other row pieces have shrunk so
                    // far.  In head page, need to respect minimumRecordSize.
                    // In overflow page entire row needs to respect
                    // StoredRecordHeader.MAX_OVERFLOW_ONLY_REC_SIZE.
                    // Don't bother with temp container.
                    if (!rowHasReservedSpace && headRowHandle != null &&
                        curPage != null && !owner.isTemporaryContainer())
                    {
                        rowHasReservedSpace =
                            curPage.checkRowReservedSpace(slot);
                    }


                    // insert the record portion on a new overflow page at slot
                    // 0 this will automatically handle any overflows in
                    // this new portion

                    // BasePage op = getNewOverflowPage();

                    BasePage op =
                        curPage.getOverflowPageForInsert(
                            slot,
                            newRow,
                            newColumnList,
                            nextColumn);

                    // We have all the information from this page so unlatch it
                    if (curPage != this)
                    {
                        curPage.unlatch();
                        curPage = null;
                    }

                    byte mode = Page.INSERT_OVERFLOW;
                    if (nextPage != 0)
                        mode |= Page.INSERT_FOR_SPLIT;

                    RecordHandle nextPortionHandle =
                        nextPage == 0 ? null :
                        owner.makeRecordHandle(nextPage, id);

                    // RESOLVED (sku):  even though we would like to roll back
                    // these inserts with PURGE rather than with delete,
                    // we have to delete because if we purge the last row
                    // from an overflow page, the purge will queue a post
                    // commit to remove the page.
                    // While this is OK with long columns, we cannot do this
                    // for long rows because long row overflow pages can be
                    // shared by more than one long rows, and thus it is unsafe
                    // to remove the page without first latching the head page.
                    // However, the insert log record do not have the head
                    // row's page number so the rollback cannot put that
                    // information into the post commit work.
                    RecordHandle portionHandle =
                        op.insertAllowOverflow(
                            0, newRow, newColumnList, nextColumn, mode, 100,
                            nextPortionHandle);

                    // Update the previous record header to point to new portion
View Full Code Here

                lock_row_loc == lock_template[lock_template.length - 1],
                "row_loc is not the object in last column of lock_template.");
        }

        // Fetch the row location to lock.
        RecordHandle rec_handle =
            current_leaf.getPage().fetchFromSlot(
                (RecordHandle) null, current_slot,
                lock_template, lock_fetch_desc, true);

        // First try to get the lock NOWAIT, while latch is held.
View Full Code Here

    int                     lock_operation)
    throws StandardException
    {
        // The scan page lock is implemented as a row lock on the reserved
        // row id on the page (RecordHandle.RECORD_ID_PROTECTION_HANDLE).
        RecordHandle scan_lock_rh =
            current_leaf.getPage().makeRecordHandle(
                RecordHandle.RECORD_ID_PROTECTION_HANDLE);

        // First try to get the lock NOWAIT, while latch is held.
        boolean ret_status =
View Full Code Here

    LeafControlRow          current_leaf)
    throws StandardException
    {
        // The scan page lock is implemented as a row lock on the reserved
        // row id on the page (RecordHandle.RECORD_ID_PROTECTION_HANDLE).
        RecordHandle scan_lock_rh =
            current_leaf.getPage().makeRecordHandle(
                RecordHandle.RECORD_ID_PROTECTION_HANDLE);

        // First try to get the lock NOWAIT, while latch is held.
        return(
View Full Code Here

    {
        // This is first row in table, lock the special key that
        // represents the key previous to the first key of the table.
        try
        {
            RecordHandle scan_lock_rh =
                open_btree.makeRecordHandle(
                    page_number, RecordHandle.RECORD_ID_PROTECTION_HANDLE);

            scan_locking_policy.unlockRecordAfterRead(
                rawtran, open_btree.getContainerHandle(),
View Full Code Here

             "long column page has > 1 record");
        }

        // Hold on to the pointer to next page on the chain before
        // we remove the long column page.
        RecordHandle nextColumnPiece =
          pageOnColumnChain.getNextColumnPiece(overflowSlotId);

        if (pageOnColumnChain.recordCount() == 1)
        {
          removePageHappened = true;
          owner.removePage(pageOnColumnChain);
        }
        else
        {
          if (SanityManager.DEBUG)
            SanityManager.THROWASSERT(
              "page on column chain has more then one record" +
              pageOnColumnChain.toString());

          pageOnColumnChain.unlatch();
          pageOnColumnChain = null;
        }

        // Chase the column chain pointer.
        if (nextColumnPiece != null)
                {
          overflowPageId      = nextColumnPiece.getPageNumber();
          overflowRecordId    = nextColumnPiece.getId();
        }
                else
                {
          // terminate the loop
          overflowPageId      = ContainerHandle.INVALID_PAGE_NUMBER;
View Full Code Here

      return;

    // Now get to the column in question and make sure it is no longer
    // pointing to the column chain.

    RecordHandle headRowHandle = work.getHeadRowHandle();

    if (SanityManager.DEBUG)
        {
            // System.out.println("Executing in removeOrphanedColumnChain.");
            // System.out.println("work =  " + work);
            // System.out.println("head = " + headOfChain);
            // System.out.println("this = " + this);

      SanityManager.ASSERT(isLatched());
      SanityManager.ASSERT(
                headRowHandle.getPageNumber() == getPageNumber(),
                "got wrong head page");
   

    // First get the row.
    int slot =
            findRecordById(
                headRowHandle.getId(), headRowHandle.getSlotNumberHint());

    // If slot < 0, it means the whole record is gone, the column chain is
    // definitely orphaned.

    if (slot >= 0)
View Full Code Here

        else if (column instanceof RecordHandle)
        {
      // we are inserting an overflow pointer for a long column

            // casted reference to column to avoid repeated casting.
      RecordHandle overflowHandle = (RecordHandle) column;

      fieldStatus     = StoredFieldHeader.setOverflow(fieldStatus, true);
      headerLength    =
                StoredFieldHeader.write(
                    logicalDataOut, fieldStatus,
                    fieldDataLength, slotFieldSize);

      fieldDataLength +=
                CompressedNumber.writeLong(out, overflowHandle.getPageNumber());
      fieldDataLength +=
                CompressedNumber.writeInt(out, overflowHandle.getId());

    }
        else
        {
      // Serializable/Externalizable/Formattable
View Full Code Here

  {
    // If this is a head page, the recordHandle is the head row handle.
    // If this is not a head page, we are calling updateAtSlot inside some
    // convoluted loop that updates an overflow chain.  There is nothing we
    // can doing about it anyway.
    RecordHandle headRowHandle =
            isOverflowPage() ? null : getRecordHandleAtSlot(slot);
   
    // RESOLVE: djd/yyz what does a null row means? (sku)
    if (row == null)
        {
      owner.getActionSet().actionUpdate(
                t, this, slot, id, row, validColumns, -1,
                (DynamicByteArrayOutputStream) null, -1, headRowHandle);

      return;
    }

    // startColumn is the first column to be updated.
    int startColumn = RowUtil.nextColumn(row, validColumns, 0);
    if (startColumn == -1)
      return;

    if (SanityManager.DEBUG)
    {
      // make sure that if N bits are set in the validColumns that
      // exactly N columns are passed in via the row array.
      if (!isOverflowPage() && validColumns != null)
      {
        if (RowUtil.getNumberOfColumns(-1, validColumns) > row.length)
          SanityManager.THROWASSERT("updating slot " + slot +
             " on page " + getIdentity() + " " +
              RowUtil.getNumberOfColumns(-1, validColumns) +
              " bits are set in validColumns but only " +
              row.length + " columns in row[]");
      }
    }


    // Keep track of row shrinkage in the head row piece.  If any row piece
    // shrinks, file a post commit work to clear all reserved space for the
    // entire row chain.
    boolean rowHasReservedSpace = false;

    StoredPage curPage = this;
    for (;;)
        {
      StoredRecordHeader rh = curPage.getHeaderAtSlot(slot);

      int startField          = rh.getFirstField();
      int endFieldExclusive   = startField + rh.getNumberFields();

      // curPage contains column[startField] to column[endFieldExclusive-1]

      // Need to cope with an update that is increasing the number of
            // columns.  If this occurs we want to make sure that we perform a
            // single update to the last portion of a record, and not an update
            // of the current columns and then an update to append a column.

      long nextPage        = -1;
      int  realStartColumn = -1;
      int  realSpaceOnPage = -1;

      if (!rh.hasOverflow() ||
                ((startColumn >= startField) &&
                 (startColumn <  endFieldExclusive)))
      {
        boolean                 hitLongColumn;
        int                     nextColumn      = -1;
        Object[]   savedFields     = null;
        DynamicByteArrayOutputStream  logBuffer       = null;

        do
                {
          try
                    {
            // Update this portion of the record.
            // Pass in headRowHandle in case we are to update any
            // long column and they need to be cleaned up by post
            // commit processing.  We don't want to purge the
            // columns right now because in order to reclaim the
            // page, we need to remove them.  But it would be bad
            // to remove them now because the transaction may not
            // commit for a long time.  We can do both purging of
            // the long column and page removal together in the
            // post commit.
            nextColumn =
                            owner.getActionSet().actionUpdate(
                                t, curPage, slot, id, row, validColumns,
                  realStartColumn, logBuffer,
                                realSpaceOnPage, headRowHandle);

            hitLongColumn = false;

          }
                    catch (LongColumnException lce)
                    {
 
            if (lce.getRealSpaceOnPage() == -1)
                        {
              // an update that has caused the row to increase
                            // in size *and* push some fields off the page
                            // that need to be inserted in an overflow page

              // no need to make a copy as we are going to use
                            // this buffer right away
              logBuffer = lce.getLogBuffer();

              savedFields     =
                                (Object[]) lce.getColumn();
                           
              realStartColumn = lce.getNextColumn();
              realSpaceOnPage = -1;

              hitLongColumn   = true;

              continue;
            }

           
            // we caught a real long column exception
            // three things should happen here:
            // 1. insert the long column into overflow pages.
            // 2. append the overflow field header in the main chain.
            // 3. continue the update in the main data chain.
            logBuffer =
                            new DynamicByteArrayOutputStream(lce.getLogBuffer());

            // step 1: insert the long column ... if this update
                        // operation rolls back, purge the after image column
                        // chain and reclaim the overflow page because the
                        // whole chain will be orphaned anyway.
            RecordHandle longColumnHandle =
              insertLongColumn(
                                curPage, lce, Page.INSERT_UNDO_WITH_PURGE);

            // step 2: append overflow field header to log buffer
            int overflowFieldLen = 0;
            try
                        {
              overflowFieldLen +=
                appendOverflowFieldHeader(
                                    logBuffer, longColumnHandle);

            }
                        catch (IOException ioe)
                        {
              throw StandardException.newException(
                                SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
            }

            // step 3: continue the insert in the main data chain
            // need to pass the log buffer, and start column to the
                        // next insert.
            realStartColumn = lce.getNextColumn() + 1;
            realSpaceOnPage = lce.getRealSpaceOnPage() - overflowFieldLen;
            hitLongColumn = true;

          }

        } while (hitLongColumn);


        // See if we completed all the columns that are on this page.
        int validColumnsSize =
                    (validColumns == null) ? 0 : validColumns.getLength();

        if (nextColumn != -1)
                {

          if (SanityManager.DEBUG)
                    {
            // note nextColumn might be less than the the first
                        // column we started updating. This is because the
                        // update might force the record header to grow and
                        // push fields before the one we are updating off the
                        // page and into this insert.

            if ((nextColumn < startField) ||
                            (rh.hasOverflow() && (nextColumn >= endFieldExclusive)))
                        {
              SanityManager.THROWASSERT(
                                "nextColumn out of range = " + nextColumn +
                " expected between " +
                                startField + " and " + endFieldExclusive);
                        }
          }

          // Need to insert rows from nextColumn to endFieldExclusive
                    // onto a new overflow page.
          // If the column is not being updated we
          // pick it up from the current page. If it is being updated
          // we take it from the new value.
          int possibleLastFieldExclusive = endFieldExclusive;
                   
          if (!rh.hasOverflow())
                    {
            // we might be adding a field here
            if (validColumns == null)
                        {
              if (row.length > possibleLastFieldExclusive)
                possibleLastFieldExclusive = row.length;
            }
                        else
                        {
              if (validColumnsSize > possibleLastFieldExclusive)
                possibleLastFieldExclusive = validColumnsSize;
            }
          }


                    // use a sparse row
          Object[] newRow =
                        new Object[possibleLastFieldExclusive];

          FormatableBitSet  newColumnList =
                        new FormatableBitSet(possibleLastFieldExclusive);

          ByteArrayOutputStream fieldStream = null;

          for (int i = nextColumn; i < possibleLastFieldExclusive; i++)
                    {
            if ((validColumns == null) ||
                            (validColumnsSize > i && validColumns.isSet(i)))
                        {
              newColumnList.set(i);
              // use the new value
              newRow[i] = RowUtil.getColumn(row, validColumns, i);

            }
                        else if (i < endFieldExclusive)
                        {
              newColumnList.set(i);

              // use the old value
              newRow[i] = savedFields[i - nextColumn];
            }
          }

          RecordHandle handle = curPage.getRecordHandleAtSlot(slot);

          // If the portion we just updated is the last portion then
                    // there cannot be any updates to do.
          if (rh.hasOverflow())
                    {
            // We have to carry across the overflow information
            // from the current record, if any.
            nextPage = rh.getOverflowPage();
            id = rh.getOverflowId();

            // find the next starting column before unlatching page
            startColumn =
                            RowUtil.nextColumn(
                                row, validColumns, endFieldExclusive);
          }
                    else
                    {
            startColumn = -1;
            nextPage = 0;
          }


          // After the update is done, see if this row piece has
          // shrunk in curPage if no other row pieces have shrunk so
          // far.  In head page, need to respect minimumRecordSize.
          // In overflow page, only need to respect
          // RawStoreFactory.MINIMUM_RECORD_SIZE_DEFAULT
          // Don't bother with temp container.
          if (!rowHasReservedSpace && headRowHandle != null &&
            curPage != null && !owner.isTemporaryContainer())
          {
            rowHasReservedSpace =
                            curPage.checkRowReservedSpace(slot);
          }


          // insert the record portion on a new overflow page at slot
                    // 0 this will automatically handle any overflows in
          // this new portion

          // BasePage op = getNewOverflowPage();

                    BasePage op =
                        curPage.getOverflowPageForInsert(
                            slot,
                            newRow,
                            newColumnList,
                            nextColumn);

          // We have all the information from this page so unlatch it
          if (curPage != this)
                    {
            curPage.unlatch();
            curPage = null;
          }

          byte mode = Page.INSERT_OVERFLOW;
          if (nextPage != 0)
            mode |= Page.INSERT_FOR_SPLIT;

          RecordHandle nextPortionHandle =
            nextPage == 0 ? null :
            owner.makeRecordHandle(nextPage, id);

          // RESOLVED (sku):  even though we would like to roll back
                    // these inserts with PURGE rather than with delete,
                    // we have to delete because if we purge the last row
          // from an overflow page, the purge will queue a post
                    // commit to remove the page.
          // While this is OK with long columns, we cannot do this
                    // for long rows because long row overflow pages can be
                    // shared by more than one long rows, and thus it is unsafe
          // to remove the page without first latching the head page.
                    // However, the insert log record do not have the head
                    // row's page number so the rollback cannot put that
          // information into the post commit work.
          RecordHandle portionHandle =
            op.insertAllowOverflow(
                            0, newRow, newColumnList, nextColumn, mode, 100,
                            nextPortionHandle);

          // Update the previous record header to point to new portion
View Full Code Here

TOP

Related Classes of org.apache.derby.iapi.store.raw.RecordHandle

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.