下面列出了java.util.ArrayDeque#removeFirst ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Given a vertex, find all of the vertices in its component.
*
* @param rg The graph containing the vertex.
* @param seedVxId The vertex to start from.
*
* @return A Set<Integer> containing all of the vertices in the same
* component as rootVxId.
*/
public static Set<Integer> getComponentContainingVertex(final GraphReadMethods rg, final int seedVxId) {
final Set<Integer> component = new HashSet<>();
final ArrayDeque<Integer> neighbours = new ArrayDeque<>();
neighbours.add(seedVxId);
component.add(seedVxId);
while (!neighbours.isEmpty()) {
final Integer vxId = neighbours.removeFirst();
final int nNeighbours = rg.getVertexNeighbourCount(vxId);
for (int nbPosition = 0; nbPosition < nNeighbours; nbPosition++) {
final int nbId = rg.getVertexNeighbour(vxId, nbPosition);
if (!component.contains(nbId)) {
neighbours.add(nbId);
component.add(nbId);
}
}
}
return component;
}
/**
* Given a vertex, find all of the vertices in its component.
*
* @param graph The graph containing the vertex.
* @param seedVxId The vertex to start from.
* @param verticesToArrange a BitSet specifying which vertices to arrange.
*
* @return A Set<Integer%gt; containing all of the vertices in the same
* component as rootVxId.
*/
@Deprecated
public static Set<Integer> getComponentContainingVertex(final GraphReadMethods graph, final int seedVxId, final BitSet verticesToArrange) {
final Set<Integer> component = new HashSet<>();
final ArrayDeque<Integer> neighbours = new ArrayDeque<>();
neighbours.add(seedVxId);
component.add(seedVxId);
while (!neighbours.isEmpty()) {
final Integer vxId = neighbours.removeFirst();
// component.add(vxId);
// Debug.debug("@added to component: %d (%d)\n", vxId, component.size());
final int nNeighbours = graph.getVertexNeighbourCount(vxId);
for (int nbPosition = 0; nbPosition < nNeighbours; nbPosition++) {
final int nbId = graph.getVertexNeighbour(vxId, nbPosition);
if (verticesToArrange.get(nbId) && !component.contains(nbId)) {
neighbours.add(nbId);
component.add(nbId);
}
}
}
return component;
}
public static void readStream(
InputStream inputStream,
Charset charset,
ArrayDeque<String> lines,
int maxMessageSize,
Consumer<String> droppedLinesConsumer) throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charset);
BufferedReader reader = new BufferedReader(inputStreamReader);
int messageSize = 0;
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
if (maxMessageSize > -1) {
messageSize += line.length();
while (messageSize > maxMessageSize) {
String removedLine = lines.removeFirst();
messageSize -= removedLine.length();
droppedLinesConsumer.accept(removedLine);
}
}
lines.add(line);
}
}
public int[] maxSlidingWindow(int[] nums, int k) {
int len = nums.length;
if (len == 0) {
return new int[0];
}
int[] res = new int[len - k + 1];
ArrayDeque<Integer> queue = new ArrayDeque<>(len);
for (int i = 0; i < len; i++) {
// 左边界滑出
if (i >= k && queue.getFirst() == i - k) {
queue.removeFirst();
}
// 在 nums[i] 加入之前考虑把不可能的值弹出
while (!queue.isEmpty() && nums[queue.getLast()] <= nums[i]) {
queue.removeLast();
}
queue.add(i);
// 记录结果
if (i >= k - 1) {
res[i - k + 1] = nums[queue.getFirst()];
}
}
return res;
}
int _countStates(DfaState<?>... starts)
{
ArrayDeque<DfaState<?>> togo = new ArrayDeque<>();
HashSet<DfaState<?>> checkSet = new HashSet<>();
for (DfaState<?> start : starts)
{
if (checkSet.add(start))
{
togo.add(start);
}
}
while(!togo.isEmpty())
{
DfaState<?> scanst = togo.removeFirst();
scanst.enumerateTransitions((c1,c2,newstate)->{
if (checkSet.add(newstate))
{
togo.add(newstate);
}
});
}
return checkSet.size();
}
/**
* isEmpty is true before add, false after
*/
public void testEmpty() {
ArrayDeque q = new ArrayDeque();
assertTrue(q.isEmpty());
q.add(new Integer(1));
assertFalse(q.isEmpty());
q.add(new Integer(2));
q.removeFirst();
q.removeFirst();
assertTrue(q.isEmpty());
}
/**
* Returns a list of all distinct paths from roots of the network to leaves. The list can be in
* arbitrary orders and can contain duplicate paths if there are multiple edges from two nodes.
*/
public static <NodeT, EdgeT> List<List<NodeT>> allPathsFromRootsToLeaves(
Network<NodeT, EdgeT> network) {
ArrayDeque<List<NodeT>> paths = new ArrayDeque<>();
// Populate the list with all roots
for (NodeT node : network.nodes()) {
if (network.inDegree(node) == 0) {
paths.add(ImmutableList.of(node));
}
}
List<List<NodeT>> distinctPathsFromRootsToLeaves = new ArrayList<>();
while (!paths.isEmpty()) {
List<NodeT> path = paths.removeFirst();
NodeT lastNode = path.get(path.size() - 1);
if (network.outDegree(lastNode) == 0) {
distinctPathsFromRootsToLeaves.add(new ArrayList<>(path));
} else {
for (EdgeT edge : network.outEdges(lastNode)) {
paths.addFirst(
ImmutableList.<NodeT>builder()
.addAll(path)
.add(network.incidentNodes(edge).target())
.build());
}
}
}
return distinctPathsFromRootsToLeaves;
}
private Tuple2<ExecutionGraph, Map<ExecutionAttemptID, Execution>> setupExecution(JobVertex v1, int dop1, JobVertex v2, int dop2) throws Exception {
v1.setParallelism(dop1);
v2.setParallelism(dop2);
v1.setInvokableClass(BatchTask.class);
v2.setInvokableClass(BatchTask.class);
final ArrayDeque<CompletableFuture<LogicalSlot>> slotFutures = new ArrayDeque<>();
for (int i = 0; i < dop1 + dop2; i++) {
slotFutures.addLast(CompletableFuture.completedFuture(new TestingLogicalSlotBuilder().createTestingLogicalSlot()));
}
final SlotProvider slotProvider = new TestingSlotProvider(ignore -> slotFutures.removeFirst());
DirectScheduledExecutorService executorService = new DirectScheduledExecutorService();
// execution graph that executes actions synchronously
ExecutionGraph eg = TestingExecutionGraphBuilder
.newBuilder()
.setFutureExecutor(executorService)
.setSlotProvider(slotProvider)
.setBlobWriter(blobWriter)
.build();
checkJobOffloaded(eg);
eg.start(ComponentMainThreadExecutorServiceAdapter.forMainThread());
List<JobVertex> ordered = Arrays.asList(v1, v2);
eg.attachJobGraph(ordered);
// schedule, this triggers mock deployment
eg.scheduleForExecution();
Map<ExecutionAttemptID, Execution> executions = eg.getRegisteredExecutions();
assertEquals(dop1 + dop2, executions.size());
return new Tuple2<>(eg, executions);
}
public static void findMaximumSlidingWindow(int[] arr,
int windowSize) {
if (arr.length < windowSize) return;
ArrayDeque<Integer> list = new ArrayDeque();
for (int i = 0; i < windowSize; i++) {
while (!list.isEmpty() && arr[i] >= arr[list.peekLast()]) {
list.removeLast();
}
list.addLast(i);
}
System.out.print(arr[list.peekFirst()] + " ");
for (int i = windowSize; i < arr.length; i++) {
while (!list.isEmpty() && arr[i] >= arr[list.peekLast()]) {
list.removeLast();
}
if (!list.isEmpty() && list.peekFirst() <= i - windowSize) {
list.removeFirst();
}
list.addLast(i);
System.out.print(arr[list.peekFirst()] + " ");
}
}
/**
* retainAll(c) retains only those elements of c and reports true if changed
*/
public void testRetainAll() {
ArrayDeque q = populatedDeque(SIZE);
ArrayDeque p = populatedDeque(SIZE);
for (int i = 0; i < SIZE; ++i) {
boolean changed = q.retainAll(p);
assertEquals(changed, (i > 0));
assertTrue(q.containsAll(p));
assertEquals(SIZE - i, q.size());
p.removeFirst();
}
}
/**
* size changes when elements added and removed
*/
public void testSize() {
ArrayDeque q = populatedDeque(SIZE);
for (int i = 0; i < SIZE; ++i) {
assertEquals(SIZE - i, q.size());
q.removeFirst();
}
for (int i = 0; i < SIZE; ++i) {
assertEquals(i, q.size());
q.add(new Integer(i));
}
}
/**
* Returns the result of applying a filter using breadth-first traversal.
*
* @param node The root node to traverse from.
* @param filter The filter to satisfy.
* @return The first node reached via BFS traversal that satisfies the filter.
*/
public static AccessibilityNodeInfoCompat searchFromBfs(
AccessibilityNodeInfoCompat node, Filter<AccessibilityNodeInfoCompat> filter) {
if (node == null) {
return null;
}
final ArrayDeque<AccessibilityNodeInfoCompat> queue = new ArrayDeque<>();
Set<AccessibilityNodeInfoCompat> visitedNodes = new HashSet<>();
queue.add(AccessibilityNodeInfoCompat.obtain(node));
try {
while (!queue.isEmpty()) {
final AccessibilityNodeInfoCompat item = queue.removeFirst();
visitedNodes.add(item);
if (filter.accept(item)) {
return item;
}
final int childCount = item.getChildCount();
for (int i = 0; i < childCount; i++) {
final AccessibilityNodeInfoCompat child = item.getChild(i);
if (child != null && !visitedNodes.contains(child)) {
queue.addLast(child);
}
}
item.recycle();
}
} finally {
while (!queue.isEmpty()) {
queue.removeFirst().recycle();
}
}
return null;
}
/**
* retainAll(c) retains only those elements of c and reports true if changed
*/
public void testRetainAll() {
ArrayDeque q = populatedDeque(SIZE);
ArrayDeque p = populatedDeque(SIZE);
for (int i = 0; i < SIZE; ++i) {
boolean changed = q.retainAll(p);
assertEquals(changed, (i > 0));
assertTrue(q.containsAll(p));
assertEquals(SIZE - i, q.size());
p.removeFirst();
}
}
/**
* removeFirst() removes first element, or throws NSEE if empty
*/
public void testRemoveFirst() {
ArrayDeque q = populatedDeque(SIZE);
for (int i = 0; i < SIZE; ++i) {
assertEquals(i, q.removeFirst());
}
try {
q.removeFirst();
shouldThrow();
} catch (NoSuchElementException success) {}
assertNull(q.peekFirst());
}
/**
* Returns a list of all distinct paths from roots of the network to leaves. The list can be in
* arbitrary orders and can contain duplicate paths if there are multiple edges from two nodes.
*/
public static <NodeT, EdgeT> List<List<NodeT>> allPathsFromRootsToLeaves(
Network<NodeT, EdgeT> network) {
ArrayDeque<List<NodeT>> paths = new ArrayDeque<>();
// Populate the list with all roots
for (NodeT node : network.nodes()) {
if (network.inDegree(node) == 0) {
paths.add(ImmutableList.of(node));
}
}
List<List<NodeT>> distinctPathsFromRootsToLeaves = new ArrayList<>();
while (!paths.isEmpty()) {
List<NodeT> path = paths.removeFirst();
NodeT lastNode = path.get(path.size() - 1);
if (network.outDegree(lastNode) == 0) {
distinctPathsFromRootsToLeaves.add(new ArrayList<>(path));
} else {
for (EdgeT edge : network.outEdges(lastNode)) {
paths.addFirst(
ImmutableList.<NodeT>builder()
.addAll(path)
.add(network.incidentNodes(edge).target())
.build());
}
}
}
return distinctPathsFromRootsToLeaves;
}
/**
* Create a graph that represents the relationship between the taxa.
* <p>
* Vertices in the new graph are the taxa keys. A transaction in the new
* graph from vertex A to vertex B represents all transactions from any
* vertex in taxon A to any vertex in taxon B.
* <p>
* @throws java.lang.InterruptedException If the thread is interrupted.
*
* @return A Condensation representing the relationship between the taxa.
*
* TODO: sometimes its not worth adding the transactions.
*/
public Condensation getCondensedGraph() throws InterruptedException {
// final Map<Integer, Extent> taxonKeyToExtent = new HashMap<>();
final Map<Integer, Integer> cVxIdToTaxonKey = new HashMap<>();
final Map<Integer, Integer> taxonKeyToVxId = new HashMap<>();
final GraphWriteMethods condensedGraph = new StoreGraph(wg.getSchema());
final int cxAttr = VisualConcept.VertexAttribute.X.ensure(condensedGraph);
final int cyAttr = VisualConcept.VertexAttribute.Y.ensure(condensedGraph);
final int czAttr = VisualConcept.VertexAttribute.Z.ensure(condensedGraph);
final int cxOrigId = condensedGraph.addAttribute(GraphElementType.VERTEX, FloatAttributeDescription.ATTRIBUTE_NAME, X_ORIG, X_ORIG, null, null);
final int cyOrigId = condensedGraph.addAttribute(GraphElementType.VERTEX, FloatAttributeDescription.ATTRIBUTE_NAME, Y_ORIG, Y_ORIG, null, null);
final int czOrigId = condensedGraph.addAttribute(GraphElementType.VERTEX, FloatAttributeDescription.ATTRIBUTE_NAME, Z_ORIG, Z_ORIG, null, null);
final int cnRadiusAttr = VisualConcept.VertexAttribute.NODE_RADIUS.ensure(condensedGraph);
final int cRadiusAttr = VisualConcept.VertexAttribute.LABEL_RADIUS.ensure(condensedGraph);
// Add the vertices.
// TODO: do these need to be sorted?
for (final Integer k : getSortedTaxaKeys()) {
if (Thread.interrupted()) {
throw new InterruptedException();
}
if (taxa.get(k).isEmpty()) {
continue;
}
final int cVxId = condensedGraph.addVertex();
final BitSet vertices = new BitSet();
for (Integer member : taxa.get(k)) {
vertices.set(member);
}
// Figure out where and how big the new vertex will be.
final Extent extent = Extent.getExtent(wg, vertices);
// The condensation has the positions of the extents and the positions of the taxon key vertices.
// The x,y,z will be modified, so remember them for repositioning later.
condensedGraph.setFloatValue(cxAttr, cVxId, extent.getX());
condensedGraph.setFloatValue(cyAttr, cVxId, extent.getY());
condensedGraph.setFloatValue(czAttr, cVxId, extent.getZ());
condensedGraph.setFloatValue(cxOrigId, cVxId, extent.getX());
condensedGraph.setFloatValue(cyOrigId, cVxId, extent.getY());
condensedGraph.setFloatValue(czOrigId, cVxId, extent.getZ());
condensedGraph.setFloatValue(cnRadiusAttr, cVxId, extent.getNRadius());
condensedGraph.setFloatValue(cRadiusAttr, cVxId, extent.getLRadius());
cVxIdToTaxonKey.put(cVxId, k);
taxonKeyToVxId.put(k, cVxId);
// taxonKeyToExtent.put(k, extent);
}
// System.out.printf("@GT Condensation (nTaxa=%d) (vxCount %d->%d)\n", taxa.keySet().size(), graph.getVertexCount(), wg.getVertexCount());
// Add the transactions.
// final long t0 = System.currentTimeMillis();
// We search through all of the taxa to find sources,
// but only look in the remaining taxa for destinations,
// otherwise we end up with two transactions between each vertex.
final ArrayDeque<Integer> sources = new ArrayDeque<>();
sources.addAll(taxa.keySet());
while (!sources.isEmpty()) {
// If we already have a transaction from the current source to a particular destination,
// don't add another one.
final Set<Integer> found = new HashSet<>();
final Integer src = sources.removeFirst();
found.add(src);
final Set<Integer> members = taxa.get(src);
for (Integer mm : members) {
if (Thread.interrupted()) {
throw new InterruptedException();
}
final int m = mm;
final int nNeighbours = wg.getVertexNeighbourCount(m);
for (int position = 0; position < nNeighbours; position++) {
final int nbId = wg.getVertexNeighbour(m, position);
final Integer dst = nodeToTaxa != null ? nodeToTaxa.get(nbId) : findTaxonContainingVertex(sources, nbId);
// Found the test for null was required to avoid issues
if (dst != null && dst != Graph.NOT_FOUND && !found.contains(dst)) {
// Debug.debug("condense src=%s(%s) dst=%s(%s)\n", src, taxonKeyToVxId.get(src), dst, taxonKeyToVxId.get(dst));
condensedGraph.addTransaction(taxonKeyToVxId.get(src), taxonKeyToVxId.get(dst), true);
found.add(dst);
}
}
}
}
return new Condensation(condensedGraph, cVxIdToTaxonKey);//, taxonKeyToExtent);
}
/**
* Tests that a blocking batch job fails if there are not enough resources left to schedule the
* succeeding tasks. This test case is related to [FLINK-4296] where finished producing tasks
* swallow the fail exception when scheduling a consumer task.
*/
@Test
public void testNoResourceAvailableFailure() throws Exception {
final JobID jobId = new JobID();
JobVertex v1 = new JobVertex("source");
JobVertex v2 = new JobVertex("sink");
int dop1 = 1;
int dop2 = 1;
v1.setParallelism(dop1);
v2.setParallelism(dop2);
v1.setInvokableClass(BatchTask.class);
v2.setInvokableClass(BatchTask.class);
v2.connectNewDataSetAsInput(v1, DistributionPattern.POINTWISE, ResultPartitionType.BLOCKING);
final ArrayDeque<CompletableFuture<LogicalSlot>> slotFutures = new ArrayDeque<>();
for (int i = 0; i < dop1; i++) {
slotFutures.addLast(CompletableFuture.completedFuture(new TestingLogicalSlot()));
}
final SlotProvider slotProvider = new TestingSlotProvider(ignore -> slotFutures.removeFirst());
final JobInformation jobInformation = new DummyJobInformation(
jobId,
"failing test job");
DirectScheduledExecutorService directExecutor = new DirectScheduledExecutorService();
// execution graph that executes actions synchronously
ExecutionGraph eg = new ExecutionGraph(
jobInformation,
directExecutor,
TestingUtils.defaultExecutor(),
AkkaUtils.getDefaultTimeout(),
new NoRestartStrategy(),
new RestartAllStrategy.Factory(),
slotProvider,
ExecutionGraph.class.getClassLoader(),
blobWriter,
AkkaUtils.getDefaultTimeout());
eg.start(TestingComponentMainThreadExecutorServiceAdapter.forMainThread());
checkJobOffloaded(eg);
eg.setQueuedSchedulingAllowed(false);
List<JobVertex> ordered = Arrays.asList(v1, v2);
eg.attachJobGraph(ordered);
// schedule, this triggers mock deployment
eg.scheduleForExecution();
ExecutionAttemptID attemptID = eg.getJobVertex(v1.getID()).getTaskVertices()[0].getCurrentExecutionAttempt().getAttemptId();
eg.updateState(new TaskExecutionState(jobId, attemptID, ExecutionState.RUNNING));
eg.updateState(new TaskExecutionState(jobId, attemptID, ExecutionState.FINISHED, null));
assertEquals(JobStatus.FAILED, eg.getState());
}
/**
* Looks at each action in {@code actionsToCheck} and determines whether additional artifacts,
* actions, and (in the case of {@link SkyframeAwareAction}s) other Skyframe nodes need to be
* restarted. If this finds more actions to restart, those actions are recursively checked too.
*/
private void checkActions(
ImmutableList<ActionAndLookupData> actionsToCheck,
Environment env,
MutableGraph<SkyKey> rewindGraph,
ImmutableList.Builder<Action> additionalActionsToRestart)
throws InterruptedException {
ArrayDeque<ActionAndLookupData> uncheckedActions = new ArrayDeque<>(actionsToCheck);
while (!uncheckedActions.isEmpty()) {
ActionAndLookupData actionAndLookupData = uncheckedActions.removeFirst();
ActionLookupData actionKey = actionAndLookupData.lookupData();
Action action = actionAndLookupData.action();
ArrayList<Artifact.DerivedArtifact> artifactsToCheck = new ArrayList<>();
ArrayList<ActionLookupData> newlyDiscoveredActions = new ArrayList<>();
if (action instanceof SkyframeAwareAction) {
// This action depends on more than just its input artifact values. We need to also restart
// the Skyframe subgraph it depends on, up to and including any artifacts, which may
// aggregate multiple actions.
addSkyframeAwareDepsAndGetNewlyVisitedArtifactsAndActions(
rewindGraph,
actionKey,
(SkyframeAwareAction) action,
artifactsToCheck,
newlyDiscoveredActions);
}
if (action.mayInsensitivelyPropagateInputs()) {
// Restarting this action won't recreate the missing input. We need to also restart this
// action's non-source inputs and the actions which created those inputs.
addPropagatingActionDepsAndGetNewlyVisitedArtifactsAndActions(
rewindGraph, actionKey, action, artifactsToCheck, newlyDiscoveredActions);
}
for (ActionLookupData actionLookupData : newlyDiscoveredActions) {
Action additionalAction =
checkNotNull(
ActionUtils.getActionForLookupData(env, actionLookupData), actionLookupData);
additionalActionsToRestart.add(additionalAction);
uncheckedActions.add(ActionAndLookupData.create(actionLookupData, additionalAction));
}
for (Artifact.DerivedArtifact artifact : artifactsToCheck) {
Map<ActionLookupData, Action> actionMap = getActionsForLostArtifact(artifact, env);
if (actionMap == null) {
continue;
}
ImmutableList<ActionAndLookupData> newlyVisitedActions =
addArtifactDepsAndGetNewlyVisitedActions(rewindGraph, artifact, actionMap);
additionalActionsToRestart.addAll(actions(newlyVisitedActions));
uncheckedActions.addAll(newlyVisitedActions);
}
}
}
/**
* Tests that a blocking batch job fails if there are not enough resources left to schedule the
* succeeding tasks. This test case is related to [FLINK-4296] where finished producing tasks
* swallow the fail exception when scheduling a consumer task.
*/
@Test
public void testNoResourceAvailableFailure() throws Exception {
final JobID jobId = new JobID();
JobVertex v1 = new JobVertex("source");
JobVertex v2 = new JobVertex("sink");
int dop1 = 1;
int dop2 = 1;
v1.setParallelism(dop1);
v2.setParallelism(dop2);
v1.setInvokableClass(BatchTask.class);
v2.setInvokableClass(BatchTask.class);
v2.connectNewDataSetAsInput(v1, DistributionPattern.POINTWISE, ResultPartitionType.BLOCKING);
final ArrayDeque<CompletableFuture<LogicalSlot>> slotFutures = new ArrayDeque<>();
for (int i = 0; i < dop1; i++) {
slotFutures.addLast(CompletableFuture.completedFuture(new TestingLogicalSlotBuilder().createTestingLogicalSlot()));
}
final SlotProvider slotProvider = new TestingSlotProvider(ignore -> slotFutures.removeFirst());
DirectScheduledExecutorService directExecutor = new DirectScheduledExecutorService();
// execution graph that executes actions synchronously
ExecutionGraph eg = createExecutionGraphWithoutQueuedScheduling(jobId, slotProvider, directExecutor, TestingUtils.defaultExecutor());
eg.start(ComponentMainThreadExecutorServiceAdapter.forMainThread());
checkJobOffloaded(eg);
List<JobVertex> ordered = Arrays.asList(v1, v2);
eg.attachJobGraph(ordered);
// schedule, this triggers mock deployment
eg.scheduleForExecution();
ExecutionAttemptID attemptID = eg.getJobVertex(v1.getID()).getTaskVertices()[0].getCurrentExecutionAttempt().getAttemptId();
eg.updateState(new TaskExecutionState(jobId, attemptID, ExecutionState.RUNNING));
eg.updateState(new TaskExecutionState(jobId, attemptID, ExecutionState.FINISHED, null));
assertEquals(JobStatus.FAILED, eg.getState());
}
@Override
public DataSet<ExecRow> getDataSet(SpliceOperation op, DataSetProcessor dsp, ExecRow execRow) throws StandardException {
operationContext = dsp.createOperationContext(op);
//Create an arraylist to store the list of roles
ArrayList<ExecRow> items = new ArrayList<ExecRow>();
Activation activation = op.getActivation();
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
List<String> groupUsers = lcc.getCurrentGroupUser(activation);
String currentUser = lcc.getCurrentUserId(activation);
// populate the queue with root nodes in the role grant graph
ArrayDeque<String> roleQueue = new ArrayDeque<>();
roleQueue.add("PUBLIC");
roleQueue.add(currentUser);
if (groupUsers != null) {
for (String user : groupUsers) {
roleQueue.add(user);
}
}
// get the role grant graph
TransactionController tc = lcc.getTransactionExecute();
DataDictionaryImpl dd = (DataDictionaryImpl)lcc.getDataDictionary();
Map<String,List<RoleGrantDescriptor>> graph =
dd.getRoleGrantGraph(tc, true, false);
while (!roleQueue.isEmpty()) {
String aRole = roleQueue.removeFirst();
ExecRow valueRow = new ValueRow(1);
valueRow.setColumn(1, new SQLVarchar(aRole));
items.add(valueRow);
List<RoleGrantDescriptor> outArcs = graph.get(aRole);
if (outArcs != null) {
for (RoleGrantDescriptor rd: outArcs) {
roleQueue.add(rd.getRoleName());
}
}
}
return dsp.createDataSet(items.iterator());
}