package mil.nga.giat.geowave.core.store.data.visibility; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; import org.apache.commons.lang3.ArrayUtils; import net.sf.json.JSONException; import net.sf.json.JSONObject; import mil.nga.giat.geowave.core.index.ByteArrayId; import mil.nga.giat.geowave.core.index.Mergeable; import mil.nga.giat.geowave.core.store.adapter.statistics.AbstractDataStatistics; import mil.nga.giat.geowave.core.store.adapter.statistics.DataStatistics; import mil.nga.giat.geowave.core.store.adapter.statistics.DataStatisticsStore; import mil.nga.giat.geowave.core.store.base.DataStoreEntryInfo; import mil.nga.giat.geowave.core.store.base.DataStoreEntryInfo.FieldInfo; import mil.nga.giat.geowave.core.store.callback.DeleteCallback; import mil.nga.giat.geowave.core.store.index.PrimaryIndex; public class DifferingFieldVisibilityEntryCount<T> extends AbstractDataStatistics<T> implements DeleteCallback<T> { public static final ByteArrayId STATS_TYPE = new ByteArrayId( "DIFFERING_VISIBILITY_COUNT"); private long entriesWithDifferingFieldVisibilities = 0; protected DifferingFieldVisibilityEntryCount() { super(); } public long getEntriesWithDifferingFieldVisibilities() { return entriesWithDifferingFieldVisibilities; } public boolean isAnyEntryDifferingFieldVisiblity() { return entriesWithDifferingFieldVisibilities > 0; } private DifferingFieldVisibilityEntryCount( final ByteArrayId dataAdapterId, final ByteArrayId statisticsId, final long entriesWithDifferingFieldVisibilities ) { super( dataAdapterId, composeId(statisticsId)); this.entriesWithDifferingFieldVisibilities = entriesWithDifferingFieldVisibilities; } public DifferingFieldVisibilityEntryCount( final ByteArrayId dataAdapterId, final ByteArrayId statisticsId ) { super( dataAdapterId, composeId(statisticsId)); } public static ByteArrayId composeId( final ByteArrayId statisticsId ) { return composeId( STATS_TYPE.getString(), statisticsId.getString()); } @Override public DataStatistics<T> duplicate() { return new DifferingFieldVisibilityEntryCount<>( dataAdapterId, statisticsId, entriesWithDifferingFieldVisibilities); } @Override public byte[] toBinary() { final ByteBuffer buf = super.binaryBuffer(8); buf.putLong(entriesWithDifferingFieldVisibilities); return buf.array(); } @Override public void fromBinary( final byte[] bytes ) { final ByteBuffer buf = super.binaryBuffer(bytes); entriesWithDifferingFieldVisibilities = buf.getLong(); } @Override public void entryIngested( final DataStoreEntryInfo entryInfo, final T entry ) { if (entryHasDifferentVisibilities(entryInfo)) { entriesWithDifferingFieldVisibilities++; } } @Override public void entryDeleted( final DataStoreEntryInfo entryInfo, final T entry ) { if (entryHasDifferentVisibilities(entryInfo)) { entriesWithDifferingFieldVisibilities--; } } @Override public void merge( final Mergeable merge ) { if ((merge != null) && (merge instanceof DifferingFieldVisibilityEntryCount)) { entriesWithDifferingFieldVisibilities += ((DifferingFieldVisibilityEntryCount) merge).entriesWithDifferingFieldVisibilities; } } private static boolean entryHasDifferentVisibilities( final DataStoreEntryInfo entryInfo ) { if ((entryInfo != null) && (entryInfo.getFieldInfo() != null)) { final List<FieldInfo<?>> fields = entryInfo.getFieldInfo(); // if there is 0 or 1 field, there won't be differing visibilities if (fields.size() > 1) { final byte[] visibility = fields.get( 0).getVisibility(); for (int i = 1; i < fields.size(); i++) { if (!Arrays.equals( visibility, fields.get( i).getVisibility())) { return true; } } } } return false; } public static DifferingFieldVisibilityEntryCount getVisibilityCounts( final PrimaryIndex index, final List<ByteArrayId> adapterIdsToQuery, final DataStatisticsStore statisticsStore, final String... authorizations ) { DifferingFieldVisibilityEntryCount combinedVisibilityCount = null; for (final ByteArrayId adapterId : adapterIdsToQuery) { final DifferingFieldVisibilityEntryCount adapterVisibilityCount = (DifferingFieldVisibilityEntryCount) statisticsStore .getDataStatistics( adapterId, DifferingFieldVisibilityEntryCount.composeId(index.getId()), authorizations); if (combinedVisibilityCount == null) { combinedVisibilityCount = adapterVisibilityCount; } else { combinedVisibilityCount.merge(adapterVisibilityCount); } } return combinedVisibilityCount; } /** * Convert Differing Visibility statistics to a JSON object */ public JSONObject toJSONObject() throws JSONException { JSONObject jo = new JSONObject(); jo.put( "type", STATS_TYPE.getString()); jo.put( "statisticsID", statisticsId.getString()); jo.put( "count", entriesWithDifferingFieldVisibilities); return jo; } }