Skip to content
This repository has been archived by the owner on Oct 25, 2024. It is now read-only.

Implement the BlockingQueue as a wrapper around the QueueFile #201

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

pschichtel
Copy link

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

…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.
@pschichtel pschichtel force-pushed the blocking-queue branch 4 times, most recently from 7fb0b22 to 27d865b Compare October 25, 2018 00:52
@pschichtel
Copy link
Author

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).

@pschichtel
Copy link
Author

pschichtel commented Oct 25, 2018

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.
If an upper bound is added to the QueueFile in the future it would be good to add one here as well.

@pschichtel
Copy link
Author

I'll take a look into directly accessing QueueFile for BlockingQueue<byte[]> instance without duplicating the whole class.

@pschichtel pschichtel force-pushed the blocking-queue branch 2 times, most recently from 75f2593 to 6764bc3 Compare October 25, 2018 22:42
…e QueueFile

Switched to an ObjectQueue<T> as the backing store and delegate closable.
…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
@pschichtel
Copy link
Author

pschichtel commented Oct 26, 2018

@f2prateek So that's the state I would go with. In order to implement ObjectQueue<byte[]> on QueueFile I had to break the current API a little as file():QueueFile on ObjectQueue conflicted with file():File in QueueFile, so I moved file():QueueFile to FileObjectQueue. This way we don't have the noop file():QueueFile on InMemoryObjectQueue and QueueFile can implement ObjectQueue<byte[]> basically as-is.

*
* @param <E> the element type
*/
public class BlockingObjectQueue<E> implements BlockingQueue<E>, Closeable {
Copy link
Contributor

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) {
Copy link
Contributor

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) {
Copy link
Contributor

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>?

Copy link
Author

@pschichtel pschichtel Nov 3, 2018

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) {
Copy link
Contributor

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;
Copy link
Contributor

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.

Copy link
Author

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?).

Copy link
Contributor

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);

Copy link
Author

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);
Copy link
Contributor

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();
Copy link
Contributor

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().

Copy link
Author

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() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's leave this.

Copy link
Author

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 {
Copy link
Contributor

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!

Copy link
Author

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[]> {
Copy link
Contributor

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.

Copy link
Author

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?

@pschichtel
Copy link
Author

Any updates here?

@pschichtel
Copy link
Author

@NightlyNexus I guess this won't be merged?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BlockingQueue implementation and other interfaces
3 participants