0
public class ReportDatabase {

    private static final Map<String, Report> reportTypes;
    private static final String[] reportTypeNameVersion = {
            "Payroll Tax Report 1",
            "Capital Gains Tax Report 1",
            "Overall Expenditure Report 1",
            "Dark Costs Report 1",
            "Petty Cash Report 1",
            "Enron Fund Report 1",
            "COVID-19 Report 1",
            "COVID-20 Report 1",
            "Brawndo Investment Report 1",
            "Philanthropy Report 1",
            "Payroll Tax Report 2",
            "Capital Gains Tax Report 2",
            "Overall Expenditure Report 2",
            "Dark Costs Report 2",
            "Petty Cash Report 2",
            "Enron Fund Report 2",
            "COVID-19 Report 2",
            "COVID-20 Report 2",
            "Brawndo Investment Report 2",
            "Philanthropy Report 2"
    };

    static {
        reportTypes = new HashMap<>();

        for (String name: reportTypeNameVersion) {
            reportTypes.put(name, new ReportImpl(name.substring(0, name.length()-1), getReportCommission(), getReportData(), getReportData(), getReportData(), getReportData(), getReportData()));
        }
    }


    public static Collection<Report> getTestReports() {
        Collection<Report> originals = reportTypes.values();
        List<Report> result = new ArrayList<>();

        for (Report original: originals) {
            Report report = (new ReportImpl(original.getReportName(),
                    original.getCommission(),
                    original.getLegalData().clone(),
                    original.getCashFlowData().clone(),
                    original.getMergesData().clone(),
                    original.getTallyingData().clone(),
                    original.getDeductionsData().clone()));

            result.add(report);

            for(int i = 0; i < original.getLegalData().length; i++) {
                System.out.println(original.getLegalData()[i]);
            }


        }
        return result;
    }

    private static double[] getReportData() {


        double[] result = new double[100];
        Random random = new Random();

        for (int i = 0; i < result.length; i++) {
            result[i] = random.nextDouble();
        }

        return result;
    }

    private static double getReportCommission() {
        Random random = new Random();

        return 1.0 + 99.0 * random.nextDouble();
    }
}

The above class is a class that I cannot modify anything.

The goal is to reduce the RAM usage and I check the RAM usage.

If I remove .clone() in getTestReports, the RAM usage decreases from 800~MB to 400~MB, but actually I cannot remove it because of its business rule.

When I call the getTestReports in other class, it directly takes 800~MB RAM consumption.

So, what I want to ask is, is there anyway to remove .clone() in getTestReports() method outside of its class such as ReportImpl class which implements Report interface and contains variables such as double[] legalData and getter methods for them?

  • If you cannot modify this class, it will be hard to optimize. Depending on what you are doing further with the Report collection, may be you can write this in streaming mode in the output (file or servlet or wathever) – ggr May 24 '20 at 08:16
  • Is this the same question you've been posting over and over, where you're probably supposed to use the flyweight pattern (at least that's the one pattern you've mentioned), but you haven't actually made any effort to implement it? Apparently so. If you don't start making an effort to learn the pattern yourself, you're going to get zero points for this homework. Unless you start doing something and asking for **specific** help when stuck, this won't move forward. – Kayaman May 24 '20 at 08:17
  • @Kayaman I finished implementing flyweight pattern and it successfully removed the duplicating reports. However, this just prevents the memory usage from getting increased, and it actually did not decrease the RAM usage. I think the problem is on the .clone() but I do not know how to remove it whilst not touching anything in the ReportDatabase class – helpmefromjava May 24 '20 at 08:22
  • @Kayaman His actions aren't justified. He should probably start a bounty on original question and not make any duplicates. –  May 24 '20 at 08:24
  • If you can't modify that class, then that's a hard limit on the memory (there's no `unclone()` of course). But that seems to be outside the scope of your assignment anyway, I thought you were still stuck on the flyweight. You seem to have finished your assignment. The program takes the correct amount of memory, and will scale with multiple users getting reports simultaneously. – Kayaman May 24 '20 at 08:33
  • Nope, I finished implementing flyweight, but it does not decrease the actual RAM usage. Other people gave me a hint to get around with .clone() to reduce the RAM usage from 800MB to 400MB, but I am really struggling with how to remove it... – helpmefromjava May 24 '20 at 08:36
  • It's not supposed to decrease it. Do you not understand flyweight? It's supposed to not make it grow. You can't remove `clone()`. You can't do anything, since you can't change the class. – Kayaman May 24 '20 at 08:37
  • No, I understand the flyweight, and that's why I am telling you that I finished implementing flyweight pattern cause I know it prevents the RAM usage from growing when duplicating objects are being added. There is another way to reduce the RAM usage since other people achieved it. If you cannot help me, thats okay, you can just ignore this post. – helpmefromjava May 24 '20 at 08:39
  • If you're certain you need to drop your memory usage, then you should concentrate on the classes that you can modify, not the ones you can't. But since your "declone" and flyweight are mutually exclusive approaches, you may have a misunderstanding on the memory requirements of the program. Especially since sharing the array data would change the semantics, allowing clients to corrupt the central data (which is why the `clone()` is there). – Kayaman May 24 '20 at 08:51
  • @Kayaman um.. there is a class called ReportImpl which contains fields such as legalData, etc and they are being used in ReportDatabase class. Is there any way to make each double[] array fields not cloneable? – helpmefromjava May 24 '20 at 17:11
  • No, `clone()` is natively implemented by arrays. You can't get in between or undo it in anyway. – Kayaman May 24 '20 at 17:39
  • It's called defensive copying. It's to make sure the client can't change the data in the database (although with flyweight clients could change data seen by other clients). But like I said, you can't undo or intercept the call to `clone()`. I'm betting there's just a misunderstanding behind this. – Kayaman May 24 '20 at 17:44
  • The answer was to caching clone() by caching flyweightFactory class but still dont know how to solve it by keeping original elements stored in each double[] array... Do you have any thoughts on this one? – helpmefromjava May 25 '20 at 05:09

0 Answers0