Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. Copyright (c) 2005 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. * Usage map whose map is written inline in the same page. This type of map
  27. * can contain a maximum of 512 pages, and is always used for free space maps.
  28. * It has a start page, which all page numbers in its map are calculated as
  29. * starting from.
  30. * @author Tim McCune
  31. */
  32. public class InlineUsageMap extends UsageMap {
  33. /** Size in bytes of the map */
  34. private static final int MAP_SIZE = 64;
  35. /** First page that this usage map applies to */
  36. private int _startPage = 0;
  37. /**
  38. * @param pageChannel Used to read in pages
  39. * @param dataBuffer Buffer that contains this map's declaration
  40. * @param pageNum Page number that this usage map is contained in
  41. * @param format Format of the database that contains this usage map
  42. * @param rowStart Offset at which the declaration starts in the buffer
  43. */
  44. public InlineUsageMap(PageChannel pageChannel, ByteBuffer dataBuffer,
  45. int pageNum, JetFormat format, short rowStart)
  46. throws IOException
  47. {
  48. super(pageChannel, dataBuffer, pageNum, format, rowStart);
  49. _startPage = dataBuffer.getInt(rowStart + 1);
  50. processMap(dataBuffer, 0, _startPage);
  51. }
  52. //Javadoc copied from UsageMap
  53. protected void addOrRemovePageNumber(final int pageNumber, boolean add)
  54. throws IOException
  55. {
  56. if (add && pageNumber < _startPage) {
  57. throw new IOException("Can't add page number " + pageNumber +
  58. " because it is less than start page " + _startPage);
  59. }
  60. int relativePageNumber = pageNumber - _startPage;
  61. ByteBuffer buffer = getDataBuffer();
  62. if ((!add && !getPageNumbers().remove(new Integer(pageNumber))) || (add &&
  63. (relativePageNumber > MAP_SIZE * 8 - 1)))
  64. {
  65. //Increase the start page to the current page and clear out the map.
  66. _startPage = pageNumber;
  67. buffer.position(getRowStart() + 1);
  68. buffer.putInt(_startPage);
  69. getPageNumbers().clear();
  70. if (!add) {
  71. for (int j = 0; j < MAP_SIZE; j++) {
  72. buffer.put((byte) 0xff); //Fill bitmap with 1s
  73. }
  74. for (int j = _startPage; j < _startPage + MAP_SIZE * 8; j++) {
  75. getPageNumbers().add(new Integer(j)); //Fill our list with page numbers
  76. }
  77. }
  78. getPageChannel().writePage(buffer, getDataPageNumber());
  79. relativePageNumber = pageNumber - _startPage;
  80. }
  81. updateMap(pageNumber, relativePageNumber, 1 << (relativePageNumber % 8), buffer, add);
  82. //Write the updated map back to disk
  83. getPageChannel().writePage(buffer, getDataPageNumber());
  84. }
  85. }