Package org.apache.derby.impl.store.raw.data

Examples of org.apache.derby.impl.store.raw.data.BasePage


     throws StandardException
  {
    // findpage will have the page latched.
    // CompensationOperation.doMe must call this.releaseResource the page
    // when it is done
    BasePage undoPage = findpage(xact);

    // Needs to pre-dirty this page so that if a checkpoint is taken any
    // time after the CLR is sent to the log stream, it will wait for the
    // actual undo to happen on the page.  We need this to preserve the
    // integrity of the redoLWM.
    undoPage.preDirty();

    return new PhysicalUndoOperation(undoPage, this);
  }
View Full Code Here


    @exception StandardException Standard Derby error policy
  */
  public void restoreLoggedRow(Object[] row, LimitObjectInput in)
    throws StandardException, IOException
  {
    BasePage p = null;

    try {
      // the optional data is written by the page in the same format it
      // stores record on the page,
      // only a page knows how to restore a logged row back to a storable row
      // first get the page where the insert went even though the row may no
      // longer be there
      p = (BasePage)(getContainer().getPage(getPageId().getPageNumber()));

      // skip over the before and after image of the column, position the
      // input stream at the entire row
      p.skipField(in)// AI of the column
      p.skipField(in)// BI of the column

      p.restoreRecordFromStream(in, row);

      // RESOLVE: this returns the BI of the row, what we need is the AI
      // of the row.  We need to someone splice in the AI of the column
      // into the storable row.

    } finally {

      if (p != null) {
        p.unlatch();
        p = null;
      }
    }
  }
View Full Code Here

    @exception StandardException Standard Derby error policy
  */
  public Page addPage(BaseContainerHandle handle, boolean isOverflow) throws StandardException {

    BasePage newPage = newPage(handle, (RawTransaction) null, handle, isOverflow);

    if (SanityManager.DEBUG) {
      SanityManager.ASSERT(newPage.isLatched());
    }

    return newPage;
  }
View Full Code Here

    @exception StandardException Standard Cloudscape error policy
  */
  public Page addPage(BaseContainerHandle handle, boolean isOverflow) throws StandardException {

    BasePage newPage = newPage(handle, (RawTransaction) null, handle, isOverflow);

    if (SanityManager.DEBUG) {
      SanityManager.ASSERT(newPage.isLatched());
    }

    return newPage;
  }
