001 /** 002 * 003 * Copyright 2004 Protique Ltd 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 **/ 018 019 package org.activemq.util; 020 import java.util.LinkedList; 021 022 /** 023 * Holder for many bitArrays - used for message audit 024 * 025 * @version $Revision: 1.1.1.1 $ 026 */ 027 public class BitArrayBin { 028 private LinkedList list; 029 private int maxNumberOfArrays; 030 private int firstIndex = -1; 031 private int firstBin = -1; 032 033 /** 034 * Create a BitArrayBin to a certain window size (number of messages to keep) 035 * 036 * @param windowSize 037 */ 038 public BitArrayBin(int windowSize) { 039 maxNumberOfArrays = ((windowSize + 1) / BitArray.LONG_SIZE) + 1; 040 maxNumberOfArrays = Math.max(maxNumberOfArrays, 1); 041 list = new LinkedList(); 042 for (int i = 0;i < maxNumberOfArrays;i++) { 043 list.add(new BitArray()); 044 } 045 } 046 047 /** 048 * Set a bit 049 * 050 * @param index 051 * @param value 052 * @return 053 */ 054 public boolean setBit(long index, boolean value) { 055 boolean answer = true; 056 BitArray ba = getBitArray(index); 057 if (ba != null) { 058 int offset = getOffset(index); 059 if (offset >= 0) { 060 answer = ba.set(offset, value); 061 } 062 } 063 return answer; 064 } 065 066 /** 067 * Get the boolean value at the index 068 * 069 * @param index 070 * @return true/false 071 */ 072 public boolean getBit(long index) { 073 boolean answer = index >= firstIndex; 074 BitArray ba = getBitArray(index); 075 if (ba != null) { 076 int offset = getOffset(index); 077 if (offset >= 0) { 078 answer = ba.get(offset); 079 return answer; 080 } 081 } 082 else { 083 //gone passed range for previous bins so assume set 084 answer = true; 085 } 086 return answer; 087 } 088 089 /** 090 * Get the BitArray for the index 091 * 092 * @param index 093 * @return 094 */ 095 private BitArray getBitArray(long index) { 096 int bin = getBin(index); 097 BitArray answer = null; 098 if (bin >= 0) { 099 if (firstIndex < 0) { 100 firstIndex = 0; 101 } 102 if (bin >= list.size()) { 103 list.removeFirst(); 104 firstIndex += BitArray.LONG_SIZE; 105 list.add(new BitArray()); 106 bin = list.size() - 1; 107 } 108 answer = (BitArray) list.get(bin); 109 } 110 return answer; 111 } 112 113 /** 114 * Get the index of the bin from the total index 115 * 116 * @param index 117 * @return the index of the bin 118 */ 119 private int getBin(long index) { 120 int answer = 0; 121 if (firstBin < 0) { 122 firstBin = 0; 123 } 124 else if (firstIndex >= 0) { 125 answer = (int) ((index - firstIndex) / BitArray.LONG_SIZE); 126 } 127 return answer; 128 } 129 130 /** 131 * Get the offset into a bin from the total index 132 * 133 * @param index 134 * @return the relative offset into a bin 135 */ 136 private int getOffset(long index) { 137 int answer = 0; 138 if (firstIndex >= 0) { 139 //System.out.println("getOffset(" + index + ") firstIndex = " + firstIndex + " bin = " + getBin(index)); 140 answer = (int) ((index - firstIndex) - (BitArray.LONG_SIZE * getBin(index))); 141 } 142 return answer; 143 } 144 }