blob: 766a8fc06cf93997784ef758a3f49f5568d8f8b1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.store.blockcache;
import java.util.concurrent.atomic.AtomicLongArray;
import org.apache.lucene.util.LongBitSet;
/**
* @lucene.experimental
*/
public class BlockLocks {
private AtomicLongArray bits;
private int wlen;
public BlockLocks(long numBits) {
int length = LongBitSet.bits2words(numBits);
bits = new AtomicLongArray(length);
wlen = length;
}
/**
* Find the next clear bit in the bit set.
*
* @param index
* index
* @return next next bit
*/
public int nextClearBit(int index) {
int i = index >> 6;
if (i >= wlen) return -1;
int subIndex = index & 0x3f; // index within the word
long word = ~bits.get(i) >> subIndex; // skip all the bits to the right of
// index
if (word != 0) {
return (i << 6) + subIndex + Long.numberOfTrailingZeros(word);
}
while (++i < wlen) {
word = ~bits.get(i);
if (word != 0) {
return (i << 6) + Long.numberOfTrailingZeros(word);
}
}
return -1;
}
/**
* Thread safe set operation that will set the bit if and only if the bit was
* not previously set.
*
* @param index
* the index position to set.
* @return returns true if the bit was set and false if it was already set.
*/
public boolean set(int index) {
int wordNum = index >> 6; // div 64
int bit = index & 0x3f; // mod 64
long bitmask = 1L << bit;
long word, oword;
do {
word = bits.get(wordNum);
// if set another thread stole the lock
if ((word & bitmask) != 0) {
return false;
}
oword = word;
word |= bitmask;
} while (!bits.compareAndSet(wordNum, oword, word));
return true;
}
public void clear(int index) {
int wordNum = index >> 6;
int bit = index & 0x03f;
long bitmask = 1L << bit;
long word, oword;
do {
word = bits.get(wordNum);
oword = word;
word &= ~bitmask;
} while (!bits.compareAndSet(wordNum, oword, word));
}
}