View Full Code Here

    boolean retry;
    int numtries = 0;
    long startSearch = lastAllocatedPage;

    AllocPage allocPage = null// the alloc page
    BasePage page = null// the new page

    try
    {
      do
      {
        retry = false;    // we don't expect we need to retry

        synchronized(allocCache)
        {
          if (SanityManager.DEBUG)
          {
            SanityManager.ASSERT(ntt.getId().equals(allocHandle.getTransaction().getId()));
            if (useNTT)
              SanityManager.ASSERT(!ntt.getId().equals(userHandle.getTransaction().getId()));
          }

          /* find an allocation page that can handle adding a new page
             allocPage is unlatched when the ntt commits
             The new page is initialized by the ntt but the latch is
             transfered to the user transaction before the allocPage is
             unlatched.  The allocPage latch prevents almost any other reader or
             writer from finding the new page until the ntt is committed and
             the new page latched by the user transaction.
                       (If the page is being reused, it is possible for another xact
                       which kept a handle on the reused page to find the page during the
                       transfer UT -> NTT. If this unlikely even occurs and the transfer
                       fails [see code relating to transfer below], we retry from
                       the beginning.)


             After the NTT commits a reader (getNextPageNumber) may get the page
             number of the newly allocated page and it will wait for the new page
             and latch it when the user transaction commits, aborts or unlatches
             the new page. Whether the user transaction commits or aborts,
             the new page stay allocated.

             RESOLVE: before NTT rolls back (or commits) the latch is released.
             To repopulate the allocation cache, need to get either the container
             lock on add page, or get a per allocation page lock.

             This blocks all page read (getPage) from accessing this alloc page in
             this this container until the alloc page is unlatched.  Those who
             already have a page handle into this container is unaffected.

             In other words, allocation blocks out reader (of any page that is
             managed by this alloc page) by the latch on the allocation page.

             Note that write page can proceed as usual.
            */
          allocPage = findAllocPageForAdd(allocHandle, ntt, startSearch);
          allocCache.invalidate(allocPage, allocPage.getPageNumber());
        }

        if (SanityManager.DEBUG)
        {
          if (allocPage == null)
            allocCache.dumpAllocationCache();

          SanityManager.ASSERT(allocPage != null,
                     "findAllocPageForAdd returned a null alloc page");
        }

        //
        // get the next free page's number.
        // for case 1, page number > lastPreallocPage
        // for case 2, page number <= lastPage
        // for case 3, lastPage < page number <= lastPreallocPage
        //
        pageNumber = allocPage.nextFreePageNumber(startSearch);

        // need to distinguish between the following 3 cases:
        // 1) the page has not been allocate or initalized.
        //    Create it in the page cache and sync it to disk.
        // 2) the page is being re-allocated.
        //    We need to read it in to re-initialize it
        // 3) the page has been preallocated.
        //    Create it in the page cache and don't sync it to disk
        //
        // first find out the current last initialized page and
        // preallocated page before the new page is added
        lastPage = allocPage.getLastPagenum();
        lastPreallocPage = allocPage.getLastPreallocPagenum();

        reuse = pageNumber <= lastPage;

        // no address translation necessary
        pkey = new PageKey(identity, pageNumber);


        if (reuse)
        {
          // if re-useing a page, make sure the deallocLock on the new
          // page is not held.  We only need a zero duration lock on
          // the new page because the allocPage is latched and this
          // is the only thread which can be looking at this
          // pageNumber.

          RecordHandle deallocLock = BasePage.MakeRecordHandle(pkey,
                 RecordHandle.DEALLOCATE_PROTECTION_HANDLE);

          if (!getDeallocLock(allocHandle, deallocLock,
                    false /* nowait */,
                    true /* zeroDuration */))
          {

            // The transaction which deallocated this page has not
            // committed yet. Try going to some other page.  If
            // this is the first time we fail to get the dealloc
            // lock, try from the beginning of the allocated page.
            // If we already did that and still fail, keep going
            // until we get a brand new page.
            if (numtries == 0)
            {
              startSearch = ContainerHandle.INVALID_PAGE_NUMBER;
              lastAllocatedPage = pageNumber;
            }
            else  // continue from where we were
              startSearch = pageNumber;

            numtries++;

            // We have to unlatch the allocPage so that if that
            // transaction rolls back, it won't deadlock with this
            // transaction.
            allocPage.unlatch();
            allocPage = null;

            retry = true;
          }
          else
          {
            // we got the lock, next time start from there
            lastAllocatedPage = pageNumber;
          }
        }
        else
        {
          // we got a new page, next time, start from beginning of
          // the bit map again if we suspect there are some some
          // deallocated pages
          if (numtries > 0)
            lastAllocatedPage = ContainerHandle.INVALID_PAGE_NUMBER;
          else
            lastAllocatedPage = pageNumber;
        }

                // Retry from the beginning if necessary.
                if (retry)
                    continue;

                // If we get past here must have (retry == false)
                if (SanityManager.DEBUG)
                {
                    SanityManager.ASSERT(retry == false);
                }

          // Now we have verified that the allocPage is latched and we can get
          // the zeroDuration deallocLock nowait.  This means the transaction
          // which freed the page has committed.  Had that transaction aborted,
          // we would have retried.

          if (SanityManager.DEBUG)
          {
            // ASSERT lastPage <= lastPreallocPage
            if (lastPage > lastPreallocPage)
              SanityManager.THROWASSERT("last page " +
                lastPage + " > lastPreallocPage " + lastPreallocPage);
          }

          // No I/O at all if this new page is requested as part of a create
          // and load statement or this new page is in a temporary container.
          // In the former case, BaseContainer will allow the MODE_UNLOGGED
          // bit to go thru to the nested top transaction alloc handle.
          // In the later case, there is no nested top transaction and the
          // alloc handle is the user handle, which is UNLOGGED.
          boolean noIO = (allocHandle.getMode() & ContainerHandle.MODE_UNLOGGED) ==
            ContainerHandle.MODE_UNLOGGED;

          // If we do not need the I/O (either because we are in a
          // create_unlogged mode or we are dealing with a temp table), don't
          // do any preallocation.  Otherwise, see if we should be
          // pre-Allocating page by now.  We don't call it before
          // nextFreePageNumber because finding a reusable page may be
          // expensive and we don't want to start preAllocation unless there
          // is no more reusable page.  Unless we are called explicitly to
          // bulk increase the container size in a preload or in a create
          // container.
          if (!noIO && (bulkIncreaseContainerSize ||
              (pageNumber > lastPreallocPage &&
               pageNumber > PreAllocThreshold)))
          {
            allocPage.preAllocatePage(this, PreAllocThreshold,
                          PreAllocSize);
          }

          // update last preAllocated Page, it may have been changed by the
          // preAllocatePage call.  We don't want to do the sync if it
          // preAllocatePage already took care of it.
          lastPreallocPage = allocPage.getLastPreallocPagenum();
          boolean prealloced = pageNumber <= lastPreallocPage;

          // Argument to the create is an array of ints.
          // The array is only used for new page creation or for creating a
          // preallocated page, not for reuse.
          // 0'th element is the page format
          // 1'st element is whether or not to sync the page to disk
          // 2'nd element is pagesize
          // 3'rd element is spareSpace

          int[] createPageArgs = new int[STORED_PAGE_ARG_NUM];
          createPageArgs[0] = StoredPage.FORMAT_NUMBER;
          createPageArgs[1] = prealloced ? 0 : (noIO ? 0 : CachedPage.WRITE_SYNC);
          createPageArgs[2] = pageSize;
          createPageArgs[3] = spareSpace;
          createPageArgs[4] = minimumRecordSize;

          // RESOLVE: right now, there is no re-mapping of pages, so
          // pageOffset = pageNumber*pageSize
          long pageOffset = pageNumber * pageSize;

          // initialize a new user page
          // we first use the NTT to initialize the new page - in case the
          // allocation failed, it is rolled back with the NTT.
          // Later, we transfer the latch to the userHandle so it won't be
          // released when the ntt commits
          page = initPage(allocHandle, pkey, createPageArgs, pageOffset,
                  reuse, isOverflow);
          if (SanityManager.DEBUG)
          {
            SanityManager.ASSERT(page != null, "initPage returns null page");
            SanityManager.ASSERT(page.isLatched(), "initPage returns unlatched page");
          }

          // allocate the page in the allocation page bit map
          allocPage.addPage(this, pageNumber, ntt, userHandle);

          if (useNTT)
          {
            // transfer the page latch from NTT to UT.
            // after the page is unlatched by NTT, it is still protected from being
            // found by almost everybody else because the alloc page is still latched and
            // the alloc cache is invalidated.
                    // However (beetle 3942) it is possible for the page to be found by threads
                    // who specifically ask for this pagenumber (e.g. HeapPostCommit).
                    // We may find that such a thread has latched the page. We shouldn't wait
                    // for it because we have the alloc page latch, and this could cause
                    // deadlock (e.g. HeapPostCommit might call removePage and this would
                    // wait on the alloc page).
                    // We may instead find that we can latch the page, but that another thread
                    // has managed to get hold of it during the transfer and either deallocate
                    // it or otherwise change it (add rows, delete rows etc.)
                    // Since this doesn't happen very often, we retry in these 2 cases
                    // (we give up the alloc page and page and we start this method from scratch).

                    // If the lock manager were changed to allow latches to be transferred between
                    // transactions, wouldn't need to unlatch to do the transfer, and would avoid
                    // having to retry in these cases (beetle 4011).

            page.unlatch();
            page = null;

            // need to find it in the cache again since unlatch also unkept the
            // page from the cache
            page = (BasePage)pageCache.find(pkey);
            page = latchPage(userHandle, page, false /* don't wait, it might deadlock */);

                    if (page == null ||
                        // recordCount will only return true if there are no rows
                        // (including deleted rows)
                        page.recordCount() != 0 ||
                        page.getPageStatus() != BasePage.VALID_PAGE)
                    {
                        retry = true;
                        if (page != null)
                        {
                            page.unlatch();
                            page = null;
                        }
                        allocPage.unlatch();
                        allocPage = null;
                    }

                }
          // if ntt is null, no need to transfer.  Page is latched by user
          // transaction already.  Will be no need to retry.
          // the alloc page is unlatched in the finally block.
            }
            while (retry == true);

            // At this point, should have a page suitable for returning
            if (SanityManager.DEBUG)
                SanityManager.ASSERT(page.isLatched());
    }
    catch (StandardException se)
    {
      if (page != null)
        page.unlatch();
      page = null;

      throw se;      // rethrow error
    }
    finally
    {
      if (!useNTT && allocPage != null)
      {
        allocPage.unlatch();
        allocPage = null;
      }

      // NTT is committed by the caller
    }

    if (SanityManager.DEBUG)
      SanityManager.ASSERT(page.isLatched());


    // if bulkIncreaseContainerSize is set, that means this newPage call
    // may have greatly expanded the container size due to preallocation.
    // Regardless of how many page it actually created, reset preAllocSize
    // to the default so we won't attempt to always preallocate 1000 pages
    // at a time in the future.
    if (bulkIncreaseContainerSize)
    {
      bulkIncreaseContainerSize = false;
      PreAllocSize = DEFAULT_PRE_ALLOC_SIZE;
    }

    if (!isOverflow && page != null)
      setLastInsertedPage(pageNumber);


    // increase estimated page count - without any synchronization or
    // logging, this is an estimate only
    if (estimatedPageCount >= 0)
      estimatedPageCount++;

    if (!this.identity.equals(page.getPageId().getContainerId())) {

      if (SanityManager.DEBUG) {
        SanityManager.THROWASSERT("just created a new page from a different container"
          + "\n this.identity = " + this.identity
          + "\n page.getPageId().getContainerId() = " + page.getPageId().getContainerId()
          + "\n userHandle is: " + userHandle
          + "\n allocHandle is: " + allocHandle
          + "\n this container is: " + this);
      }

      throw StandardException.newException(
                    SQLState.DATA_DIFFERENT_CONTAINER,
                    this.identity, page.getPageId().getContainerId());
    }

    return page;      // return the newly added page
  }
