| // Copyright (C) 2022 The Android Open Source Project |
| // |
| // Licensed 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 com.google.gerrit.common; |
| |
| import java.util.BitSet; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| /** |
| * A space efficient Table for Booleans. This Table takes advantage of the fact that the values |
| * stored in it are all Booleans and uses BitSets to make this very space efficient. |
| */ |
| public class BooleanTable<R, C> { |
| protected class Row { |
| public final BitSet hasValues = new BitSet(); |
| public final BitSet values = new BitSet(); |
| |
| public void setPosition(int position, Boolean value) { |
| if (value != null) { |
| values.set(position, value); |
| } |
| hasValues.set(position, value != null); |
| } |
| |
| public Boolean getPosition(int position) { |
| if (hasValues.get(position)) { |
| return values.get(position); |
| } |
| return null; |
| } |
| } |
| |
| protected Map<R, Row> rowByRow = new HashMap<>(); |
| protected Map<C, Integer> positionByColumn = new HashMap<>(); |
| protected int highestPosition = -1; |
| |
| public void put(R r, C c, Boolean v) { |
| Row row = rowByRow.computeIfAbsent(r, k -> new Row()); |
| Integer columnPosition = positionByColumn.computeIfAbsent(c, k -> nextPosition()); |
| row.setPosition(columnPosition, v); |
| } |
| |
| protected int nextPosition() { |
| return ++highestPosition; |
| } |
| |
| public Boolean get(R r, C c) { |
| Row row = rowByRow.get(r); |
| if (row != null) { |
| Integer columnPosition = positionByColumn.get(c); |
| if (columnPosition != null) { |
| return row.getPosition(columnPosition); |
| } |
| } |
| return null; |
| } |
| } |