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.

NullMask.java 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. Copyright (c) 2005 Health Market Science, Inc.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package com.healthmarketscience.jackcess.impl;
  14. import java.nio.ByteBuffer;
  15. /**
  16. * Bitmask that indicates whether or not each column in a row is null. Also
  17. * holds values of boolean columns.
  18. * @author Tim McCune
  19. */
  20. public class NullMask {
  21. /** num row columns */
  22. private final int _columnCount;
  23. /** The actual bitmask */
  24. private final byte[] _mask;
  25. /**
  26. * @param columnCount Number of columns in the row that this mask will be
  27. * used for
  28. */
  29. public NullMask(int columnCount) {
  30. _columnCount = columnCount;
  31. // we leave everything initially marked as null so that we don't need to
  32. // do anything for deleted columns (we only need to mark as non-null
  33. // valid columns for which we actually have values).
  34. _mask = new byte[(_columnCount + 7) / 8];
  35. }
  36. /**
  37. * Read a mask in from a buffer
  38. */
  39. public void read(ByteBuffer buffer) {
  40. buffer.get(_mask);
  41. }
  42. /**
  43. * Write a mask to a buffer
  44. */
  45. public void write(ByteBuffer buffer) {
  46. buffer.put(_mask);
  47. }
  48. /**
  49. * @param column column to test for {@code null}
  50. * @return Whether or not the value for that column is null. For boolean
  51. * columns, returns the actual value of the column (where
  52. * non-{@code null} == {@code true})
  53. */
  54. public boolean isNull(ColumnImpl column) {
  55. int columnNumber = column.getColumnNumber();
  56. // if new columns were added to the table, old null masks may not include
  57. // them (meaning the field is null)
  58. if(columnNumber >= _columnCount) {
  59. // it's null
  60. return true;
  61. }
  62. return (_mask[byteIndex(columnNumber)] & bitMask(columnNumber)) == 0;
  63. }
  64. /**
  65. * Indicate that the column with the given number is not {@code null} (or a
  66. * boolean value is {@code true}).
  67. * @param column column to be marked non-{@code null}
  68. */
  69. public void markNotNull(ColumnImpl column) {
  70. int columnNumber = column.getColumnNumber();
  71. int maskIndex = byteIndex(columnNumber);
  72. _mask[maskIndex] = (byte) (_mask[maskIndex] | bitMask(columnNumber));
  73. }
  74. /**
  75. * @return Size in bytes of this mask
  76. */
  77. public int byteSize() {
  78. return _mask.length;
  79. }
  80. private static int byteIndex(int columnNumber) {
  81. return columnNumber / 8;
  82. }
  83. private static byte bitMask(int columnNumber) {
  84. return (byte) (1 << (columnNumber % 8));
  85. }
  86. }