001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.modeshape.common.collection.ring; 018 019import org.modeshape.common.collection.ring.GarbageCollectingConsumer.Collectable; 020 021/** 022 * A cursor in a ring buffer at which point information can be added to the buffer. A ring buffer uses its cursor to keep track of 023 * the {@link Pointer positions} of all consumers (to keep from overlapping them), and to ensure that entries are added to the 024 * buffer in the correct fashion using a two-phase process: 025 * <ol> 026 * <li>{@link #claim() Claim} the next position for writing</li> 027 * <li>{@link #publish Publish} that one or more positions has been successfully populated with entries and that the consumers are 028 * free to consume them</li> 029 * </ol> 030 * 031 * @author Randall Hauch (rhauch@redhat.com) 032 */ 033public interface Cursor extends DependentOnPointers { 034 035 /** 036 * Get the size of the buffer that this cursor operates against. 037 * 038 * @return the size of the ring buffer; always positive and a power of 2 039 */ 040 int getBufferSize(); 041 042 /** 043 * Get the current position that can be read. 044 * 045 * @return the position for entries that have been published. 046 */ 047 long getCurrent(); 048 049 /** 050 * Claim the next position for writing and publishing. This method blocks until the next position is available. 051 * 052 * @return the position that is available for publishing 053 */ 054 long claim(); 055 056 /** 057 * Claim a batch of positions for writing and publishing. This method blocks until all desired positions are available. 058 * 059 * @param number the number of positions to be claimed; must be greater than 0 060 * @return the largest position that is available for publishing 061 */ 062 long claim( int number ); 063 064 /** 065 * Publish the supplied position, making it available for consumers. 066 * 067 * @param position the position that is now available for consumers 068 * @return true if the position was published, or false if not 069 */ 070 boolean publish( long position ); 071 072 /** 073 * Get the highest published position that is equal to or between the supplied lower and upper positions. 074 * 075 * @param lowerPosition the lowest potential position 076 * @param upperPosition the highest potential position 077 * @return the highest available position 078 */ 079 long getHighestPublishedPosition( long lowerPosition, 080 long upperPosition ); 081 082 /** 083 * Add a new barrier that a consumer can use the wait for the next available positions. 084 * 085 * @return the new barrier; never null 086 */ 087 PointerBarrier newBarrier(); 088 089 /** 090 * Return a new pointer that starts at this cursor's current position, ensuring that this cursor always 091 * {@link #stayBehind(Pointer...) stays behind} it on the ring buffer. 092 * 093 * @return the new pointer 094 */ 095 Pointer newPointer(); 096 097 /** 098 * Signal that the consumers should wake up if they are blocked on the barrier. 099 */ 100 void signalConsumers(); 101 102 /** 103 * Signal that no more entries will be written and that the {@link #newBarrier() barriers} will not block on this cursor and 104 * should return a negative number from {@link PointerBarrier#waitFor(long)}. 105 */ 106 void complete(); 107 108 /** 109 * Return whether this cursor has {@link #complete() completed} normally. 110 * 111 * @return true if this cursor is complete, or false otherwise 112 */ 113 boolean isComplete(); 114 115 GarbageCollectingConsumer createGarbageCollectingConsumer( Collectable collectable ); 116}