BitSet.java

  1. /*
  2.  * Copyright (C) 2012, Google Inc. and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */

  10. package org.eclipse.jgit.internal.storage.file;

  11. import java.util.Arrays;

  12. import com.googlecode.javaewah.EWAHCompressedBitmap;

  13. /**
  14.  * A random access BitSet to supports efficient conversions to
  15.  * EWAHCompressedBitmap.
  16.  */
  17. final class BitSet {

  18.     private long[] words;

  19.     BitSet(int initialCapacity) {
  20.         words = new long[block(initialCapacity) + 1];
  21.     }

  22.     final void clear() {
  23.         Arrays.fill(words, 0);
  24.     }

  25.     final void set(int position) {
  26.         int block = block(position);
  27.         if (block >= words.length) {
  28.             long[] buf = new long[2 * block(position)];
  29.             System.arraycopy(words, 0, buf, 0, words.length);
  30.             words = buf;
  31.         }
  32.         words[block] |= mask(position);
  33.     }

  34.     final void clear(int position) {
  35.         int block = block(position);
  36.         if (block < words.length)
  37.             words[block] &= ~mask(position);
  38.     }

  39.     final boolean get(int position) {
  40.         int block = block(position);
  41.         return block < words.length && (words[block] & mask(position)) != 0;
  42.     }

  43.     final EWAHCompressedBitmap toEWAHCompressedBitmap() {
  44.         EWAHCompressedBitmap compressed = new EWAHCompressedBitmap(
  45.                 words.length);
  46.         int runningEmptyWords = 0;
  47.         long lastNonEmptyWord = 0;
  48.         for (long word : words) {
  49.             if (word == 0) {
  50.                 runningEmptyWords++;
  51.                 continue;
  52.             }

  53.             if (lastNonEmptyWord != 0)
  54.                 compressed.addWord(lastNonEmptyWord);

  55.             if (runningEmptyWords > 0) {
  56.                 compressed.addStreamOfEmptyWords(false, runningEmptyWords);
  57.                 runningEmptyWords = 0;
  58.             }

  59.             lastNonEmptyWord = word;
  60.         }
  61.         int bitsThatMatter = 64 - Long.numberOfLeadingZeros(lastNonEmptyWord);
  62.         if (bitsThatMatter > 0)
  63.             compressed.addWord(lastNonEmptyWord, bitsThatMatter);
  64.         return compressed;
  65.     }

  66.     private static final int block(int position) {
  67.         return position >> 6;
  68.     }

  69.     private static final long mask(int position) {
  70.         return 1L << position;
  71.     }
  72. }