You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TempPageHolder.java 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. Copyright (c) 2007 Health Market Science, Inc.
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with this library; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  14. USA
  15. You can contact Health Market Science at info@healthmarketscience.com
  16. or at the following address:
  17. Health Market Science
  18. 2700 Horizon Drive
  19. Suite 200
  20. King of Prussia, PA 19406
  21. */
  22. package com.healthmarketscience.jackcess;
  23. import java.io.IOException;
  24. import java.nio.ByteBuffer;
  25. /**
  26. * Manages a reference to a page buffer.
  27. *
  28. * @author James Ahlborn
  29. */
  30. public final class TempPageHolder {
  31. private int _pageNumber = PageChannel.INVALID_PAGE_NUMBER;
  32. private final TempBufferHolder _buffer;
  33. /** the last "modification" count of the buffer that this holder observed.
  34. this is tracked so that the page data can be re-read if the underlying
  35. buffer has been discarded since the last page read */
  36. private int _bufferModCount;
  37. private TempPageHolder(TempBufferHolder.Type type) {
  38. _buffer = TempBufferHolder.newHolder(type, false);
  39. _bufferModCount = _buffer.getModCount();
  40. }
  41. /**
  42. * Creates a new TempPageHolder.
  43. * @param type the type of reference desired for any create page buffers
  44. */
  45. public static TempPageHolder newHolder(TempBufferHolder.Type type) {
  46. return new TempPageHolder(type);
  47. }
  48. /**
  49. * @return the currently set page number
  50. */
  51. public int getPageNumber() {
  52. return _pageNumber;
  53. }
  54. /**
  55. * @return the page for the current page number, reading as necessary,
  56. * position and limit are unchanged
  57. */
  58. public ByteBuffer getPage(PageChannel pageChannel)
  59. throws IOException
  60. {
  61. return setPage(pageChannel, _pageNumber, false);
  62. }
  63. /**
  64. * Sets the current page number and returns that page
  65. * @return the page for the new page number, reading as necessary, resets
  66. * position
  67. */
  68. public ByteBuffer setPage(PageChannel pageChannel, int pageNumber)
  69. throws IOException
  70. {
  71. return setPage(pageChannel, pageNumber, true);
  72. }
  73. private ByteBuffer setPage(PageChannel pageChannel, int pageNumber,
  74. boolean rewind)
  75. throws IOException
  76. {
  77. ByteBuffer buffer = _buffer.getPageBuffer(pageChannel);
  78. int modCount = _buffer.getModCount();
  79. if((pageNumber != _pageNumber) || (_bufferModCount != modCount)) {
  80. _pageNumber = pageNumber;
  81. _bufferModCount = modCount;
  82. pageChannel.readPage(buffer, _pageNumber);
  83. } else if(rewind) {
  84. buffer.rewind();
  85. }
  86. return buffer;
  87. }
  88. /**
  89. * Allocates a new buffer in the database (with undefined data) and returns
  90. * a new empty buffer.
  91. */
  92. public ByteBuffer setNewPage(PageChannel pageChannel)
  93. throws IOException
  94. {
  95. // ditch any current data
  96. clear();
  97. // allocate a new page in the database
  98. _pageNumber = pageChannel.allocateNewPage();
  99. // return a new buffer
  100. return _buffer.getPageBuffer(pageChannel);
  101. }
  102. /**
  103. * Forces any current page data to be disregarded (any
  104. * <code>getPage</code>/<code>setPage</code> call must reload page data).
  105. * Does not necessarily release any memory.
  106. */
  107. public void invalidate() {
  108. possiblyInvalidate(_pageNumber, null);
  109. }
  110. /**
  111. * Forces any current page data to be disregarded if it matches the given
  112. * page number (any <code>getPage</code>/<code>setPage</code> call must
  113. * reload page data) and is not the given buffer. Does not necessarily
  114. * release any memory.
  115. */
  116. public void possiblyInvalidate(int modifiedPageNumber,
  117. ByteBuffer modifiedBuffer) {
  118. if(modifiedBuffer == _buffer.getExistingBuffer()) {
  119. // no worries, our buffer was the one modified (or is null, either way
  120. // we'll need to reload)
  121. return;
  122. }
  123. if(modifiedPageNumber == _pageNumber) {
  124. _pageNumber = PageChannel.INVALID_PAGE_NUMBER;
  125. }
  126. }
  127. /**
  128. * Forces any current page data to be disregarded (any
  129. * <code>getPage</code>/<code>setPage</code> call must reload page data) and
  130. * releases any referenced memory.
  131. */
  132. public void clear() {
  133. invalidate();
  134. _buffer.clear();
  135. }
  136. }