All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.nfgraph.compressed.HashSetOrdinalSet Maven / Gradle / Ivy

/*
 *  Copyright 2013 Netflix, Inc.
 *
 *     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.netflix.nfgraph.compressed;

import com.netflix.nfgraph.OrdinalIterator;
import com.netflix.nfgraph.OrdinalSet;
import com.netflix.nfgraph.spec.NFPropertySpec;
import com.netflix.nfgraph.util.ByteArrayReader;
import com.netflix.nfgraph.util.Mixer;

/**
 * An implementation of {@link OrdinalSet}, returned for connections represented as variable-byte hashed integer arrays in an {@link NFCompressedGraph}.

* * A variable-byte hashed integer array representation contains between one and five bytes per connection. The ordinal for each * connection is hashed into a byte array, then represented as a variant on the variable-byte integers used in the {@link CompactOrdinalSet}.

* * The byte array can be thought of as a open-addressed hash table, with each byte representing a single bucket. Because * values may be represented in more than one byte, single values may spill over into multiple buckets. The beginning of the * value is indicated by an unset sign bit, and will be located at or after the bucket to which it is hashed. If the value's * first bit is not located at the hashed position, it will be located in a position after the bucket with no empty buckets in between.

* * This implementation provides O(1) time for contains(), but is not as memory-efficient as a {@link CompactOrdinalSet}.

* * This representation for a connection set can be configured for an {@link NFPropertySpec} using {@link NFPropertySpec#HASH}. * * @see Compact Representations * */ public class HashSetOrdinalSet extends OrdinalSet { private final ByteArrayReader reader; private int size = Integer.MIN_VALUE; public HashSetOrdinalSet(ByteArrayReader reader) { this.reader = reader; } @Override public OrdinalIterator iterator() { return new HashSetOrdinalIterator(reader.copy()); } @Override public boolean contains(int value) { value += 1; int offset = (Mixer.hashInt(value) & (reader.length() - 1)); offset = seekBeginByte(offset); while(reader.getByte(offset) != 0) { int readValue = reader.getByte(offset); offset = nextOffset(offset); while((reader.getByte(offset) & 0x80) != 0) { readValue <<= 7; readValue |= reader.getByte(offset) & 0x7F; offset = nextOffset(offset); } if(readValue == value) return true; } return false; } @Override public int size() { if(size == Integer.MIN_VALUE) size = countHashEntries(); return size; } private int seekBeginByte(int offset) { while((reader.getByte(offset) & 0x80) != 0) offset = nextOffset(offset); return offset; } private int nextOffset(int offset) { offset++; if(offset >= reader.length()) { offset = 0; } return offset; } private int countHashEntries() { int counter = 0; for(int i=0;i





© 2015 - 2025 Weber Informatics LLC | Privacy Policy