Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
29 changed files
with
4,317 additions
and
348 deletions.
There are no files selected for viewing
112 changes: 112 additions & 0 deletions
112
common/src/main/java/org/apache/drill/common/AutoCloseablePointer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/** | ||
* 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.drill.common; | ||
|
||
/** | ||
* A class similar to Pointer<>, but with features unique to holding | ||
* AutoCloseable pointers. The AutoCloseablePointer<> must be closed | ||
* when it will no longer be used. | ||
* | ||
* <p>If you're familiar with C++/Boost's shared_ptr<>, you might recognize | ||
* some of the features here.</p> | ||
* | ||
* @param <T> type of the pointer | ||
*/ | ||
public final class AutoCloseablePointer<T extends AutoCloseable> implements AutoCloseable { | ||
private T pointer; | ||
|
||
/** | ||
* Constructor for a null-valued pointer. | ||
*/ | ||
public AutoCloseablePointer() { | ||
pointer = null; | ||
} | ||
|
||
/** | ||
* Constructor for a pointer value. | ||
* | ||
* @param pointer the initial pointer value | ||
*/ | ||
public AutoCloseablePointer(final T pointer) { | ||
this.pointer = pointer; | ||
} | ||
|
||
@Override | ||
public void close() throws Exception { | ||
assign(null); | ||
} | ||
|
||
/** | ||
* Get the raw pointer out for use. | ||
* | ||
* @return the raw pointer | ||
*/ | ||
public T get() { | ||
return pointer; | ||
} | ||
|
||
/** | ||
* The caller adopts the pointer; the holder is set to | ||
* null, and will no longer be responsible for close()ing this pointer. | ||
* | ||
* @return the pointer being adopted; may be null | ||
*/ | ||
public T adopt() { | ||
final T p = pointer; | ||
pointer = null; | ||
return p; | ||
} | ||
|
||
/** | ||
* Assign a new pointer to this holder. Any currently held pointer | ||
* will first be closed. If closing the currently held pointer throws | ||
* an exception, the new pointer is still assigned, and the holder must still | ||
* be closed to close that. | ||
* | ||
* <p>This makes it convenient to assign a new pointer without having to check | ||
* for a previous value and worry about cleaning it up; this does all that.</p> | ||
* | ||
* @param newP the new pointer to hold | ||
* @throws Exception any exception thrown by closing the currently held | ||
* pointer | ||
*/ | ||
public void assign(final T newP) throws Exception { | ||
try { | ||
if (pointer != null) { | ||
pointer.close(); | ||
} | ||
} finally { | ||
pointer = newP; | ||
} | ||
} | ||
|
||
/** | ||
* Like {@link #assign(AutoCloseable)}, except that any exception thrown | ||
* by closing the previously held pointer is wrapped with (an unchecked) | ||
* {@link RuntimeException}. | ||
* | ||
* @param newP the new pointer to hold | ||
*/ | ||
public void assignNoChecked(final T newP) { | ||
try { | ||
assign(newP); | ||
} catch(final Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
common/src/main/java/org/apache/drill/common/DrillCloseables.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* 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.drill.common; | ||
|
||
import java.io.Closeable; | ||
import java.io.IOException; | ||
|
||
/** | ||
* Provides additional functionality to Guava's Closeables. | ||
*/ | ||
public class DrillCloseables { | ||
/** | ||
* Constructor. Prevents construction for class of static utilities. | ||
*/ | ||
private DrillCloseables() { | ||
} | ||
|
||
/** | ||
* Close() a {@see java.io.Closeable} without throwing a (checked) | ||
* {@see java.io.IOException}. This wraps the close() call with a | ||
* try-catch that will rethrow an IOException wrapped with a | ||
* {@see java.lang.RuntimeException}, providing a way to call close() | ||
* without having to do the try-catch everywhere or propagate the IOException. | ||
* | ||
* <p>Guava has deprecated {@see com.google.common.io.Closeables.closeQuietly()} | ||
* as described in | ||
* {@link https://code.google.com/p/guava-libraries/issues/detail?id=1118}. | ||
* | ||
* @param closeable the Closeable to close | ||
* @throws RuntimeException if an IOException occurs; the IOException is | ||
* wrapped by the RuntimeException | ||
*/ | ||
public static void closeNoChecked(final Closeable closeable) { | ||
try { | ||
closeable.close(); | ||
} catch(final IOException e) { | ||
throw new RuntimeException("IOException while closing", e); | ||
} | ||
} | ||
} |
179 changes: 179 additions & 0 deletions
179
common/src/main/java/org/apache/drill/common/HistoricalLog.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
/** | ||
* 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.drill.common; | ||
|
||
import java.util.LinkedList; | ||
|
||
import org.slf4j.Logger; | ||
|
||
/** | ||
* Utility class that can be used to log activity within a class | ||
* for later logging and debugging. Supports recording events and | ||
* recording the stack at the time they occur. | ||
*/ | ||
public class HistoricalLog { | ||
private static class Event { | ||
private final String note; // the event text | ||
private final StackTrace stackTrace; // where the event occurred | ||
|
||
public Event(final String note) { | ||
this.note = note; | ||
stackTrace = new StackTrace(); | ||
} | ||
} | ||
|
||
private final LinkedList<Event> history = new LinkedList<>(); | ||
private final String idString; // the formatted id string | ||
private Event firstEvent; // the first stack trace recorded | ||
private final int limit; // the limit on the number of events kept | ||
|
||
/** | ||
* Constructor. The format string will be formatted and have its arguments | ||
* substituted at the time this is called. | ||
* | ||
* @param idStringFormat {@link String#format} format string that can be used | ||
* to identify this object in a log. Including some kind of unique identifier | ||
* that can be associated with the object instance is best. | ||
* @param args for the format string, or nothing if none are required | ||
*/ | ||
public HistoricalLog(final String idStringFormat, Object... args) { | ||
this(Integer.MAX_VALUE, idStringFormat, args); | ||
} | ||
|
||
/** | ||
* Constructor. The format string will be formatted and have its arguments | ||
* substituted at the time this is called. | ||
* | ||
* <p>This form supports the specification of a limit that will limit the | ||
* number of historical entries kept (which keeps down the amount of memory | ||
* used). With the limit, the first entry made is always kept (under the | ||
* assumption that this is the creation site of the object, which is usually | ||
* interesting), and then up to the limit number of entries are kept after that. | ||
* Each time a new entry is made, the oldest that is not the first is dropped. | ||
* </p> | ||
* | ||
* @param limit the maximum number of historical entries that will be kept, | ||
* not including the first entry made | ||
* @param idStringFormat {@link String#format} format string that can be used | ||
* to identify this object in a log. Including some kind of unique identifier | ||
* that can be associated with the object instance is best. | ||
* @param args for the format string, or nothing if none are required | ||
*/ | ||
public HistoricalLog(final int limit, final String idStringFormat, Object... args) { | ||
this.limit = limit; | ||
this.idString = String.format(idStringFormat, args); | ||
} | ||
|
||
/** | ||
* Record an event. Automatically captures the stack trace at the time this is | ||
* called. The format string will be formatted and have its arguments substituted | ||
* at the time this is called. | ||
* | ||
* @param noteFormat {@link String#format} format string that describes the event | ||
* @param args for the format string, or nothing if none are required | ||
*/ | ||
public synchronized void recordEvent(final String noteFormat, Object... args) { | ||
final String note = String.format(noteFormat, args); | ||
final Event event = new Event(note); | ||
if (firstEvent == null) { | ||
firstEvent = event; | ||
} | ||
if (history.size() == limit) { | ||
history.removeFirst(); | ||
} | ||
history.add(event); | ||
} | ||
|
||
/** | ||
* Write the history of this object to the given {@link StringBuilder}. The history | ||
* includes the identifying string provided at construction time, and all the recorded | ||
* events with their stack traces. | ||
* | ||
* @param sb {@link StringBuilder} to write to | ||
*/ | ||
public void buildHistory(final StringBuilder sb) { | ||
buildHistory(sb, null); | ||
} | ||
|
||
/** | ||
* Write the history of this object to the given {@link StringBuilder}. The history | ||
* includes the identifying string provided at construction time, and all the recorded | ||
* events with their stack traces. | ||
* | ||
* @param sb {@link StringBuilder} to write to | ||
* @param additional an extra string that will be written between the identifying | ||
* information and the history; often used for a current piece of state | ||
*/ | ||
public synchronized void buildHistory(final StringBuilder sb, final CharSequence additional) { | ||
sb.append('\n') | ||
.append(idString); | ||
|
||
if (additional != null) { | ||
sb.append('\n') | ||
.append(additional) | ||
.append('\n'); | ||
} | ||
|
||
sb.append(" event log\n"); | ||
|
||
if (firstEvent != null) { | ||
sb.append(" ") | ||
.append(firstEvent.note) | ||
.append('\n'); | ||
firstEvent.stackTrace.writeToBuilder(sb, 4); | ||
|
||
for(final Event event : history) { | ||
if (event == firstEvent) { | ||
continue; | ||
} | ||
|
||
sb.append(" ") | ||
.append(event.note) | ||
.append('\n'); | ||
|
||
event.stackTrace.writeToBuilder(sb, 4); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Write the history of this object to the given {@link Logger}. The history | ||
* includes the identifying string provided at construction time, and all the recorded | ||
* events with their stack traces. | ||
* | ||
* @param logger {@link Logger} to write to | ||
* @param additional an extra string that will be written between the identifying | ||
* information and the history; often used for a current piece of state | ||
*/ | ||
public void logHistory(final Logger logger, final CharSequence additional) { | ||
final StringBuilder sb = new StringBuilder(); | ||
buildHistory(sb, additional); | ||
logger.debug(sb.toString()); | ||
} | ||
|
||
/** | ||
* Write the history of this object to the given {@link Logger}. The history | ||
* includes the identifying string provided at construction time, and all the recorded | ||
* events with their stack traces. | ||
* | ||
* @param logger {@link Logger} to write to | ||
*/ | ||
public void logHistory(final Logger logger) { | ||
logHistory(logger, null); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.