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

org.apache.datasketches.memory.BaseBuffer Maven / Gradle / Ivy

There is a newer version: 5.0.0
Show newest version
/*
 * 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.datasketches.memory;

/**
 * A new positional API. This is different from and simpler than Java Buffer positional approach.
 * 
  • All based on longs instead of ints.
  • *
  • Eliminated "mark". Rarely used and confusing with its silent side effects.
  • *
  • The invariants are {@code 0 <= start <= position <= end <= capacity}.
  • *
  • It always starts up as (0, 0, capacity, capacity).
  • *
  • You set (start, position, end) in one call with * {@link #setStartPositionEnd(long, long, long)}
  • *
  • Position can be set directly or indirectly when using the positional get/put methods. *
  • Added incrementPosition(long), which is much easier when you know the increment.
  • *
  • This approach eliminated a number of methods and checks, and has no unseen side effects, * e.g., mark being invalidated.
  • *
  • Clearer method naming (IMHO).
  • *
* * @author Lee Rhodes */ public abstract class BaseBuffer extends BaseState { private long capacity; private long start = 0; private long pos = 0; private long end; //Pass-through ctor BaseBuffer(final Object unsafeObj, final long nativeBaseOffset, final long regionOffset, final long capacityBytes) { super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes); capacity = end = capacityBytes; } /** * Increments the current position by the given increment. * Asserts that the resource is valid and that the positional invariants are not violated, * otherwise, if asserts are enabled throws an {@link AssertionError}. * @param increment the given increment * @return BaseBuffer */ public final BaseBuffer incrementPosition(final long increment) { incrementAndAssertPositionForRead(pos, increment); return this; } /** * Increments the current position by the given increment. * Checks that the resource is valid and that the positional invariants are not violated, * otherwise throws an {@link IllegalArgumentException}. * @param increment the given increment * @return BaseBuffer */ public final BaseBuffer incrementAndCheckPosition(final long increment) { incrementAndCheckPositionForRead(pos, increment); return this; } /** * Gets the end position * @return the end position */ public final long getEnd() { return end; } /** * Gets the current position * @return the current position */ public final long getPosition() { return pos; } /** * Gets start position * @return start position */ public final long getStart() { return start; } /** * The number of elements remaining between the current position and the end position * @return {@code (end - position)} */ public final long getRemaining() { return end - pos; } /** * Returns true if there are elements remaining between the current position and the end position * @return {@code (end - position) > 0} */ public final boolean hasRemaining() { return (end - pos) > 0; } /** * Resets the current position to the start position, * This does not modify any data. * @return BaseBuffer */ public final BaseBuffer resetPosition() { pos = start; return this; } /** * Sets the current position. * Asserts that the positional invariants are not violated, * otherwise, if asserts are enabled throws an {@link AssertionError}. * @param position the given current position. * @return BaseBuffer */ public final BaseBuffer setPosition(final long position) { assertInvariants(start, position, end, capacity); pos = position; return this; } /** * Sets the current position. * Checks that the positional invariants are not violated, * otherwise, throws an {@link IllegalArgumentException}. * @param position the given current position. * @return BaseBuffer */ public final BaseBuffer setAndCheckPosition(final long position) { checkInvariants(start, position, end, capacity); pos = position; return this; } /** * Sets start position, current position, and end position. * Asserts that the positional invariants are not violated, * otherwise, if asserts are enabled throws an {@link AssertionError}. * @param start the start position in the buffer * @param position the current position between the start and end * @param end the end position in the buffer * @return BaseBuffer */ public final BaseBuffer setStartPositionEnd(final long start, final long position, final long end) { assertInvariants(start, position, end, capacity); this.start = start; this.end = end; pos = position; return this; } /** * Sets start position, current position, and end position. * Checks that the positional invariants are not violated, * otherwise, throws an {@link IllegalArgumentException}. * @param start the start position in the buffer * @param position the current position between the start and end * @param end the end position in the buffer * @return BaseBuffer */ public final BaseBuffer setAndCheckStartPositionEnd(final long start, final long position, final long end) { checkInvariants(start, position, end, capacity); this.start = start; this.end = end; pos = position; return this; } //RESTRICTED final void incrementAndAssertPositionForRead(final long position, final long increment) { assertValid(); final long newPos = position + increment; assertInvariants(start, newPos, end, capacity); pos = newPos; } final void incrementAndAssertPositionForWrite(final long position, final long increment) { assertValid(); assert !isReadOnly() : "Buffer is read-only."; final long newPos = position + increment; assertInvariants(start, newPos, end, capacity); pos = newPos; } final void incrementAndCheckPositionForRead(final long position, final long increment) { checkValid(); final long newPos = position + increment; checkInvariants(start, newPos, end, capacity); pos = newPos; } final void incrementAndCheckPositionForWrite(final long position, final long increment) { checkValidForWrite(); final long newPos = position + increment; checkInvariants(start, newPos, end, capacity); pos = newPos; } final void checkValidForWrite() { checkValid(); if (isReadOnly()) { throw new ReadOnlyException("Buffer is read-only."); } } /** * The invariants equation is: {@code 0 <= start <= position <= end <= capacity}. * If this equation is violated and assertions are enabled, * an AssertionError will be thrown. * @param start the lowest start position * @param pos the current position * @param end the highest position * @param cap the capacity of the backing buffer. */ static final void assertInvariants(final long start, final long pos, final long end, final long cap) { assert (start | pos | end | cap | (pos - start) | (end - pos) | (cap - end) ) >= 0L : "Violation of Invariants: " + "start: " + start + " <= pos: " + pos + " <= end: " + end + " <= cap: " + cap + "; (pos - start): " + (pos - start) + ", (end - pos): " + (end - pos) + ", (cap - end): " + (cap - end); } /** * The invariants equation is: {@code 0 <= start <= position <= end <= capacity}. * If this equation is violated an IllegalArgumentException will be thrown. * @param start the lowest start position * @param pos the current position * @param end the highest position * @param cap the capacity of the backing buffer. */ static final void checkInvariants(final long start, final long pos, final long end, final long cap) { if ((start | pos | end | cap | (pos - start) | (end - pos) | (cap - end) ) < 0L) { throw new IllegalArgumentException( "Violation of Invariants: " + "start: " + start + " <= pos: " + pos + " <= end: " + end + " <= cap: " + cap + "; (pos - start): " + (pos - start) + ", (end - pos): " + (end - pos) + ", (cap - end): " + (cap - end) ); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy