Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Allow multiple objects on selecting a GROUP BY result line. #7

Open
ajohnson1 opened this issue Jul 27, 2018 · 3 comments

Comments

@ajohnson1
Copy link

MAT Calcite is a clever piece of software for enhancing Memory Analyzer.

I was looking at an old MAT defect and thought MAT Calcite might help. I'm not sure how to do inbounds() but GROUP BY and SUM work.

select length(a.this) as "length", count(a.this) as "count", sum(shallowSize(a.this)) as "total mem" from "java.lang.Object[]" a group by length order by "total mem" desc

Examining the result of that query gives a table. It would be really neat if with multiple objects associated per line MAT Calcite could return IContextObjectSet. That would allow the user to select a line or lines and operate on all the objects selected. See a standard histogram query for an example. Selecting a line lists the class in the inspector view, but the context menu operates on all the instance of the class. Perhaps getOQL() could return a Calcite SQL query returning just that particular line, though that might be tricky.

getResultMetaData could also be useful - this allows a list of ContextProviders via getContextProviders() and then a choice of results is presented for each line, as used for the ClassLoaderExplorer query where the choices are the class loader, or all the classes loaded by the loader. This could be used if there were multiple columns which could sensibly each return a IObject or set of objects.

@vlsi
Copy link
Owner

vlsi commented Jul 28, 2018

@ajohnson1 , glad you find MAT Calcite interesting.

I'm not sure how to do inbounds() but GROUP BY and SUM work.

Please check "table functions" in the README.

Here are samples from the unit tests as well: https://github.com/vlsi/mat-calcite-plugin/blob/master/MatCalciteTest/src/com/github/vlsi/mat/tests/calcite/BasicQueriesTests.java#L153-L165

Technically speaking, there's CARDINALITY(...) operator, so you can use either lateral (select * from table(getInboundReferences(hm.this))) or cross apply table(getInboundReferences(u.this)) or even select cardinality(getInboundReferences(hm.this)) ...

@ajohnson1
Copy link
Author

Okay, I think I have a way of solving the problem in the old MAT bug 241154:

select inb "#inbounds", count(arr.this) "#objects" from instanceof.java.lang.Object arr cross apply (select count(*) inb from table(getInboundReferences(arr.this)))  where length(arr.this) >= 0 group by inb order by inb asc

Notes:

  • 'instanceof.java.lang.Object' selects all objects (assuming they are subclasses of java.lang.Object)
    length(arr.this) >= 0 which are arrays (simple objects return -1)
  • select count(*) inb from table(getInboundReferences(arr.this)) - finds the number of inbound references, puts the result into inb
  • group by inb groups all objects with same number of inbounds
  • order by inb asc sorts by inb = number of inbounds

My first attempts using cardinality() didn't work, hence the count(*) approach.

I see that you had already implemented my request for multiple context providers:

select * from java.util.HashMap
shows

  • HashMap.this
  • HashMap.table

in the context menu. Thank you. On checking MAT doesn't do that for OQL - '*' displays a tree, not fields, but OQL select hm, hm.table from java.util.HashMap hm displays both columns, but not both as context menu items, so I have some work to do for OQL.

I'd still like to see multiple objects in a context menu for GROUP BY.

I'll continue to experiment with MAT Calcite to understand how to change OQL queries to SQL. I've also seen some exceptions in the MAT error log - once I can reproduce them I'll raise separate issues.

@vlsi
Copy link
Owner

vlsi commented Jul 29, 2018

On checking MAT doesn't do that for OQL - '*' displays a tree, not fields

I thought of displaying results as tree, however it is not clear how that should look like since columns might refer completely different objects in heap.

Do you have an idea there?

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

No branches or pull requests

2 participants