View Full Code Here

                int[] createArgs,
                long pageOffset,
                boolean reuse,
                boolean overflow) throws StandardException
  {
    BasePage page = null;

    boolean releasePage = true;

    try
    {
      if (reuse)        //  read the page in first
      {
        // Cannot go thru the container handle because all read pages are blocked. 
        // do it underneath the handle and directly to the cache. 
        // Nobody can get thru becuase getPage will block at getting the alloc page.

        if (SanityManager.DEBUG)
                {
                    if (SanityManager.DEBUG_ON(SPACE_TRACE))
                    {
                        SanityManager.DEBUG(
                            SPACE_TRACE, "reusing page " + pkey);
                    }
                }

        page = (BasePage)pageCache.find(pkey);
        if (page == null// hmmm?
                {
          throw StandardException.newException(
                            SQLState.FILE_REUSE_PAGE_NOT_FOUND, pkey);
                }
      }
      else
      {
        if (SanityManager.DEBUG)
                {
                    if (SanityManager.DEBUG_ON(SPACE_TRACE))
                    {
                        SanityManager.DEBUG(
                            SPACE_TRACE, "allocation new page " + pkey);
                    }
                }

        // a brand new page, initialize and a new page in cache
        page = (BasePage) pageCache.create(pkey, createArgs);

        if (SanityManager.DEBUG)
          SanityManager.ASSERT(page != null, "page Cache create return a null page");
      }
      releasePage = false;
            page = latchPage(allochandle, page, true /* may need to wait, track3822 */);

      if (page == null)
            {
        throw StandardException.newException(
                        SQLState.FILE_NEW_PAGE_NOT_LATCHED, pkey);
            }    

      // page is either brand new or is read from disk, in either case,
      // it knows how to get itself initialized.
      int initPageFlag = 0;
      if (reuse) initPageFlag |= BasePage.INIT_PAGE_REUSE;
      if (overflow) initPageFlag |= BasePage.INIT_PAGE_OVERFLOW;
      if (reuse && isReusableRecordId())
        initPageFlag |= BasePage.INIT_PAGE_REUSE_RECORDID;

      page.initPage(initPageFlag, pageOffset);
      page.setContainerRowCount(estimatedRowCount);

    }
    finally
    {
      if (releasePage && page != null)
View Full Code Here

    }

    // RESOLVE: no translation!

    PageKey pageSearch = new PageKey(identity, pageNumber);
    BasePage page = (BasePage)pageCache.find(pageSearch);

    if (page == null)
    {
      return page;
    }

        // latch the page
        if (latchPage(handle,page,wait) == null)
        {
      // page was already released from cache
            return null;
        }

    // double check for overflow and deallocated page
    // a page that was valid before maybe invalid by now if it was
    // deallocated in the interum.
    // a page that is invalid can also become valid in the interim, but
    // we do not handle that.  The client must supply other locking
    // mechanism to prevent that (an allocatino happenning where there are
    // readers) if that is needed
    if ((page.isOverflowPage() && !overflowOK) ||
      (page.getPageStatus() != BasePage.VALID_PAGE))
    {
      // unlatch releases page from cache, see StoredPage.releaseExclusive()
            page.unlatch();
      page = null;
    }

    return page;
  }
View Full Code Here

    {
      allocCache.invalidate();
    }
   
    PageKey pageSearch = new PageKey(identity, pageNumber);
    BasePage page = (BasePage) pageCache.find(pageSearch);

    return page;
  }
View Full Code Here

        SanityManager.DEBUG_PRINT("Trace", "recreating page " + pkey + " for load tran");

    // Can't just call initPage because that wants to log an initPage
    // operation, whereas we are here because of an initPage operation in
    // the log already.
    BasePage page = null;
    boolean releasePage = true;
    try
    {
      // a brand new page, initialize and a new page in cache
      page = (BasePage) pageCache.create(pkey, reCreatePageArgs);
View Full Code Here

  {
    if (getCommittedDropState()) // committed and dropped, cannot get a page
      return null;

    PageKey pageSearch = new PageKey(identity, pageNumber);
    BasePage page = (BasePage) pageCache.find(pageSearch);

    if (SanityManager.DEBUG)
    {
      if (page == null)
        SanityManager.THROWASSERT(
View Full Code Here

TOP

Related Classes of org.apache.derby.impl.store.raw.data.BasePage

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.