-
Notifications
You must be signed in to change notification settings - Fork 286
Implement the BlockingQueue as a wrapper around the QueueFile #201
base: master
Are you sure you want to change the base?
Conversation
…e QueueFile The resulting BlockingFileQueue is thread-safe and unbounded. Thread-safety is implemented with a single lock around all operations against the backing queue.
7fb0b22
to
27d865b
Compare
I switched to the ObjectQueue as the backing structure as I generally agree that it's more useful, however I'm not entirely sure what overhead this adds in case I'm really only using byte[] buffers (as I am in the project where code this originally comes from). |
The current implementation is also unbounded and I don't intend to implement an upper bound because the backing queue also doesn't have an upper bound. |
I'll take a look into directly accessing QueueFile for BlockingQueue<byte[]> instance without duplicating the whole class. |
75f2593
to
6764bc3
Compare
…e QueueFile Switched to an ObjectQueue<T> as the backing store and delegate closable.
6764bc3
to
c799abe
Compare
…e QueueFile QueueFile is now an ObjectQueue<byte[]> and can thus be used without overhead in the blocking queue. ObjectQueue's file():QueueFile method has been moved to FileObjectQueue where it fits better as InMemoryObjectQueue doesn't have a backing file. Removed the ByteArrayConverter again as it was the initial attempt to optimize for byte[] queues.
…e QueueFile sneakyfy the IO exception as done in other places.
…e QueueFile Increased coverage and minor cleanup
@f2prateek So that's the state I would go with. In order to implement |
…e QueueFile minor cleanup
* | ||
* @param <E> the element type | ||
*/ | ||
public class BlockingObjectQueue<E> implements BlockingQueue<E>, Closeable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final
|
||
private final ObjectQueue<E> queue; | ||
|
||
public BlockingObjectQueue(ObjectQueue<E> queue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about just having the static factory?
* @param <T> the element type | ||
* @return a BlockObjectQueue implementation | ||
*/ | ||
public static <T> BlockingObjectQueue<T> create(QueueFile qf, ObjectQueue.Converter<T> conv) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just take in an ObjectQueue<T>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are convenience methods, I'd rather remove the static factories than the constructor. I did them similar to the one in ObjectQueue.
* @param qf the queue file which should not be shared to other places | ||
* @return a BlockObjectQueue implementation | ||
*/ | ||
public static BlockingObjectQueue<byte[]> create(QueueFile qf) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto above. maybe can remove this.
return true; | ||
} catch (IOException e) { | ||
QueueFile.<Error>getSneakyThrowable(e); | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about throw QueueFile.<Error>getSneakyThrowable(e);
? then we don't need the unreachable return statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing outside the method doesn't work (I tried it, do you know a way that works?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, should work. there are some existing usages.
throw QueueFile.<Error>getSneakyThrowable(e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It must have been late... :D
try { | ||
queue.clear(); | ||
} catch (IOException e) { | ||
QueueFile.<Error>getSneakyThrowable(e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: throws for consistency and clarity.
@@ -25,9 +26,6 @@ | |||
return new InMemoryObjectQueue<>(); | |||
} | |||
|
|||
/** The underlying {@link QueueFile} backing this queue, or null if it's only in memory. */ | |||
public abstract @Nullable QueueFile file(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this has value. let's leave it.
if we do make QueueFile an ObjectQueue, we could rename this API to queueFile()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with file():QueueFile
in ObjectQueue
you would need to null-check on the result to be save, now with the method in FileObjectQueue
you have to check for the implementation and are then guaranteed to get a QueueFile
back, not a huge difference.
I think this could be improved by making the factory methods return the specific implementations.
@@ -424,11 +423,6 @@ private long remainingBytes() { | |||
return fileLength - usedBytes(); | |||
} | |||
|
|||
/** Returns true if this queue contains no entries. */ | |||
public boolean isEmpty() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's leave this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's inherited from ObjectQueue
* | ||
* @throws NoSuchElementException if the queue is empty | ||
*/ | ||
public void remove() throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and leave this. people use QueueFile directly, and the convenience APIs are convenient!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's inherited from ObjectQueue
@@ -52,7 +51,7 @@ | |||
* | |||
* @author Bob Lee ([email protected]) | |||
*/ | |||
public final class QueueFile implements Closeable, Iterable<byte[]> { | |||
public final class QueueFile extends ObjectQueue<byte[]> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmmm, could you get the same functionality by making a FileObjectQueue<byte[]>? a little roundabout, but it keeps QueueFile focused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the benefit, can you elaborate?
…e QueueFile more cleanup and a new test
…e QueueFile directly throw the sneaky exceptions
Any updates here? |
@NightlyNexus I guess this won't be merged? |
The resulting BlockingFileQueue is thread-safe and unbounded.
Thread-safety is implemented with a single lock around all operations against the backing queue.
Closes #198