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

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


    StoredRecordHeader recordHeader = getHeaderAtSlot(slot);

    if (!recordHeader.hasOverflow())
      return super.fetchNumFieldsAtSlot(slot);

    BasePage overflowPage = getOverflowPage(recordHeader.getOverflowPage());
    int count = overflowPage.fetchNumFieldsAtSlot(getOverflowSlot(overflowPage, recordHeader));
    overflowPage.unlatch();
    return count;
  }
View Full Code Here


    FormatableBitSet                 validColumns,
    StoredRecordHeader      recordHeader)
    throws StandardException
  {

    BasePage overflowPage = getOverflowPage(recordHeader.getOverflowPage());

    try {

      int overflowSlot = getOverflowSlot(overflowPage, recordHeader);

      overflowPage.doUpdateAtSlot(t, overflowSlot, recordHeader.getOverflowId(), row, validColumns);
      overflowPage.unlatch();
      overflowPage = null;

      return;

    } finally {
      if (overflowPage != null) {
        overflowPage.unlatch();
        overflowPage = null;
      }
    }
  }
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 is 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 container until the alloc page is
                     * unlatched.  Those who already have a page handle into
                     * this container are 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
          // 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

                try
                {
          page = initPage(allocHandle, pkey, createPageArgs, pageOffset,
                  reuse, isOverflow);
                }
                catch (StandardException se)
                {
                    if (SanityManager.DEBUG) {
                        SanityManager.DEBUG_PRINT("FileContainer",
                            "got exception from initPage:"  +
                            "\nreuse = " + reuse +
                            "\ncreatePageArgs[1] = " + createPageArgs[1] +
                            "\nallocPage = " + allocPage
                            );
                    }
                    allocCache.dumpAllocationCache();

                    throw se;
                }

          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

      if (nextNumber == ContainerHandle.INVALID_PAGE_NUMBER)
        return null;

      // optimistically go for the next page
      BasePage p = getUserPage(handle, nextNumber,
                false /* no overflow page*/, wait);
      if (p != null)
        return p;

      pageNumber = nextNumber;
View Full Code Here

     throws StandardException
  {
    if (pageNumber == ContainerHandle.INVALID_PAGE_NUMBER)
      return null;

    BasePage p = getUserPage(handle, pageNumber, overflowOK, wait);
    if (p != null)
    {
            // make sure the page is not too full
            if (!p.allowInsert())
            {
                p.unlatch();
                p = null;

                // it is too full, make sure we are tracking it so we won't
                // see it again.
                allocCache.trackUnfilledPage(pageNumber, false);
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.