From d3bac575d42b7f003ca199cb59e64685b110c597 Mon Sep 17 00:00:00 2001 From: Rumps Date: Fri, 14 Apr 2017 08:29:38 +0100 Subject: [PATCH] Initial commit --- README.txt | 1 + dat/archives/difffile-html.bz2 | Bin 0 -> 7016 bytes dat/archives/difffile-images.bz2 | Bin 0 -> 7013 bytes dat/archives/difffile-large.bz2 | Bin 0 -> 7003 bytes dat/archives/difffile-small.bz2 | Bin 0 -> 7028 bytes dat/archives/difffile.bz2 | Bin 0 -> 7030 bytes dat/archives/samefile-html.bz2 | Bin 0 -> 7045 bytes dat/archives/samefile-images.bz2 | Bin 0 -> 7048 bytes dat/cache/CacheHandlerBase.dn | 267 +++ dat/cache/Thumbs.db | Bin 0 -> 23552 bytes dat/cache/difffile-large/0/CacheHandler0_0.dn | 267 +++ dat/cache/difffile-large/0/CacheHandler0_1.dn | 267 +++ .../difffile-large/0/CacheHandler0_10.dn | 267 +++ .../difffile-large/0/CacheHandler0_11.dn | 267 +++ .../difffile-large/0/CacheHandler0_12.dn | 267 +++ .../difffile-large/0/CacheHandler0_13.dn | 267 +++ .../difffile-large/0/CacheHandler0_14.dn | 267 +++ .../difffile-large/0/CacheHandler0_15.dn | 267 +++ .../difffile-large/0/CacheHandler0_16.dn | 267 +++ .../difffile-large/0/CacheHandler0_17.dn | 267 +++ .../difffile-large/0/CacheHandler0_18.dn | 267 +++ .../difffile-large/0/CacheHandler0_19.dn | 267 +++ dat/cache/difffile-large/0/CacheHandler0_2.dn | 267 +++ .../difffile-large/0/CacheHandler0_20.dn | 267 +++ .../difffile-large/0/CacheHandler0_21.dn | 267 +++ .../difffile-large/0/CacheHandler0_22.dn | 267 +++ .../difffile-large/0/CacheHandler0_23.dn | 267 +++ .../difffile-large/0/CacheHandler0_24.dn | 267 +++ .../difffile-large/0/CacheHandler0_25.dn | 267 +++ .../difffile-large/0/CacheHandler0_26.dn | 267 +++ .../difffile-large/0/CacheHandler0_27.dn | 267 +++ .../difffile-large/0/CacheHandler0_28.dn | 267 +++ .../difffile-large/0/CacheHandler0_29.dn | 267 +++ dat/cache/difffile-large/0/CacheHandler0_3.dn | 267 +++ .../difffile-large/0/CacheHandler0_30.dn | 267 +++ .../difffile-large/0/CacheHandler0_31.dn | 267 +++ .../difffile-large/0/CacheHandler0_32.dn | 267 +++ .../difffile-large/0/CacheHandler0_33.dn | 267 +++ .../difffile-large/0/CacheHandler0_34.dn | 267 +++ dat/cache/difffile-large/0/CacheHandler0_4.dn | 267 +++ dat/cache/difffile-large/0/CacheHandler0_5.dn | 267 +++ dat/cache/difffile-large/0/CacheHandler0_6.dn | 267 +++ dat/cache/difffile-large/0/CacheHandler0_7.dn | 267 +++ dat/cache/difffile-large/0/CacheHandler0_8.dn | 267 +++ dat/cache/difffile-large/0/CacheHandler0_9.dn | 267 +++ dat/cache/difffile-large/1/CacheHandler1_0.dn | 267 +++ dat/cache/difffile-large/1/CacheHandler1_1.dn | 267 +++ .../difffile-large/1/CacheHandler1_10.dn | 267 +++ .../difffile-large/1/CacheHandler1_11.dn | 267 +++ .../difffile-large/1/CacheHandler1_12.dn | 267 +++ .../difffile-large/1/CacheHandler1_13.dn | 267 +++ .../difffile-large/1/CacheHandler1_14.dn | 267 +++ .../difffile-large/1/CacheHandler1_15.dn | 267 +++ .../difffile-large/1/CacheHandler1_16.dn | 267 +++ .../difffile-large/1/CacheHandler1_17.dn | 267 +++ .../difffile-large/1/CacheHandler1_18.dn | 267 +++ .../difffile-large/1/CacheHandler1_19.dn | 267 +++ dat/cache/difffile-large/1/CacheHandler1_2.dn | 267 +++ .../difffile-large/1/CacheHandler1_20.dn | 267 +++ .../difffile-large/1/CacheHandler1_21.dn | 267 +++ .../difffile-large/1/CacheHandler1_22.dn | 267 +++ .../difffile-large/1/CacheHandler1_23.dn | 267 +++ .../difffile-large/1/CacheHandler1_24.dn | 267 +++ .../difffile-large/1/CacheHandler1_25.dn | 267 +++ .../difffile-large/1/CacheHandler1_26.dn | 267 +++ .../difffile-large/1/CacheHandler1_27.dn | 267 +++ .../difffile-large/1/CacheHandler1_28.dn | 267 +++ .../difffile-large/1/CacheHandler1_29.dn | 267 +++ dat/cache/difffile-large/1/CacheHandler1_3.dn | 267 +++ .../difffile-large/1/CacheHandler1_30.dn | 267 +++ .../difffile-large/1/CacheHandler1_31.dn | 267 +++ .../difffile-large/1/CacheHandler1_32.dn | 267 +++ .../difffile-large/1/CacheHandler1_33.dn | 267 +++ .../difffile-large/1/CacheHandler1_34.dn | 267 +++ dat/cache/difffile-large/1/CacheHandler1_4.dn | 267 +++ dat/cache/difffile-large/1/CacheHandler1_5.dn | 267 +++ dat/cache/difffile-large/1/CacheHandler1_6.dn | 267 +++ dat/cache/difffile-large/1/CacheHandler1_7.dn | 267 +++ dat/cache/difffile-large/1/CacheHandler1_8.dn | 267 +++ dat/cache/difffile-large/1/CacheHandler1_9.dn | 267 +++ .../difffile-large/10/CacheHandler10_0.dn | 267 +++ .../difffile-large/10/CacheHandler10_1.dn | 267 +++ .../difffile-large/10/CacheHandler10_10.dn | 267 +++ .../difffile-large/10/CacheHandler10_11.dn | 267 +++ .../difffile-large/10/CacheHandler10_12.dn | 267 +++ .../difffile-large/10/CacheHandler10_13.dn | 267 +++ .../difffile-large/10/CacheHandler10_14.dn | 267 +++ .../difffile-large/10/CacheHandler10_15.dn | 267 +++ .../difffile-large/10/CacheHandler10_16.dn | 267 +++ .../difffile-large/10/CacheHandler10_17.dn | 267 +++ .../difffile-large/10/CacheHandler10_18.dn | 267 +++ .../difffile-large/10/CacheHandler10_19.dn | 267 +++ .../difffile-large/10/CacheHandler10_2.dn | 267 +++ .../difffile-large/10/CacheHandler10_20.dn | 267 +++ .../difffile-large/10/CacheHandler10_21.dn | 267 +++ .../difffile-large/10/CacheHandler10_22.dn | 267 +++ .../difffile-large/10/CacheHandler10_23.dn | 267 +++ .../difffile-large/10/CacheHandler10_24.dn | 267 +++ .../difffile-large/10/CacheHandler10_25.dn | 267 +++ .../difffile-large/10/CacheHandler10_26.dn | 267 +++ .../difffile-large/10/CacheHandler10_27.dn | 267 +++ .../difffile-large/10/CacheHandler10_28.dn | 267 +++ .../difffile-large/10/CacheHandler10_29.dn | 267 +++ .../difffile-large/10/CacheHandler10_3.dn | 267 +++ .../difffile-large/10/CacheHandler10_30.dn | 267 +++ .../difffile-large/10/CacheHandler10_31.dn | 267 +++ .../difffile-large/10/CacheHandler10_32.dn | 267 +++ .../difffile-large/10/CacheHandler10_33.dn | 267 +++ .../difffile-large/10/CacheHandler10_34.dn | 267 +++ .../difffile-large/10/CacheHandler10_4.dn | 267 +++ .../difffile-large/10/CacheHandler10_5.dn | 267 +++ .../difffile-large/10/CacheHandler10_6.dn | 267 +++ .../difffile-large/10/CacheHandler10_7.dn | 267 +++ .../difffile-large/10/CacheHandler10_8.dn | 267 +++ .../difffile-large/10/CacheHandler10_9.dn | 267 +++ .../difffile-large/11/CacheHandler11_0.dn | 267 +++ .../difffile-large/11/CacheHandler11_1.dn | 267 +++ .../difffile-large/11/CacheHandler11_10.dn | 267 +++ .../difffile-large/11/CacheHandler11_11.dn | 267 +++ .../difffile-large/11/CacheHandler11_12.dn | 267 +++ .../difffile-large/11/CacheHandler11_13.dn | 267 +++ .../difffile-large/11/CacheHandler11_14.dn | 267 +++ .../difffile-large/11/CacheHandler11_15.dn | 267 +++ .../difffile-large/11/CacheHandler11_16.dn | 267 +++ .../difffile-large/11/CacheHandler11_17.dn | 267 +++ .../difffile-large/11/CacheHandler11_18.dn | 267 +++ .../difffile-large/11/CacheHandler11_19.dn | 267 +++ .../difffile-large/11/CacheHandler11_2.dn | 267 +++ .../difffile-large/11/CacheHandler11_20.dn | 267 +++ .../difffile-large/11/CacheHandler11_21.dn | 267 +++ .../difffile-large/11/CacheHandler11_22.dn | 267 +++ .../difffile-large/11/CacheHandler11_23.dn | 267 +++ .../difffile-large/11/CacheHandler11_24.dn | 267 +++ .../difffile-large/11/CacheHandler11_25.dn | 267 +++ .../difffile-large/11/CacheHandler11_26.dn | 267 +++ .../difffile-large/11/CacheHandler11_27.dn | 267 +++ .../difffile-large/11/CacheHandler11_28.dn | 267 +++ .../difffile-large/11/CacheHandler11_29.dn | 267 +++ .../difffile-large/11/CacheHandler11_3.dn | 267 +++ .../difffile-large/11/CacheHandler11_30.dn | 267 +++ .../difffile-large/11/CacheHandler11_31.dn | 267 +++ .../difffile-large/11/CacheHandler11_32.dn | 267 +++ .../difffile-large/11/CacheHandler11_33.dn | 267 +++ .../difffile-large/11/CacheHandler11_34.dn | 267 +++ .../difffile-large/11/CacheHandler11_4.dn | 267 +++ .../difffile-large/11/CacheHandler11_5.dn | 267 +++ .../difffile-large/11/CacheHandler11_6.dn | 267 +++ .../difffile-large/11/CacheHandler11_7.dn | 267 +++ .../difffile-large/11/CacheHandler11_8.dn | 267 +++ .../difffile-large/11/CacheHandler11_9.dn | 267 +++ .../difffile-large/12/CacheHandler12_0.dn | 267 +++ .../difffile-large/12/CacheHandler12_1.dn | 267 +++ .../difffile-large/12/CacheHandler12_10.dn | 267 +++ .../difffile-large/12/CacheHandler12_11.dn | 267 +++ .../difffile-large/12/CacheHandler12_12.dn | 267 +++ .../difffile-large/12/CacheHandler12_13.dn | 267 +++ .../difffile-large/12/CacheHandler12_14.dn | 267 +++ .../difffile-large/12/CacheHandler12_15.dn | 267 +++ .../difffile-large/12/CacheHandler12_16.dn | 267 +++ .../difffile-large/12/CacheHandler12_17.dn | 267 +++ .../difffile-large/12/CacheHandler12_18.dn | 267 +++ .../difffile-large/12/CacheHandler12_19.dn | 267 +++ .../difffile-large/12/CacheHandler12_2.dn | 267 +++ .../difffile-large/12/CacheHandler12_20.dn | 267 +++ .../difffile-large/12/CacheHandler12_21.dn | 267 +++ .../difffile-large/12/CacheHandler12_22.dn | 267 +++ .../difffile-large/12/CacheHandler12_23.dn | 267 +++ .../difffile-large/12/CacheHandler12_24.dn | 267 +++ .../difffile-large/12/CacheHandler12_25.dn | 267 +++ .../difffile-large/12/CacheHandler12_26.dn | 267 +++ .../difffile-large/12/CacheHandler12_27.dn | 267 +++ .../difffile-large/12/CacheHandler12_28.dn | 267 +++ .../difffile-large/12/CacheHandler12_29.dn | 267 +++ .../difffile-large/12/CacheHandler12_3.dn | 267 +++ .../difffile-large/12/CacheHandler12_30.dn | 267 +++ .../difffile-large/12/CacheHandler12_31.dn | 267 +++ .../difffile-large/12/CacheHandler12_32.dn | 267 +++ .../difffile-large/12/CacheHandler12_33.dn | 267 +++ .../difffile-large/12/CacheHandler12_34.dn | 267 +++ .../difffile-large/12/CacheHandler12_4.dn | 267 +++ .../difffile-large/12/CacheHandler12_5.dn | 267 +++ .../difffile-large/12/CacheHandler12_6.dn | 267 +++ .../difffile-large/12/CacheHandler12_7.dn | 267 +++ .../difffile-large/12/CacheHandler12_8.dn | 267 +++ .../difffile-large/12/CacheHandler12_9.dn | 267 +++ .../difffile-large/13/CacheHandler13_0.dn | 267 +++ .../difffile-large/13/CacheHandler13_1.dn | 267 +++ .../difffile-large/13/CacheHandler13_10.dn | 267 +++ .../difffile-large/13/CacheHandler13_11.dn | 267 +++ .../difffile-large/13/CacheHandler13_12.dn | 267 +++ .../difffile-large/13/CacheHandler13_13.dn | 267 +++ .../difffile-large/13/CacheHandler13_14.dn | 267 +++ .../difffile-large/13/CacheHandler13_15.dn | 267 +++ .../difffile-large/13/CacheHandler13_16.dn | 267 +++ .../difffile-large/13/CacheHandler13_17.dn | 267 +++ .../difffile-large/13/CacheHandler13_18.dn | 267 +++ .../difffile-large/13/CacheHandler13_19.dn | 267 +++ .../difffile-large/13/CacheHandler13_2.dn | 267 +++ .../difffile-large/13/CacheHandler13_20.dn | 267 +++ .../difffile-large/13/CacheHandler13_21.dn | 267 +++ .../difffile-large/13/CacheHandler13_22.dn | 267 +++ .../difffile-large/13/CacheHandler13_23.dn | 267 +++ .../difffile-large/13/CacheHandler13_24.dn | 267 +++ .../difffile-large/13/CacheHandler13_25.dn | 267 +++ .../difffile-large/13/CacheHandler13_26.dn | 267 +++ .../difffile-large/13/CacheHandler13_27.dn | 267 +++ .../difffile-large/13/CacheHandler13_28.dn | 267 +++ .../difffile-large/13/CacheHandler13_29.dn | 267 +++ .../difffile-large/13/CacheHandler13_3.dn | 267 +++ .../difffile-large/13/CacheHandler13_30.dn | 267 +++ .../difffile-large/13/CacheHandler13_31.dn | 267 +++ .../difffile-large/13/CacheHandler13_32.dn | 267 +++ .../difffile-large/13/CacheHandler13_33.dn | 267 +++ .../difffile-large/13/CacheHandler13_34.dn | 267 +++ .../difffile-large/13/CacheHandler13_4.dn | 267 +++ .../difffile-large/13/CacheHandler13_5.dn | 267 +++ .../difffile-large/13/CacheHandler13_6.dn | 267 +++ .../difffile-large/13/CacheHandler13_7.dn | 267 +++ .../difffile-large/13/CacheHandler13_8.dn | 267 +++ .../difffile-large/13/CacheHandler13_9.dn | 267 +++ .../difffile-large/14/CacheHandler14_0.dn | 267 +++ .../difffile-large/14/CacheHandler14_1.dn | 267 +++ .../difffile-large/14/CacheHandler14_10.dn | 267 +++ .../difffile-large/14/CacheHandler14_11.dn | 267 +++ .../difffile-large/14/CacheHandler14_12.dn | 267 +++ .../difffile-large/14/CacheHandler14_13.dn | 267 +++ .../difffile-large/14/CacheHandler14_14.dn | 267 +++ .../difffile-large/14/CacheHandler14_15.dn | 267 +++ .../difffile-large/14/CacheHandler14_16.dn | 267 +++ .../difffile-large/14/CacheHandler14_17.dn | 267 +++ .../difffile-large/14/CacheHandler14_18.dn | 267 +++ .../difffile-large/14/CacheHandler14_19.dn | 267 +++ .../difffile-large/14/CacheHandler14_2.dn | 267 +++ .../difffile-large/14/CacheHandler14_20.dn | 267 +++ .../difffile-large/14/CacheHandler14_21.dn | 267 +++ .../difffile-large/14/CacheHandler14_22.dn | 267 +++ .../difffile-large/14/CacheHandler14_23.dn | 267 +++ .../difffile-large/14/CacheHandler14_24.dn | 267 +++ .../difffile-large/14/CacheHandler14_25.dn | 267 +++ .../difffile-large/14/CacheHandler14_26.dn | 267 +++ .../difffile-large/14/CacheHandler14_27.dn | 267 +++ .../difffile-large/14/CacheHandler14_28.dn | 267 +++ .../difffile-large/14/CacheHandler14_29.dn | 267 +++ .../difffile-large/14/CacheHandler14_3.dn | 267 +++ .../difffile-large/14/CacheHandler14_30.dn | 267 +++ .../difffile-large/14/CacheHandler14_31.dn | 267 +++ .../difffile-large/14/CacheHandler14_32.dn | 267 +++ .../difffile-large/14/CacheHandler14_33.dn | 267 +++ .../difffile-large/14/CacheHandler14_34.dn | 267 +++ .../difffile-large/14/CacheHandler14_4.dn | 267 +++ .../difffile-large/14/CacheHandler14_5.dn | 267 +++ .../difffile-large/14/CacheHandler14_6.dn | 267 +++ .../difffile-large/14/CacheHandler14_7.dn | 267 +++ .../difffile-large/14/CacheHandler14_8.dn | 267 +++ .../difffile-large/14/CacheHandler14_9.dn | 267 +++ .../difffile-large/15/CacheHandler15_0.dn | 267 +++ .../difffile-large/15/CacheHandler15_1.dn | 267 +++ .../difffile-large/15/CacheHandler15_10.dn | 267 +++ .../difffile-large/15/CacheHandler15_11.dn | 267 +++ .../difffile-large/15/CacheHandler15_12.dn | 267 +++ .../difffile-large/15/CacheHandler15_13.dn | 267 +++ .../difffile-large/15/CacheHandler15_14.dn | 267 +++ .../difffile-large/15/CacheHandler15_15.dn | 267 +++ .../difffile-large/15/CacheHandler15_16.dn | 267 +++ .../difffile-large/15/CacheHandler15_17.dn | 267 +++ .../difffile-large/15/CacheHandler15_18.dn | 267 +++ .../difffile-large/15/CacheHandler15_19.dn | 267 +++ .../difffile-large/15/CacheHandler15_2.dn | 267 +++ .../difffile-large/15/CacheHandler15_20.dn | 267 +++ .../difffile-large/15/CacheHandler15_21.dn | 267 +++ .../difffile-large/15/CacheHandler15_22.dn | 267 +++ .../difffile-large/15/CacheHandler15_23.dn | 267 +++ .../difffile-large/15/CacheHandler15_24.dn | 267 +++ .../difffile-large/15/CacheHandler15_25.dn | 267 +++ .../difffile-large/15/CacheHandler15_26.dn | 267 +++ .../difffile-large/15/CacheHandler15_27.dn | 267 +++ .../difffile-large/15/CacheHandler15_28.dn | 267 +++ .../difffile-large/15/CacheHandler15_29.dn | 267 +++ .../difffile-large/15/CacheHandler15_3.dn | 267 +++ .../difffile-large/15/CacheHandler15_30.dn | 267 +++ .../difffile-large/15/CacheHandler15_31.dn | 267 +++ .../difffile-large/15/CacheHandler15_32.dn | 267 +++ .../difffile-large/15/CacheHandler15_33.dn | 267 +++ .../difffile-large/15/CacheHandler15_34.dn | 267 +++ .../difffile-large/15/CacheHandler15_4.dn | 267 +++ .../difffile-large/15/CacheHandler15_5.dn | 267 +++ .../difffile-large/15/CacheHandler15_6.dn | 267 +++ .../difffile-large/15/CacheHandler15_7.dn | 267 +++ .../difffile-large/15/CacheHandler15_8.dn | 267 +++ .../difffile-large/15/CacheHandler15_9.dn | 267 +++ .../difffile-large/16/CacheHandler16_0.dn | 267 +++ .../difffile-large/16/CacheHandler16_1.dn | 267 +++ .../difffile-large/16/CacheHandler16_10.dn | 267 +++ .../difffile-large/16/CacheHandler16_11.dn | 267 +++ .../difffile-large/16/CacheHandler16_12.dn | 267 +++ .../difffile-large/16/CacheHandler16_13.dn | 267 +++ .../difffile-large/16/CacheHandler16_14.dn | 267 +++ .../difffile-large/16/CacheHandler16_15.dn | 267 +++ .../difffile-large/16/CacheHandler16_16.dn | 267 +++ .../difffile-large/16/CacheHandler16_17.dn | 267 +++ .../difffile-large/16/CacheHandler16_18.dn | 267 +++ .../difffile-large/16/CacheHandler16_19.dn | 267 +++ .../difffile-large/16/CacheHandler16_2.dn | 267 +++ .../difffile-large/16/CacheHandler16_20.dn | 267 +++ .../difffile-large/16/CacheHandler16_21.dn | 267 +++ .../difffile-large/16/CacheHandler16_22.dn | 267 +++ .../difffile-large/16/CacheHandler16_23.dn | 267 +++ .../difffile-large/16/CacheHandler16_24.dn | 267 +++ .../difffile-large/16/CacheHandler16_25.dn | 267 +++ .../difffile-large/16/CacheHandler16_26.dn | 267 +++ .../difffile-large/16/CacheHandler16_27.dn | 267 +++ .../difffile-large/16/CacheHandler16_28.dn | 267 +++ .../difffile-large/16/CacheHandler16_29.dn | 267 +++ .../difffile-large/16/CacheHandler16_3.dn | 267 +++ .../difffile-large/16/CacheHandler16_30.dn | 267 +++ .../difffile-large/16/CacheHandler16_31.dn | 267 +++ .../difffile-large/16/CacheHandler16_32.dn | 267 +++ .../difffile-large/16/CacheHandler16_33.dn | 267 +++ .../difffile-large/16/CacheHandler16_34.dn | 267 +++ .../difffile-large/16/CacheHandler16_4.dn | 267 +++ .../difffile-large/16/CacheHandler16_5.dn | 267 +++ .../difffile-large/16/CacheHandler16_6.dn | 267 +++ .../difffile-large/16/CacheHandler16_7.dn | 267 +++ .../difffile-large/16/CacheHandler16_8.dn | 267 +++ .../difffile-large/16/CacheHandler16_9.dn | 267 +++ .../difffile-large/17/CacheHandler17_0.dn | 267 +++ .../difffile-large/17/CacheHandler17_1.dn | 267 +++ .../difffile-large/17/CacheHandler17_10.dn | 267 +++ .../difffile-large/17/CacheHandler17_11.dn | 267 +++ .../difffile-large/17/CacheHandler17_12.dn | 267 +++ .../difffile-large/17/CacheHandler17_13.dn | 267 +++ .../difffile-large/17/CacheHandler17_14.dn | 267 +++ .../difffile-large/17/CacheHandler17_15.dn | 267 +++ .../difffile-large/17/CacheHandler17_16.dn | 267 +++ .../difffile-large/17/CacheHandler17_17.dn | 267 +++ .../difffile-large/17/CacheHandler17_18.dn | 267 +++ .../difffile-large/17/CacheHandler17_19.dn | 267 +++ .../difffile-large/17/CacheHandler17_2.dn | 267 +++ .../difffile-large/17/CacheHandler17_20.dn | 267 +++ .../difffile-large/17/CacheHandler17_21.dn | 267 +++ .../difffile-large/17/CacheHandler17_22.dn | 267 +++ .../difffile-large/17/CacheHandler17_23.dn | 267 +++ .../difffile-large/17/CacheHandler17_24.dn | 267 +++ .../difffile-large/17/CacheHandler17_25.dn | 267 +++ .../difffile-large/17/CacheHandler17_26.dn | 267 +++ .../difffile-large/17/CacheHandler17_27.dn | 267 +++ .../difffile-large/17/CacheHandler17_28.dn | 267 +++ .../difffile-large/17/CacheHandler17_29.dn | 267 +++ .../difffile-large/17/CacheHandler17_3.dn | 267 +++ .../difffile-large/17/CacheHandler17_30.dn | 267 +++ .../difffile-large/17/CacheHandler17_31.dn | 267 +++ .../difffile-large/17/CacheHandler17_32.dn | 267 +++ .../difffile-large/17/CacheHandler17_33.dn | 267 +++ .../difffile-large/17/CacheHandler17_34.dn | 267 +++ .../difffile-large/17/CacheHandler17_4.dn | 267 +++ .../difffile-large/17/CacheHandler17_5.dn | 267 +++ .../difffile-large/17/CacheHandler17_6.dn | 267 +++ .../difffile-large/17/CacheHandler17_7.dn | 267 +++ .../difffile-large/17/CacheHandler17_8.dn | 267 +++ .../difffile-large/17/CacheHandler17_9.dn | 267 +++ dat/cache/difffile-large/17/chromosomes.txt | 35 + dat/cache/difffile-large/2/CacheHandler2_0.dn | 267 +++ dat/cache/difffile-large/2/CacheHandler2_1.dn | 267 +++ .../difffile-large/2/CacheHandler2_10.dn | 267 +++ .../difffile-large/2/CacheHandler2_11.dn | 267 +++ .../difffile-large/2/CacheHandler2_12.dn | 267 +++ .../difffile-large/2/CacheHandler2_13.dn | 267 +++ .../difffile-large/2/CacheHandler2_14.dn | 267 +++ .../difffile-large/2/CacheHandler2_15.dn | 267 +++ .../difffile-large/2/CacheHandler2_16.dn | 267 +++ .../difffile-large/2/CacheHandler2_17.dn | 267 +++ .../difffile-large/2/CacheHandler2_18.dn | 267 +++ .../difffile-large/2/CacheHandler2_19.dn | 267 +++ dat/cache/difffile-large/2/CacheHandler2_2.dn | 267 +++ .../difffile-large/2/CacheHandler2_20.dn | 267 +++ .../difffile-large/2/CacheHandler2_21.dn | 267 +++ .../difffile-large/2/CacheHandler2_22.dn | 267 +++ .../difffile-large/2/CacheHandler2_23.dn | 267 +++ .../difffile-large/2/CacheHandler2_24.dn | 267 +++ .../difffile-large/2/CacheHandler2_25.dn | 267 +++ .../difffile-large/2/CacheHandler2_26.dn | 267 +++ .../difffile-large/2/CacheHandler2_27.dn | 267 +++ .../difffile-large/2/CacheHandler2_28.dn | 267 +++ .../difffile-large/2/CacheHandler2_29.dn | 267 +++ dat/cache/difffile-large/2/CacheHandler2_3.dn | 267 +++ .../difffile-large/2/CacheHandler2_30.dn | 267 +++ .../difffile-large/2/CacheHandler2_31.dn | 267 +++ .../difffile-large/2/CacheHandler2_32.dn | 267 +++ .../difffile-large/2/CacheHandler2_33.dn | 267 +++ .../difffile-large/2/CacheHandler2_34.dn | 267 +++ dat/cache/difffile-large/2/CacheHandler2_4.dn | 267 +++ dat/cache/difffile-large/2/CacheHandler2_5.dn | 267 +++ dat/cache/difffile-large/2/CacheHandler2_6.dn | 267 +++ dat/cache/difffile-large/2/CacheHandler2_7.dn | 267 +++ dat/cache/difffile-large/2/CacheHandler2_8.dn | 267 +++ dat/cache/difffile-large/2/CacheHandler2_9.dn | 267 +++ dat/cache/difffile-large/3/CacheHandler3_0.dn | 267 +++ dat/cache/difffile-large/3/CacheHandler3_1.dn | 267 +++ .../difffile-large/3/CacheHandler3_10.dn | 267 +++ .../difffile-large/3/CacheHandler3_11.dn | 267 +++ .../difffile-large/3/CacheHandler3_12.dn | 267 +++ .../difffile-large/3/CacheHandler3_13.dn | 267 +++ .../difffile-large/3/CacheHandler3_14.dn | 267 +++ .../difffile-large/3/CacheHandler3_15.dn | 267 +++ .../difffile-large/3/CacheHandler3_16.dn | 267 +++ .../difffile-large/3/CacheHandler3_17.dn | 267 +++ .../difffile-large/3/CacheHandler3_18.dn | 267 +++ .../difffile-large/3/CacheHandler3_19.dn | 267 +++ dat/cache/difffile-large/3/CacheHandler3_2.dn | 267 +++ .../difffile-large/3/CacheHandler3_20.dn | 267 +++ .../difffile-large/3/CacheHandler3_21.dn | 267 +++ .../difffile-large/3/CacheHandler3_22.dn | 267 +++ .../difffile-large/3/CacheHandler3_23.dn | 267 +++ .../difffile-large/3/CacheHandler3_24.dn | 267 +++ .../difffile-large/3/CacheHandler3_25.dn | 267 +++ .../difffile-large/3/CacheHandler3_26.dn | 267 +++ .../difffile-large/3/CacheHandler3_27.dn | 267 +++ .../difffile-large/3/CacheHandler3_28.dn | 267 +++ .../difffile-large/3/CacheHandler3_29.dn | 267 +++ dat/cache/difffile-large/3/CacheHandler3_3.dn | 267 +++ .../difffile-large/3/CacheHandler3_30.dn | 267 +++ .../difffile-large/3/CacheHandler3_31.dn | 267 +++ .../difffile-large/3/CacheHandler3_32.dn | 267 +++ .../difffile-large/3/CacheHandler3_33.dn | 267 +++ .../difffile-large/3/CacheHandler3_34.dn | 267 +++ dat/cache/difffile-large/3/CacheHandler3_4.dn | 267 +++ dat/cache/difffile-large/3/CacheHandler3_5.dn | 267 +++ dat/cache/difffile-large/3/CacheHandler3_6.dn | 267 +++ dat/cache/difffile-large/3/CacheHandler3_7.dn | 267 +++ dat/cache/difffile-large/3/CacheHandler3_8.dn | 267 +++ dat/cache/difffile-large/3/CacheHandler3_9.dn | 267 +++ dat/cache/difffile-large/4/CacheHandler4_0.dn | 267 +++ dat/cache/difffile-large/4/CacheHandler4_1.dn | 267 +++ .../difffile-large/4/CacheHandler4_10.dn | 267 +++ .../difffile-large/4/CacheHandler4_11.dn | 267 +++ .../difffile-large/4/CacheHandler4_12.dn | 267 +++ .../difffile-large/4/CacheHandler4_13.dn | 267 +++ .../difffile-large/4/CacheHandler4_14.dn | 267 +++ .../difffile-large/4/CacheHandler4_15.dn | 267 +++ .../difffile-large/4/CacheHandler4_16.dn | 267 +++ .../difffile-large/4/CacheHandler4_17.dn | 267 +++ .../difffile-large/4/CacheHandler4_18.dn | 267 +++ .../difffile-large/4/CacheHandler4_19.dn | 267 +++ dat/cache/difffile-large/4/CacheHandler4_2.dn | 267 +++ .../difffile-large/4/CacheHandler4_20.dn | 267 +++ .../difffile-large/4/CacheHandler4_21.dn | 267 +++ .../difffile-large/4/CacheHandler4_22.dn | 267 +++ .../difffile-large/4/CacheHandler4_23.dn | 267 +++ .../difffile-large/4/CacheHandler4_24.dn | 267 +++ .../difffile-large/4/CacheHandler4_25.dn | 267 +++ .../difffile-large/4/CacheHandler4_26.dn | 267 +++ .../difffile-large/4/CacheHandler4_27.dn | 267 +++ .../difffile-large/4/CacheHandler4_28.dn | 267 +++ .../difffile-large/4/CacheHandler4_29.dn | 267 +++ dat/cache/difffile-large/4/CacheHandler4_3.dn | 267 +++ .../difffile-large/4/CacheHandler4_30.dn | 267 +++ .../difffile-large/4/CacheHandler4_31.dn | 267 +++ .../difffile-large/4/CacheHandler4_32.dn | 267 +++ .../difffile-large/4/CacheHandler4_33.dn | 267 +++ .../difffile-large/4/CacheHandler4_34.dn | 267 +++ dat/cache/difffile-large/4/CacheHandler4_4.dn | 267 +++ dat/cache/difffile-large/4/CacheHandler4_5.dn | 267 +++ dat/cache/difffile-large/4/CacheHandler4_6.dn | 267 +++ dat/cache/difffile-large/4/CacheHandler4_7.dn | 267 +++ dat/cache/difffile-large/4/CacheHandler4_8.dn | 267 +++ dat/cache/difffile-large/4/CacheHandler4_9.dn | 267 +++ dat/cache/difffile-large/5/CacheHandler5_0.dn | 267 +++ dat/cache/difffile-large/5/CacheHandler5_1.dn | 267 +++ .../difffile-large/5/CacheHandler5_10.dn | 267 +++ .../difffile-large/5/CacheHandler5_11.dn | 267 +++ .../difffile-large/5/CacheHandler5_12.dn | 267 +++ .../difffile-large/5/CacheHandler5_13.dn | 267 +++ .../difffile-large/5/CacheHandler5_14.dn | 267 +++ .../difffile-large/5/CacheHandler5_15.dn | 267 +++ .../difffile-large/5/CacheHandler5_16.dn | 267 +++ .../difffile-large/5/CacheHandler5_17.dn | 267 +++ .../difffile-large/5/CacheHandler5_18.dn | 267 +++ .../difffile-large/5/CacheHandler5_19.dn | 267 +++ dat/cache/difffile-large/5/CacheHandler5_2.dn | 267 +++ .../difffile-large/5/CacheHandler5_20.dn | 267 +++ .../difffile-large/5/CacheHandler5_21.dn | 267 +++ .../difffile-large/5/CacheHandler5_22.dn | 267 +++ .../difffile-large/5/CacheHandler5_23.dn | 267 +++ .../difffile-large/5/CacheHandler5_24.dn | 267 +++ .../difffile-large/5/CacheHandler5_25.dn | 267 +++ .../difffile-large/5/CacheHandler5_26.dn | 267 +++ .../difffile-large/5/CacheHandler5_27.dn | 267 +++ .../difffile-large/5/CacheHandler5_28.dn | 267 +++ .../difffile-large/5/CacheHandler5_29.dn | 267 +++ dat/cache/difffile-large/5/CacheHandler5_3.dn | 267 +++ .../difffile-large/5/CacheHandler5_30.dn | 267 +++ .../difffile-large/5/CacheHandler5_31.dn | 267 +++ .../difffile-large/5/CacheHandler5_32.dn | 267 +++ .../difffile-large/5/CacheHandler5_33.dn | 267 +++ .../difffile-large/5/CacheHandler5_34.dn | 267 +++ dat/cache/difffile-large/5/CacheHandler5_4.dn | 267 +++ dat/cache/difffile-large/5/CacheHandler5_5.dn | 267 +++ dat/cache/difffile-large/5/CacheHandler5_6.dn | 267 +++ dat/cache/difffile-large/5/CacheHandler5_7.dn | 267 +++ dat/cache/difffile-large/5/CacheHandler5_8.dn | 267 +++ dat/cache/difffile-large/5/CacheHandler5_9.dn | 267 +++ dat/cache/difffile-large/6/CacheHandler6_0.dn | 267 +++ dat/cache/difffile-large/6/CacheHandler6_1.dn | 267 +++ .../difffile-large/6/CacheHandler6_10.dn | 267 +++ .../difffile-large/6/CacheHandler6_11.dn | 267 +++ .../difffile-large/6/CacheHandler6_12.dn | 267 +++ .../difffile-large/6/CacheHandler6_13.dn | 267 +++ .../difffile-large/6/CacheHandler6_14.dn | 267 +++ .../difffile-large/6/CacheHandler6_15.dn | 267 +++ .../difffile-large/6/CacheHandler6_16.dn | 267 +++ .../difffile-large/6/CacheHandler6_17.dn | 267 +++ .../difffile-large/6/CacheHandler6_18.dn | 267 +++ .../difffile-large/6/CacheHandler6_19.dn | 267 +++ dat/cache/difffile-large/6/CacheHandler6_2.dn | 267 +++ .../difffile-large/6/CacheHandler6_20.dn | 267 +++ .../difffile-large/6/CacheHandler6_21.dn | 267 +++ .../difffile-large/6/CacheHandler6_22.dn | 267 +++ .../difffile-large/6/CacheHandler6_23.dn | 267 +++ .../difffile-large/6/CacheHandler6_24.dn | 267 +++ .../difffile-large/6/CacheHandler6_25.dn | 267 +++ .../difffile-large/6/CacheHandler6_26.dn | 267 +++ .../difffile-large/6/CacheHandler6_27.dn | 267 +++ .../difffile-large/6/CacheHandler6_28.dn | 267 +++ .../difffile-large/6/CacheHandler6_29.dn | 267 +++ dat/cache/difffile-large/6/CacheHandler6_3.dn | 267 +++ .../difffile-large/6/CacheHandler6_30.dn | 267 +++ .../difffile-large/6/CacheHandler6_31.dn | 267 +++ .../difffile-large/6/CacheHandler6_32.dn | 267 +++ .../difffile-large/6/CacheHandler6_33.dn | 267 +++ .../difffile-large/6/CacheHandler6_34.dn | 267 +++ dat/cache/difffile-large/6/CacheHandler6_4.dn | 267 +++ dat/cache/difffile-large/6/CacheHandler6_5.dn | 267 +++ dat/cache/difffile-large/6/CacheHandler6_6.dn | 267 +++ dat/cache/difffile-large/6/CacheHandler6_7.dn | 267 +++ dat/cache/difffile-large/6/CacheHandler6_8.dn | 267 +++ dat/cache/difffile-large/6/CacheHandler6_9.dn | 267 +++ dat/cache/difffile-large/7/CacheHandler7_0.dn | 267 +++ dat/cache/difffile-large/7/CacheHandler7_1.dn | 267 +++ .../difffile-large/7/CacheHandler7_10.dn | 267 +++ .../difffile-large/7/CacheHandler7_11.dn | 267 +++ .../difffile-large/7/CacheHandler7_12.dn | 267 +++ .../difffile-large/7/CacheHandler7_13.dn | 267 +++ .../difffile-large/7/CacheHandler7_14.dn | 267 +++ .../difffile-large/7/CacheHandler7_15.dn | 267 +++ .../difffile-large/7/CacheHandler7_16.dn | 267 +++ .../difffile-large/7/CacheHandler7_17.dn | 267 +++ .../difffile-large/7/CacheHandler7_18.dn | 267 +++ .../difffile-large/7/CacheHandler7_19.dn | 267 +++ dat/cache/difffile-large/7/CacheHandler7_2.dn | 267 +++ .../difffile-large/7/CacheHandler7_20.dn | 267 +++ .../difffile-large/7/CacheHandler7_21.dn | 267 +++ .../difffile-large/7/CacheHandler7_22.dn | 267 +++ .../difffile-large/7/CacheHandler7_23.dn | 267 +++ .../difffile-large/7/CacheHandler7_24.dn | 267 +++ .../difffile-large/7/CacheHandler7_25.dn | 267 +++ .../difffile-large/7/CacheHandler7_26.dn | 267 +++ .../difffile-large/7/CacheHandler7_27.dn | 267 +++ .../difffile-large/7/CacheHandler7_28.dn | 267 +++ .../difffile-large/7/CacheHandler7_29.dn | 267 +++ dat/cache/difffile-large/7/CacheHandler7_3.dn | 267 +++ .../difffile-large/7/CacheHandler7_30.dn | 267 +++ .../difffile-large/7/CacheHandler7_31.dn | 267 +++ .../difffile-large/7/CacheHandler7_32.dn | 267 +++ .../difffile-large/7/CacheHandler7_33.dn | 267 +++ .../difffile-large/7/CacheHandler7_34.dn | 267 +++ dat/cache/difffile-large/7/CacheHandler7_4.dn | 267 +++ dat/cache/difffile-large/7/CacheHandler7_5.dn | 267 +++ dat/cache/difffile-large/7/CacheHandler7_6.dn | 267 +++ dat/cache/difffile-large/7/CacheHandler7_7.dn | 267 +++ dat/cache/difffile-large/7/CacheHandler7_8.dn | 267 +++ dat/cache/difffile-large/7/CacheHandler7_9.dn | 267 +++ dat/cache/difffile-large/8/CacheHandler8_0.dn | 267 +++ dat/cache/difffile-large/8/CacheHandler8_1.dn | 267 +++ .../difffile-large/8/CacheHandler8_10.dn | 267 +++ .../difffile-large/8/CacheHandler8_11.dn | 267 +++ .../difffile-large/8/CacheHandler8_12.dn | 267 +++ .../difffile-large/8/CacheHandler8_13.dn | 267 +++ .../difffile-large/8/CacheHandler8_14.dn | 267 +++ .../difffile-large/8/CacheHandler8_15.dn | 267 +++ .../difffile-large/8/CacheHandler8_16.dn | 267 +++ .../difffile-large/8/CacheHandler8_17.dn | 267 +++ .../difffile-large/8/CacheHandler8_18.dn | 267 +++ .../difffile-large/8/CacheHandler8_19.dn | 267 +++ dat/cache/difffile-large/8/CacheHandler8_2.dn | 267 +++ .../difffile-large/8/CacheHandler8_20.dn | 267 +++ .../difffile-large/8/CacheHandler8_21.dn | 267 +++ .../difffile-large/8/CacheHandler8_22.dn | 267 +++ .../difffile-large/8/CacheHandler8_23.dn | 267 +++ .../difffile-large/8/CacheHandler8_24.dn | 267 +++ .../difffile-large/8/CacheHandler8_25.dn | 267 +++ .../difffile-large/8/CacheHandler8_26.dn | 267 +++ .../difffile-large/8/CacheHandler8_27.dn | 267 +++ .../difffile-large/8/CacheHandler8_28.dn | 267 +++ .../difffile-large/8/CacheHandler8_29.dn | 267 +++ dat/cache/difffile-large/8/CacheHandler8_3.dn | 267 +++ .../difffile-large/8/CacheHandler8_30.dn | 267 +++ .../difffile-large/8/CacheHandler8_31.dn | 267 +++ .../difffile-large/8/CacheHandler8_32.dn | 267 +++ .../difffile-large/8/CacheHandler8_33.dn | 267 +++ .../difffile-large/8/CacheHandler8_34.dn | 267 +++ dat/cache/difffile-large/8/CacheHandler8_4.dn | 267 +++ dat/cache/difffile-large/8/CacheHandler8_5.dn | 267 +++ dat/cache/difffile-large/8/CacheHandler8_6.dn | 267 +++ dat/cache/difffile-large/8/CacheHandler8_7.dn | 267 +++ dat/cache/difffile-large/8/CacheHandler8_8.dn | 267 +++ dat/cache/difffile-large/8/CacheHandler8_9.dn | 267 +++ dat/cache/difffile-large/9/CacheHandler9_0.dn | 267 +++ dat/cache/difffile-large/9/CacheHandler9_1.dn | 267 +++ .../difffile-large/9/CacheHandler9_10.dn | 267 +++ .../difffile-large/9/CacheHandler9_11.dn | 267 +++ .../difffile-large/9/CacheHandler9_12.dn | 267 +++ .../difffile-large/9/CacheHandler9_13.dn | 267 +++ .../difffile-large/9/CacheHandler9_14.dn | 267 +++ .../difffile-large/9/CacheHandler9_15.dn | 267 +++ .../difffile-large/9/CacheHandler9_16.dn | 267 +++ .../difffile-large/9/CacheHandler9_17.dn | 267 +++ .../difffile-large/9/CacheHandler9_18.dn | 267 +++ .../difffile-large/9/CacheHandler9_19.dn | 267 +++ dat/cache/difffile-large/9/CacheHandler9_2.dn | 267 +++ .../difffile-large/9/CacheHandler9_20.dn | 267 +++ .../difffile-large/9/CacheHandler9_21.dn | 267 +++ .../difffile-large/9/CacheHandler9_22.dn | 267 +++ .../difffile-large/9/CacheHandler9_23.dn | 267 +++ .../difffile-large/9/CacheHandler9_24.dn | 267 +++ .../difffile-large/9/CacheHandler9_25.dn | 267 +++ .../difffile-large/9/CacheHandler9_26.dn | 267 +++ .../difffile-large/9/CacheHandler9_27.dn | 267 +++ .../difffile-large/9/CacheHandler9_28.dn | 267 +++ .../difffile-large/9/CacheHandler9_29.dn | 267 +++ dat/cache/difffile-large/9/CacheHandler9_3.dn | 267 +++ .../difffile-large/9/CacheHandler9_30.dn | 267 +++ .../difffile-large/9/CacheHandler9_31.dn | 267 +++ .../difffile-large/9/CacheHandler9_32.dn | 267 +++ .../difffile-large/9/CacheHandler9_33.dn | 267 +++ .../difffile-large/9/CacheHandler9_34.dn | 267 +++ dat/cache/difffile-large/9/CacheHandler9_4.dn | 267 +++ dat/cache/difffile-large/9/CacheHandler9_5.dn | 267 +++ dat/cache/difffile-large/9/CacheHandler9_6.dn | 267 +++ dat/cache/difffile-large/9/CacheHandler9_7.dn | 267 +++ dat/cache/difffile-large/9/CacheHandler9_8.dn | 267 +++ dat/cache/difffile-large/9/CacheHandler9_9.dn | 267 +++ dat/helloworld/output0.txt | 100 + dat/helloworld/output100.txt | 100 + dat/helloworld/output50.txt | 100 + dat/output (normal).txt | 648 +++++ dat/output (verbose).txt | 1027 ++++++++ dat/results/results_difffile-large.ods | Bin 0 -> 36022 bytes dat/results/results_samefile-images.ods | Bin 0 -> 34761 bytes dat/runTests.sh | 24 + dat/scripts/difffile-html.script | 44 + dat/scripts/difffile-images.script | 48 + dat/scripts/difffile-large.script | 40 + dat/scripts/difffile-small.script | 40 + dat/scripts/difffile.script | 40 + dat/scripts/samefile-html.script | 40 + dat/scripts/samefile-images.script | 40 + index.html | 68 + report/final-report.aux | 164 ++ report/final-report.bbl | 130 + report/final-report.bib | 193 ++ report/final-report.blg | 15 + report/final-report.log | 1203 ++++++++++ report/final-report.pdf | Bin 0 -> 383434 bytes report/final-report.synctex.gz | Bin 0 -> 479634 bytes report/final-report.tex | 753 ++++++ report/img/Thumbs.db | Bin 0 -> 82432 bytes report/img/difffile-large-wo.png | Bin 0 -> 10017 bytes report/img/difffile-large.png | Bin 0 -> 12280 bytes report/img/samefile-images-wo.png | Bin 0 -> 14741 bytes report/img/samefile-images.png | Bin 0 -> 15236 bytes src/cachingpolicy/LICENSE.md | 675 ++++++ src/cachingpolicy/README.md | 32 + .../cachebackup/CacheHandlerBase.dn | 278 +++ src/cachingpolicy/emergenetic.dn | 201 ++ src/cachingpolicy/htdocs/GenerateContent.dn | 17 + src/cachingpolicy/htdocs/GenerateContent.o | Bin 0 -> 45515 bytes src/cachingpolicy/htdocs/Thumbs.db | Bin 0 -> 23552 bytes src/cachingpolicy/htdocs/image_big.jpg | Bin 0 -> 1671167 bytes src/cachingpolicy/htdocs/image_med.jpg | Bin 0 -> 84760 bytes src/cachingpolicy/htdocs/image_small.jpg | Bin 0 -> 4001 bytes src/cachingpolicy/htdocs/index.html | 32 + src/cachingpolicy/htdocs/index_150KB.html | 1282 ++++++++++ src/cachingpolicy/htdocs/index_big.html | 709 ++++++ src/cachingpolicy/htdocs/index_huge.html | 2113 +++++++++++++++++ src/cachingpolicy/htdocs/index_med.html | 31 + src/cachingpolicy/htdocs/index_small.html | 11 + .../project/cachingpolicy/config.conf | 7 + .../project/cachingpolicy/mutator.py | 329 +++ .../project/cachingpolicy/setup.sh | 13 + .../resources/cache/CacheHandler.dn | 36 + src/emergenetic/LICENSE.md | 675 ++++++ src/emergenetic/README.md | 46 + src/emergenetic/emergenetic.dn | 167 ++ src/emergenetic/scripts/blank.script | 0 src/helloworld/LICENSE.md | 675 ++++++ src/helloworld/README.md | 32 + src/helloworld/project/helloworld/mutator.py | 94 + src/helloworld/project/helloworld/setup.sh | 13 + 698 files changed, 180798 insertions(+) create mode 100644 README.txt create mode 100644 dat/archives/difffile-html.bz2 create mode 100644 dat/archives/difffile-images.bz2 create mode 100644 dat/archives/difffile-large.bz2 create mode 100644 dat/archives/difffile-small.bz2 create mode 100644 dat/archives/difffile.bz2 create mode 100644 dat/archives/samefile-html.bz2 create mode 100644 dat/archives/samefile-images.bz2 create mode 100644 dat/cache/CacheHandlerBase.dn create mode 100644 dat/cache/Thumbs.db create mode 100644 dat/cache/difffile-large/0/CacheHandler0_0.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_1.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_10.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_11.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_12.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_13.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_14.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_15.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_16.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_17.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_18.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_19.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_2.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_20.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_21.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_22.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_23.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_24.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_25.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_26.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_27.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_28.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_29.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_3.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_30.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_31.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_32.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_33.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_34.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_4.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_5.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_6.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_7.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_8.dn create mode 100644 dat/cache/difffile-large/0/CacheHandler0_9.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_0.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_1.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_10.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_11.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_12.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_13.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_14.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_15.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_16.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_17.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_18.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_19.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_2.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_20.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_21.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_22.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_23.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_24.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_25.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_26.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_27.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_28.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_29.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_3.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_30.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_31.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_32.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_33.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_34.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_4.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_5.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_6.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_7.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_8.dn create mode 100644 dat/cache/difffile-large/1/CacheHandler1_9.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_0.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_1.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_10.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_11.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_12.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_13.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_14.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_15.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_16.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_17.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_18.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_19.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_2.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_20.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_21.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_22.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_23.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_24.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_25.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_26.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_27.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_28.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_29.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_3.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_30.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_31.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_32.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_33.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_34.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_4.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_5.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_6.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_7.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_8.dn create mode 100644 dat/cache/difffile-large/10/CacheHandler10_9.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_0.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_1.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_10.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_11.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_12.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_13.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_14.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_15.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_16.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_17.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_18.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_19.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_2.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_20.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_21.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_22.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_23.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_24.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_25.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_26.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_27.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_28.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_29.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_3.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_30.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_31.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_32.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_33.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_34.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_4.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_5.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_6.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_7.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_8.dn create mode 100644 dat/cache/difffile-large/11/CacheHandler11_9.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_0.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_1.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_10.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_11.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_12.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_13.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_14.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_15.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_16.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_17.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_18.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_19.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_2.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_20.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_21.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_22.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_23.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_24.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_25.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_26.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_27.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_28.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_29.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_3.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_30.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_31.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_32.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_33.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_34.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_4.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_5.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_6.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_7.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_8.dn create mode 100644 dat/cache/difffile-large/12/CacheHandler12_9.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_0.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_1.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_10.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_11.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_12.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_13.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_14.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_15.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_16.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_17.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_18.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_19.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_2.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_20.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_21.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_22.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_23.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_24.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_25.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_26.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_27.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_28.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_29.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_3.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_30.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_31.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_32.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_33.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_34.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_4.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_5.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_6.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_7.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_8.dn create mode 100644 dat/cache/difffile-large/13/CacheHandler13_9.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_0.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_1.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_10.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_11.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_12.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_13.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_14.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_15.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_16.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_17.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_18.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_19.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_2.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_20.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_21.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_22.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_23.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_24.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_25.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_26.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_27.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_28.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_29.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_3.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_30.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_31.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_32.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_33.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_34.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_4.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_5.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_6.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_7.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_8.dn create mode 100644 dat/cache/difffile-large/14/CacheHandler14_9.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_0.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_1.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_10.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_11.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_12.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_13.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_14.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_15.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_16.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_17.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_18.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_19.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_2.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_20.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_21.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_22.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_23.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_24.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_25.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_26.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_27.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_28.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_29.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_3.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_30.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_31.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_32.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_33.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_34.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_4.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_5.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_6.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_7.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_8.dn create mode 100644 dat/cache/difffile-large/15/CacheHandler15_9.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_0.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_1.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_10.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_11.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_12.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_13.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_14.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_15.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_16.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_17.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_18.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_19.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_2.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_20.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_21.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_22.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_23.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_24.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_25.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_26.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_27.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_28.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_29.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_3.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_30.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_31.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_32.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_33.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_34.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_4.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_5.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_6.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_7.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_8.dn create mode 100644 dat/cache/difffile-large/16/CacheHandler16_9.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_0.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_1.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_10.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_11.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_12.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_13.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_14.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_15.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_16.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_17.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_18.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_19.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_2.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_20.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_21.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_22.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_23.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_24.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_25.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_26.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_27.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_28.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_29.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_3.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_30.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_31.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_32.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_33.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_34.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_4.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_5.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_6.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_7.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_8.dn create mode 100644 dat/cache/difffile-large/17/CacheHandler17_9.dn create mode 100644 dat/cache/difffile-large/17/chromosomes.txt create mode 100644 dat/cache/difffile-large/2/CacheHandler2_0.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_1.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_10.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_11.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_12.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_13.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_14.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_15.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_16.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_17.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_18.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_19.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_2.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_20.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_21.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_22.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_23.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_24.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_25.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_26.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_27.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_28.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_29.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_3.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_30.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_31.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_32.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_33.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_34.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_4.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_5.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_6.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_7.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_8.dn create mode 100644 dat/cache/difffile-large/2/CacheHandler2_9.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_0.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_1.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_10.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_11.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_12.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_13.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_14.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_15.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_16.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_17.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_18.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_19.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_2.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_20.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_21.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_22.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_23.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_24.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_25.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_26.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_27.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_28.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_29.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_3.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_30.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_31.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_32.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_33.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_34.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_4.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_5.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_6.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_7.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_8.dn create mode 100644 dat/cache/difffile-large/3/CacheHandler3_9.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_0.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_1.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_10.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_11.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_12.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_13.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_14.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_15.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_16.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_17.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_18.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_19.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_2.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_20.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_21.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_22.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_23.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_24.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_25.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_26.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_27.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_28.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_29.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_3.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_30.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_31.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_32.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_33.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_34.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_4.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_5.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_6.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_7.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_8.dn create mode 100644 dat/cache/difffile-large/4/CacheHandler4_9.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_0.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_1.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_10.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_11.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_12.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_13.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_14.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_15.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_16.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_17.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_18.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_19.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_2.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_20.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_21.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_22.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_23.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_24.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_25.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_26.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_27.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_28.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_29.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_3.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_30.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_31.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_32.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_33.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_34.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_4.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_5.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_6.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_7.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_8.dn create mode 100644 dat/cache/difffile-large/5/CacheHandler5_9.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_0.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_1.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_10.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_11.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_12.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_13.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_14.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_15.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_16.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_17.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_18.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_19.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_2.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_20.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_21.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_22.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_23.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_24.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_25.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_26.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_27.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_28.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_29.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_3.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_30.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_31.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_32.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_33.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_34.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_4.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_5.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_6.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_7.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_8.dn create mode 100644 dat/cache/difffile-large/6/CacheHandler6_9.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_0.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_1.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_10.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_11.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_12.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_13.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_14.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_15.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_16.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_17.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_18.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_19.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_2.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_20.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_21.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_22.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_23.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_24.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_25.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_26.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_27.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_28.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_29.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_3.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_30.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_31.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_32.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_33.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_34.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_4.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_5.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_6.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_7.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_8.dn create mode 100644 dat/cache/difffile-large/7/CacheHandler7_9.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_0.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_1.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_10.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_11.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_12.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_13.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_14.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_15.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_16.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_17.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_18.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_19.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_2.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_20.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_21.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_22.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_23.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_24.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_25.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_26.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_27.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_28.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_29.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_3.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_30.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_31.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_32.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_33.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_34.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_4.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_5.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_6.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_7.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_8.dn create mode 100644 dat/cache/difffile-large/8/CacheHandler8_9.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_0.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_1.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_10.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_11.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_12.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_13.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_14.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_15.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_16.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_17.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_18.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_19.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_2.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_20.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_21.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_22.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_23.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_24.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_25.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_26.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_27.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_28.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_29.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_3.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_30.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_31.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_32.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_33.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_34.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_4.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_5.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_6.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_7.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_8.dn create mode 100644 dat/cache/difffile-large/9/CacheHandler9_9.dn create mode 100644 dat/helloworld/output0.txt create mode 100644 dat/helloworld/output100.txt create mode 100644 dat/helloworld/output50.txt create mode 100644 dat/output (normal).txt create mode 100644 dat/output (verbose).txt create mode 100644 dat/results/results_difffile-large.ods create mode 100644 dat/results/results_samefile-images.ods create mode 100644 dat/runTests.sh create mode 100644 dat/scripts/difffile-html.script create mode 100644 dat/scripts/difffile-images.script create mode 100644 dat/scripts/difffile-large.script create mode 100644 dat/scripts/difffile-small.script create mode 100644 dat/scripts/difffile.script create mode 100644 dat/scripts/samefile-html.script create mode 100644 dat/scripts/samefile-images.script create mode 100644 index.html create mode 100644 report/final-report.aux create mode 100644 report/final-report.bbl create mode 100644 report/final-report.bib create mode 100644 report/final-report.blg create mode 100644 report/final-report.log create mode 100644 report/final-report.pdf create mode 100644 report/final-report.synctex.gz create mode 100644 report/final-report.tex create mode 100644 report/img/Thumbs.db create mode 100644 report/img/difffile-large-wo.png create mode 100644 report/img/difffile-large.png create mode 100644 report/img/samefile-images-wo.png create mode 100644 report/img/samefile-images.png create mode 100644 src/cachingpolicy/LICENSE.md create mode 100644 src/cachingpolicy/README.md create mode 100644 src/cachingpolicy/cachebackup/CacheHandlerBase.dn create mode 100644 src/cachingpolicy/emergenetic.dn create mode 100644 src/cachingpolicy/htdocs/GenerateContent.dn create mode 100644 src/cachingpolicy/htdocs/GenerateContent.o create mode 100644 src/cachingpolicy/htdocs/Thumbs.db create mode 100644 src/cachingpolicy/htdocs/image_big.jpg create mode 100644 src/cachingpolicy/htdocs/image_med.jpg create mode 100644 src/cachingpolicy/htdocs/image_small.jpg create mode 100644 src/cachingpolicy/htdocs/index.html create mode 100644 src/cachingpolicy/htdocs/index_150KB.html create mode 100644 src/cachingpolicy/htdocs/index_big.html create mode 100644 src/cachingpolicy/htdocs/index_huge.html create mode 100644 src/cachingpolicy/htdocs/index_med.html create mode 100644 src/cachingpolicy/htdocs/index_small.html create mode 100644 src/cachingpolicy/project/cachingpolicy/config.conf create mode 100644 src/cachingpolicy/project/cachingpolicy/mutator.py create mode 100644 src/cachingpolicy/project/cachingpolicy/setup.sh create mode 100644 src/cachingpolicy/resources/cache/CacheHandler.dn create mode 100644 src/emergenetic/LICENSE.md create mode 100644 src/emergenetic/README.md create mode 100644 src/emergenetic/emergenetic.dn create mode 100644 src/emergenetic/scripts/blank.script create mode 100644 src/helloworld/LICENSE.md create mode 100644 src/helloworld/README.md create mode 100644 src/helloworld/project/helloworld/mutator.py create mode 100644 src/helloworld/project/helloworld/setup.sh diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..a6d4eb5 --- /dev/null +++ b/README.txt @@ -0,0 +1 @@ +Visit http://www.lancaster.ac.uk/ug/goldswor/scc300/ for webpage. \ No newline at end of file diff --git a/dat/archives/difffile-html.bz2 b/dat/archives/difffile-html.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..12aff56d2c58bbbb88c96859a2532622f510270d GIT binary patch literal 7016 zcmX9?30M%p zfZ~!sJPH9(5Eb}Q2_i^Dids=HsDMR9MDVEpgtCvaB)i`?-^{%4yfbcrYn>cim9rGe z=rzqV%?qMG9(nUlJw5E>$B+A-Jh%(L-kMFHWVX!A%re~R{yqf>|zujj#y>4mYM@du8rop|8*vGL1isP|7>3!gVcn0;n(TOdo(&~sdm8M5;x zI8V!2ZvA@7uLaKDie=-}o@T1KR&qBEt(vu5!KIzKy|ikLv$sgSBC9AN-FfB2FWX*v zySu#iem^06d(Av_w0PJUwmrvsbK&Nih^$uOC%Q!cE6-o{l(n=J=Iv;)x*zfEUUp>i ziccI@#ieOx-P7Xo!}bFuqMO+|PW@k9cKG$!=i@o@>Mf719ef|JeQh%})hkPs>OrhA zH=E>`V(o5z!flGv%tO(t!3}JyXQv?DI@MnJyT7OPOY*AS6wS7I0kcl~hTn6{F3y=l z$Tt>DXE}a}gXxd1yrL>x%v=?<;o z=@{6pQGX=nKlM ztkdfQBM&|L{cp4hZ7~MTp;| zlvN^I(HjkA76EnQo8&hZ0q@#m;=9vjH3`^;94+Y5jT<> z6)PU%My9~h=dlk3QqHmuq0_ z`IeVr#i(J3+Kg%B;z83XJ4lzYZ_t*fXtPS$jpZ}oq-?Y$lbmllSA*#_^aj{Gc6Ez) zQjtbw(%3bEmr=+LlRqrWn#cySlE0sHlk{itDdfsbcQ~~xpW8t$!OPxTmboh%NarLt z!)7curK}Ch=fImSsMu&al4Y3zy;g@_%R=JNmKn%m3Op16=X=HdsSmx80^!@06z~+w zvrxXnFFPT*c&QP+CWi-V5$Ad^r5n9kCm!>F$rRHS0WO0VUvi^PkuLj5XO(gkFB_tw zo}eu^vHW8Y1h~Dyje5n6l1o=3`QhXelNm;|Wi^uEi~sq@i1U-uU(OEgcz5HT>g}S+ zZ4bIfxAhFZ>bSPxWbDYilP7-mS530N>ALx=)?N4ZcK6qfJARlGv+>l6*+pl5G%Jm3 z6Z%oEu`9+cyQ>bo(X;uJ z9_bvVk1AC*$ld#bbd$DY9rC%_74OO)Y-5iHTGgZ~9&sazr!>;v_~LCOPdXLhLhw|+ zA#yQZDgpqiW!@!B{jrTqgH~F_7!)!uj;F;LkteHWJ`*l1bR^aaqeWMVH9`l`0Xv?U zQjs>IcY_i(P!MEUf?i#XLN>jlYnPEDY<1JTwsQF=`R!rwv zYxKe;mPP%X0E`w>Yvd-lTVy5X`l#hunand{`vfT$@zFL-|KKRLRI>ptjo8JdPpLg3 z1lM7y{L5$?+5R(kuetOn`JCEQi*UDG`+C#=7S7C-eeR3j>_UzB1vZdc2ai@`1=3Xr zcQtbMRCBC7!`v5@^QuK2M6@U+n6^)gLp#Vh(FlIoS3VCG9brQZ5+Ij)jTO^WDymXE zC3Z4jEaF#T#qi8Qte79q*I~3h7@eRB>!#wUSUN({%-j+65*wKpg)VN27U6tiTcMM1 zE>n}y$@IcTItA}2FSpmL{C6kBND6}C2>sx0Ft&fLCS6mHFWn zR4laxechk~TOmAK(0)|UKSd^ruOMs)PkIIIMZ2*#@XcyiY(!vMvL6o4kVYyRewUNS z(YshZ8O`S)w1kCS+0ayeAGI%-yp2AAN1wyjG<6(t_^?gj;FDfF;}Lq-_75&PfLE&m zs0gf=N)Uwd>~;1$xMHR2uxip>QNs)tE^_l1Xe=}y%w5a?RYHrgq#(?KE99D=SRpf1-gQl?f{5F@A@tycu>@N0}4Z^GS2*f#?Ux_AjCv&FPE^&8TaA&Y+?(s86vrecbW}0NQ|b$&|$Cj^NAgWOB@w44~SC@-H*Nj z7nwp@O{Ve_!LVK`9=}LSIegitoM3bR1Vtw-w3C-3T*_+ZY6O~fibO>nGjx0%xFG{K zV2_{*qVG^iL&d$w&RD64FG7giXuuro;VE29=L&)vD!{Q%!Mu1x5GuDf0NSXXg3v6) zcji4XJHFv!FFzj9LzX^5hw$^bU$+<%-ioagn~TxwQ=0t3qb}O`Cz1Uoj|u{?KJ*pZ zezwu}j|VPV$g*_2WDDe#0c*r+Aq7-q5jj9bWGD|Cup}izwq?|la_ImShhJJ`6@fh$ z1VCu^#7e+AM^1>Nf>x;1b;LzD9Z&?F$#lAzRw_mBpns#c@V_bq_tjr}z$hRO-r)wTH9seDYbz%a?0kKK=XA zqd)k+Es%cu;m#_6Dz%+CXnC<)GVhNVQt$noipy~RTBW&+J2xu09<^RQlU2t9Ad--U zC8T>06^@;1|Bl9VaG5>=GxSI=QXfRc$mg9763(~se*8$<3G_j$_|9JL3MrudDr)!o^+m% zCJVsd#B@Sd#lxMmbZnqkmV~$K_7k|S2a$HC;*DpTF-Q6AcozeBe;!LIJp@|SZ zg$sxhYBvYg^Y|AtLHIeq=dawgYVz_J7U+D9eMRHj4u`^7y$>Pr_%3aM}E8E%VVb(nx-~S={8E4^yaDO#+%s+qG%XV^(?DT}6K&wvM zpucb_N|RT%A+o%E;nFO=jGrBU>&Ufr>vLu|T}a-5wm**B6DAxM1PxL<8)r{W+1Rt> z@b%UQ4z0JYpPb)x^{dYvGMgfu;=j*WIE3r&-wKHx9=d(@zti`BI%V3FsdW=)xwCj3 z@hT(H&3&rCNjgaF@EUs9AE&LFu%R@4es*KT29Z`*ctRahaqILiiCZ@4(|?-XbM0sI za_k&(sx0rTGmi7Od6nOanq!Xymalu3xrS=-J^7{hMD5~R`N{XD-p*?7&*fbCJye-9 zFTJueYU^{a!*$n!*Iqq*(laZw?e2AP=IXAWTMv|ddi9&llZ)1*#k3z$t~uiP6Vf$j z{gf{y>5c8>xwp<%#NED{b$!EtXVm)p=(F77R(-g?zh~g}EMz;{(b{+WZ5{s+f9Cn4HYil3af*}lR6WbN9y@F}D!lfHNSIU} zYw{&i~`oPpTP(n5V zoynzYDA;nT9`57$!}x`Ua%yiM&^1F22*S=_ALPDQ^EW_cHxjX&KvuJxS1L;NVo#P(dyDx4 zw7nqI9D64S)>4n4zK$A01)s-C*dP|x>qQ3b;T|eqEjr4YN=J3{7kXE(RQ`3SK~JF2 z0i?3A$3VSlCUrGE^?j`L2-d#xG^`SUWu>tyU!|#JG|ljUs!$G~W`U1mr$<257KG{G z{|DaLMW_DegmApCxSuMVt(YUQ*GY{4%0w|*i`0qNPm@a~p@&VyC1< z)OwfMoJHTt?RgSo5U7VfkPcAkO(sMm1zE0kFKX?kXT1Dy`S-`~9=Ke8_0PwFS5K~= zU;=25CVe7tF;Yb<3(DpQ3V*z)mL=BHG65}{6&V?+V&LXd;(o;@*JYxk!aW>s9Wx~J zc3yRecrA1Z1fo+D@pQh&vE8+HR-%-mhC>0qh#ur-uLqr9!Q5H)pUh_Brno>Ys`(y9CrR*80@uR!3u8w9;X z;Cs7}C?4d&HP8pc_~ixVhx$07HN@M886BX~Vwe~BIj8wmh7toyNa!=Xcb%ylLwL zWzO>!&C=bKI~y)qTkC-yr@c^&pYtU;>?!m6-0#X z5>*gh4ysRyb{BtFP7bH&u=MWYZ-D+)q%D=k?i7SIfxx}Yh2ne@ds83w0ewh9$-lla zxN>vP)%7nLDjWV4WO1M^&V!a#fj9;b27`z-X&sQo6^XM9rgBmTYBrrT_v?kZ2B?le zBHoaVtaaGHZoakVP10%ls8KU1 z<4>W}j4klA0W@?mlInYt+)$CT4feSWIe$I;Oxl5J-g$%K5uL-zT7`=Q>c)xai6m1u zBr%$-TZeuw<1-|4EEcp~1o&{8V%@5B*hueZg0NP!PEsfSp8#YJPYn41c*M(>y%7Wp z0wEfmiTPRRYe6WAwaS;rBev8BINwIAkB-n1>?5#dkdM0trF+n~dcGR#0dZ-GlB*sFxm6P?K` zhex0f+SThdq)zk`&K8ElaOPDbm5P9R1VNL^Z-B0EsS@Fd1tFl~OQB=AycvuK?X3U4 zj%g5XD_p<{E!X@idd7xYK(90c-38=_68s5bELqE{$oH(0yB5o`aQV8K*R;X?F8I$-s-d_GP81+<8lrUREI%Uxo~ z(HY#0KtPaL2mUT}wh#@oq1o&n7AzQ5g-w$+5(zA{$TyiQ<5g-VeX$RdS<@V ziT~ah<^jVfu#*F7{2nwLyLs{;xJQaaH++8cA$8wYyXvs#a9lmY0h=NKwcSL5JU7~_ zO_L$2A!+P|AS6ON)Nlci`dSbKa%e3?=BPy)5?W#mI5YqZxOA?%*E?R+wQ{ac za7x+IXoQx!!{&laQz-&nc^>-oq_BRx98Pw~eMk@h=4>|=xjw3zv{0lF2H3ol8DV`k zaK6m~VVlZ_zL%VgkE%ku_?NI0a`t`5qPvOtR#=zMZ&~o&A>zt-xuRN_zEXg;l85I1w#GIQ7 z1AfVx%#a7mq1hm|>7iFLYJ@;{Fcg$8Ma4}pWy}iM6*-rsI`@kfNkLoH6Nd;mHPp z>jUvB4xcWb>hoI-29vIZcqKMlxD^H+N9i2lBJ*z`KVJbqtOmLfA*fc*M~lB^LAeMW zO`}Lpu;ZwyB@}2L=RaAKQQ+N>eMi%KqxVO^MTj6|?ePJ|E}VGG3}s-CL1w%XE~$r} zy#RZHzD**ZtyCDP?Zq>yu-CpbeK43v{$mZ^Y(d`%0PoNqD(-{ZRDd_V2M0z5I*<*= z`2*BXj#w33I_wpGX)2#5(c+t_-GinqZN@t3;#QdBoEE*bIKyaG67Pq!mnMv_b+w}v z?aYWguMI{wZ;jBl?`GZ@HSdKkjl}lCg~G)GO$V`s6Y35V0%*0%sRUbmcQ1(LR`jhP z5U4L~BXq)rX2!`{LQ@5#EcXN!fV$!-bgs!5fZ51HsM{v)X4SO#m>S**W&@}gri~e( zkJkBbu=&=?ViQOwJ+#y&=4TWY#LkBq1{k#50DGI6ca76HVZ~z+y_%dv)=(;-dm5wF za>WP;gdMO2@b{_+lY)r=K4?V;h&fZ>(#X^PXLCSVO#2}fuK$-7oP1k`L$;6+afm3*|06*vvR&6r{-WP#FU_j7L*aU?{MOKqr#zsl- z1ZZcL$elhjQNb_+#AZMRENM%%0i7A4!mq=IK`%72G4jvw^UHpKNu%b;SZR9f%NJ;L zyb5Bkk49uVxoJZ8h|V2n_k_;F@sWl~DsmT3`ZH#<$&-zz6_1ISw1ZV3OB{>&$8G$4 zXC{$%VZhJ?Y34E_jF)Gooiw3=;Z^Gt2Bw$Jrt@tT&kGmx@&Y-bm6N}l=^e2RQP?YRS^KU3R~^vgxzB04Wq zYd_|WZYVL^%;#KINrt@2@#|!?oh@~rfeo4``XARC?bl0D@6+os51@9 zuHq0RmC7axvRH~r_;8D8LB#@%3yO${C}QgkbKfjh)pXx{FTmsU>lB(!^LZKCMDCRD^t-mNs2W* zvr`&IY=3w@AykkhZb|0a8)$+xopQ^`Cd_p7)3f36Jg1WmuiYKjn(!`~n0&SuuE0l< zMZ%%mHZA6pt*uR(CY#(^n_<&rZqj0HJ!4XIbGY{BHRf=a`J|tn#;^G-!z9?;^gD&X zdTvgboBp)u({j6lDFD)7uAiN zW4b8Exdk~Hrxp>Drn*dZn)B-9bKSyxFPtqtU7zZ5xLUV#`cg$6X+L;_?73nbZHQ{v zeDpvF-*T)YEBHplfQ8iWfN4*!Wgs<4Z56cH@vR73`Bk~Yk?Qib1tsjlBa2kA5hZ=o zhb-v(w3@^A;94<~*}QyerhA^AU>dMpn6 z+46FS-I45^Uxk?aqM)wRrlu$M{$gUbee%|{BiM?sf~ljw$vC5$Hi^krI11ellg(}$conIhiu6{TMw&hG zGRmw9ZJOAjTty=()o9z*PVL%f+p9a#b_(-Co2lu99uZ23GKd^&LrN(3wFoI2hq+pY9Y1yG`!j1S)X3VUJHIQ zqSp-dw*K)UAzsy^_7!DI4^%AVd&qL~kMuLiudbKI96G zMB~TSA$z*1#prb}B!Q?rfo#IFxEqr_pP*N|(d$7-40`n{w{!mdde|8nX*6bq=1&CF$sOJ0xBZ+KT5B zl`+ym^qPZLIqZ{{0^0?NdeK`+(k6I#3+1f#N|FX4k$ApYWgTTJh(>Q0!VinlHo;FP zi2w0CU!XTd_OdfCV7IGD^5fv;ddyc4-cGF`D$jF=`1DIkpb;eo>vVL^y#%r?bX5^g)?OceTlw62Lxew{Z{ze!G=-K1+juH z-=tJtq*m8~8SlSe75)|3d=*DR~OW}0*6)!xvu0^E zxO;Hy8S5}+o~P<3CA~s5MfE+eyL-s}xbLBz(b0z|CIzlJnKJFt#4k^n*?;Lf*{sjI zYJE}qf-154()iDKr*+mi_J-cwLD|a=1;g-TjnOB3LymGu4qfHc=(qSF1u#HLzMHhm0n}#IfSVOpdFK<_W3R+<oWZzsUK0V^9dV~28RYbKQ5Kk}6csTLd?4*fjx|w{XN_ebJ(020#I4dsR*D(+o=nJAS8sS7s_$_I*rzB(frlcDr{Z2 zWDN7U^*mMdfT+M3Dbc`3Sbw&RdWOCu8Vcoi1wo>(w_JX|X#dwwi5T4vd=ZL2pd;`S z1oN+u3F7G>M6l7j?IHSvI7deD&X}u&Ib^UZeSiBwwT~bq3e}6A=+?5{^zIp=1X#s- z;!T>ia!IYKpNyY2Ww$N+lrmV_i@%_E5H&65z+JsKBX^@P{}QB7{upf=qQlY0=m5Rj z2+xW~h_hf!xF{9&RyZ-ouFn6qQ1gsDPj98S!KQGBsE$rx{cA)#-;~M;v#;SVVa0QF zL`V0)haNFlDlNHZ!&TVG67y4gp|1tecvfLMRfvxbS;Dn|Dq4L&sY+ATNK&08&f!j2 z4N*TNgX3+dV(o9(BSxL3Sn4l0>|^w;(Hm^s zptOOk0A_1ghZudLDmP0+>0Cnj3uW$ea=1M7?-Rv>XADxP2q{?K{7W$GQK3>eXTwex zPu>HwkB4YyP=;gZ8-ACm_GT`Y9Jt9hg`?5j`-bM;OR;4`6&u{6Lbn!rW9^zL_ZYZ=t2 zQYzTl?1?r>(T{ebe_N{X_YVFB+16`29;aX1`TF{?XW)#BR2yCzehq)m$Xe=JDpw~# zpq{zUX{M57$^H(WfK@wEssu6UkYEQua~(Y734GfMSB3>~bX-aq-jlcZ&p-b-`RB=V zzZ|Ih@7MS1mXCF=+e*jK+cgKx>eb#G{X0de-*!QIzOB)_96Y?!O^aqH73?1mN`!)> zQ3DC$H3-l9YS0K#4KFS)gY>2nC6CEXnpZ_j zAiHY0JeEI#Ao^kc9{Yb0%B$%hQ8WIMj!X6i{%n$ulO+dyNtx9Epfv}CQN@;d=6!k9 zv7wIlv@Dd~Lnz=#q9Oi^e90reHyJN1P!}gL*@AeYn%)B00fNvkv2n@x3xD6Z(U%~+ zIwR`~$JrBd<92BJN>0xB;@2roUk>GE%Nb+aLy_|n6O$R?aj}N>tHmG7(}_W%PVIk6 z*I*Aunia=FEk7s2C6^!>Hz0k8jxLl5LLzX+9JnHa?^j=6pI@J!pI=|!c!f-~5Qn&= z^LED;*J|GOxg627s=COi(#oi$^?H|9O>^<^sS1cP)KnDOgf{~j)KTY)ulI)>Z*Q?$ zncD9XoH(_kpm}6o`O4I;&h4Jo^-B2+(WVb?5|@v@jrn`#MlY>r#>?~&?r&VpZG5-A zG<~e)EZSsUw3~gdYu0Zasx7)PaqL5{{MI{FhcJ3#pP^&HE%g5M#zWiUqsl9ys_&ef zIU(|etIFt{_~=7?^~NJVeRoTHZ)3*U>fC2DHmw?l+BFp9Y-!Ez@i+A$YDXSiE_;^9 z`b2hTO8I@u#dq%Qp1MeTeaeRN&Yq(O@^-Y8U(gm%1yv!Qouy8G&HZ^f{Z~GplCbdF z{j=Gnk;f|V2l>Mfua&edaEdjraxB}h{eFh-lGHQj#+@sExm}6#ENw^H+CtY>E;=%< zR=oJ13kOG{j`)7QtnUbt_l@Px5uKGGxsxu%&D*tXk_`7mw0uQVp9ab4asb zfc5XS92Ef=_+tLCljuDdbtsln|9VrrP@EuG*T)w3kdc~q%DklYC6cE}>%~?U&(VG? zpb#Gx0^>H}?^s`skAZ8{{w4=wWI$$qL-GT#a~>5|9HY{biNbt^GvB#tLB9p1(Y!9Q z6)zj-p;VpyPY!N`W+;uLmszRrt>roR9oJH$KhG1-PGi;XUL1I~&2|K4tD?e1EWL@2 z;RQp@U;#RK@AfDYhib%I$lauPgCr?C3sl3Nuc5L)Rhd-_e)2TXVY;=MM5|8brunzk zZpbhRw+fV>2d(s)^~HQz&cVLd;6dRC;1MG$%po`M&RpT0PVzW6_@Vgr>s@;S{yOnL zg+0qSA8}%jY|VQR!>m`fDo}DgvyQ(&VZtcHap4%Fz?gu6nUgv?#jAbAyHZ{9B`*}t z?@rFj>?3#Soy02*pgjgOUo;EL3bWGEQzz_S7pb`mK&Y3z5-)aLm0XNz2gx_Q-;;~& zRrQilWeyozv{1awpc3X8vH&sO6rK#s94=ZiaruOueWHPu3cQEYV_d)-z!z@RZPdVg zYm0;mEtT?10Nf))P^m(yh?$c90Ps1%1PU>>1dr%W<={xec zamBrZwi`G3){M|`H&mEE2qny$a;mA26+l3!)}mK7cd{7>|KVE8R%UQOiGzqmC{OSl@4M{c&r;r z*o9R+JPNz z+rXj-CO_PfjOOjGklz7XT$ILc<1$66Tgy!x_DDpJ&@rPw1`=W*rLm1ll0ttetBHB| z=g}Ewboe#A=~MaTft+ZDVt{=g!i&>?kbD*JdzD}@oJVOXlo8t?;+vq2S3*<57AL5P zQ=JeYGH^~TC@&qm1(YGTa4!`jT@)jO)+5;~E5u+4?ExoXn~QnHBgv&qp0Rih`Ap-7 z`NHK`ItG1;7rMuy_oB32YHxZQFk?*TIslX;4_v&Or|CkStySro&Na<$(M*ngJ16X9 ztar-K%=hJzR#&J~VHUWsZGSmLX^_mo0vJ5mC)w)&0pb`Wf&otzU8KVVgHTT1;F-Ve zT*}c`L>-R;!8{~&pEIWR0^)hAgdPC!$5x~T3E9A-UNO$?#lfm;nl4GIlX!*j$4>NJ zON}5TP;aIF>MMyx8)_>lBReHe`QExyckw=8`mJ;%=5M58!F8CwM8pTFm*zM2+{XA-^W7cr0%dXWM&`iJwBgBPdp08cnbX?y0D!N@JxILuS` zgHS#L!TiD`o#;T)yjTjPr~`^TV{xmdMZB$O z2|vIT)Vz_76M}oXV5|cPqDLTf6+CavJ(7hl^I1 zOP)hN+^hw@%2l|e0e}q#7-b7!WGM6~p zXhX{-B~YVkO)D8lf&tK3uUS`u5RDmJ3LZ_q(NdUv7OcCiG{}BXL3L5$xo7rc_QgK;fN|3=kJ|^a!I>IL}@%ZL-3}l^j0xO}pl8 z1i4wfgj5S_#H&#iqY9Ti#ed*w^^ROSNA3{jVOpjjIupitlNHY4F7~R}-)f> z)=k`O=b}L0pn3Kl_FRkMTq8ODOD%2y#r&M8a66PvEix-(L->)?pV5IHULrN<+)p4F zfj5@e0hfk8EsfRq8#X{nb)t{x?U-*Wg6dw-dt#|eAg{aetY(VA@2324A5tcn z3PYpN`_Ob5@Eb&(JJHJSQU~m$79~SnS7QL6_9 zLwFPQ)3H?=aK-@9V1#+@Y3g4k^nSc4cHWpML8aC*xxCXH_vDZ}?H2Sx)9{BR8K};E zjsjt%$F)FpzL17d;O7B_ZSon}{BJbEbL19SqJ^99XnHk6dKVjEtrA8DKnZb0s~vS! z*q(HlOteEFn{WshV3?lk(&W8#xa0{eV~fv97?m&^FoX|qH$W$<{jlZAT)hjHmXYLf zfZWM68vN14Z@dm^S zf`M@e3}}4bv()9JTyDO?z%+v|;v*Qq16bu`0CXsou)oE?Or>@9*G3KvS#Q{-9W>qX zKw5pOm5me1n(EIIoiM`~hM@-}H%q}rj;_mu`Qgst&U_~r)Un0fL`kh37FO*qL5e0m zL@z0qgS`=e5UJd7>#fnh6J{Q)UmqYp3&jfRU^^WHYKNPdbURo<7U>~gX}@9KfGm0- zn{eb0A43*kS~s~_$<30Sj9T$h@yfH}Wov%m9d!Tz?}55##SJCjH~^(9M79W5d)Pv8 zlrl41(q#Hyo>si7UCZPt^I8jynwPv>qOk{k0-9XU4X{QqkkM}$c|^&#vqjd@>o%HU z@p6f5WO#y8RYrk83$nTH?SNMAM&FU zI^@92I^lWoQj?71he}}<)u0fCBSamuf5-gf1XTCIUVa)-KRF;BecS9Uh_v|CtPFoY rP9_MWj?S%)v9;;+I_MNZ2U2E`P#^mc;=I|%mvNYCKcCkhz&H6n0*G&^ literal 0 HcmV?d00001 diff --git a/dat/archives/difffile-large.bz2 b/dat/archives/difffile-large.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..d3eddfa6917dc245278136491cdae6bb4dba40b4 GIT binary patch literal 7003 zcmY*dc~}#7w|0pw*m`SHoLFmH9TUqy7DYZSE~u2z$;g_35>}yzK*1sc3gVVV3yfMP zh87SP=#W4Zl|>K~5E?ash#J8PDk??=ceaY+a!>r8`^RN?Aj{18o&9~!aSM!gnY~m# zQzk#(kg7J&xb8r|s&whtATVg|&bVp7(Aek^>!l==2d_cVQ=acQ&n_}ymZ#CPm z_OwO+_p{7yX}tZYE7ms?tbaz0x*I*=lRaZ+ZXdg3bY_8Ohi3Z}=jc(?pw_WAjTbjGSIQ+8z2S2p$3i*0b!@QQNo9VY* zs$wUdej*ngEM77HN=kGMwS)X;^zGZ>h1eS1l+dRh__(8=IiKwRrcgB2e5(EEwK{)) zpIJkVj)i1|jFWFJGSzej&YbR4ZYt`%eY+z&->G}oiZq`q)d?)W%9gW!=i62|uV~S? z{OzpITpLtV8@mskx;0(_34O#;+pnkMJZUSh=5>PEhtbqrtTv%)@GnPbW*M{iIz zRqSv?8L%{H{PHX4RYWh(J>zV+z3%!=ULYMw@dD_GlCRJvJQEq`uarmF25`z%IqGxS z8Np0|+R>dFgVX+z>fQX6cDt=-H5>nkS|eR_E2Cj4cbJZQi09ykJK;|rYWjFx?qUCQ zA8kGH#hm5Wa{q8Lm1UjwR((GE(MkiWcxN!1r)d0jhwH?sSg|I0&XO^Lm+(+)zu*cr z*(%6@7YfsPp)@y#`pJyvv)7vO!*9?_85KA1LxqAK`~V$gQ>K&`AoFd?hUm4GlnZ-p zFM7#Pk&7hY1MGBtXri#yJ&2Ae6g0u@Iru@n{O(89TJKUH6k?9ZJ!o&F{GBCO8KMtG z1=!aY*lTwnscaCnz@{Qm@B(dhmzN>y@cfL50wkPkL9Z!5)LqIzc}2<YmiNJl=X#GaqD#p-`g*^Ma}wnxfTj6R#O_0aL{!V zy^)=gQHgfd(3|KusWU#vPGYbBhNw78Ej~v%TUBqv53tv=oAE5PcsZTwqfMcZI`UtEq3h zL9G|;pTd#3Xsc5Ge^(i@kp{ho4HZ}L!6X=f7gqE*{N>_LH`bkrJN#=|OT{+o!9TyZjNifH$Jcgg zmU<5U!A#tfJ=X1MVnn1nrg6JgEZy^q{pxv+CwBj*sC-w8 zT(~c*M5a7q=j*d5etYhv-NeP2ir6Lz-V@^7$X~Op=4Wh@ZO%PL`M0?Ro!m97&Dkw5 zx@Tr>&y_7odjI>jhC44_4ZM2Ppgnr;W%{8L4$RiMw#c{$sidF1!rh?2?8s&BHGSUi)PPT8C>R5&>t*Hat~-^n&WZNy&kXWJi5MeMOb z!zr|l%0v{a>@;Q>`H3oDn#*_QRI2auovc;&7e@d!X^*|K1QC@)6?-+lyKv8g@lUg7 zE%hI^Xg$<=ZC}w`G9B}hcss}xvO4Vb_T@k51ge9X-a0b5@UPhTVyOVVi{}`TesK#ri2Fa!N>k-QkA2B^R`>B2_Q=s* z)X2@l-X&5l^bPbn zq8!&#ywFU9sN)FT!*ZxO%{W8lQ&spYOE42;CC;u2Yc$oqx_Mmqu zCydcz*iexRe_oNR9Lw}zv@C4_mg!~d6&*+?(&;K8bl7A%2}GQx zzCSqwYn$MI}Di`BkL-lRcOfUrQRfgD<<@)Whgn*I)5Yh}{c%g07HSk|P zxILXx!$HpQT%t8H4et9RwF+4|83P_9lbJKT&>F6s3w7`d+KqRD|56#S)(>1@{&CF8 zm)UpKBStUGt5Re1PL$=zRA6o$c0)Z>5R04fY{HD+vBK1do6t~oGpb7}{)&qs$nqS4u28mr4T}Om7y=eH>u!XCsDbO38Yh)&=`bu+@cMX8Nj$r;H6cyAnYZbu&-1f z07558lmV;&{Eyi=$Ie~$CSo4DCRlpzYEHmJpTLj(Wv@1YpiiVXvkh0A*l@b5BxlGAi-6tgz8Y z&7*}IF06G;dvy67M}WRS2Qp5Tx)>U=@EUGDHK*TDMQ_c&5`b-ts9(%R6e9Of zH!(--3wOAOjsd8QfKON<`j938d*h=CCttjXe$n&f&Yk10w#^g0fBw)f7|JVT%?yQD zg5>?vi1r;Fu>@N}KYWEfW4`+a%h0UW7A-NlodhpKFvF3IYV;f>KjvygtQVwelQl7d zm>~8#yo|VhDo(u{Z4|VQRD5?>zGf~_6|>OjR^P#m;hsaUSH9Cz{Wd4F1MnS)Q`BTS zG5CoK19@_U>ITpS)*vzqhw9(l(cw+d63b0X&(2Zd+zZh6A_MR;ZYzH6Pp=6{twHnWXyUI)A^qPc zipsy1$~x6=I0qXYC0=dXMCvphfj>Yyq5st5853E4He;p+mHxi}{Ncqx7d+cNxM>?V zMWw9q_qh;LoThDX9o5I|%eY<+q0&P0f*bK#d&9F6Jk1=y}|~>FrkU@BeIhXQw^y>*%z3$?^~U zMQz$j>Ny?G?W5yME8=x@CG{Ho3@HHJrwx3KJE;zsb2!!f`O_Dyx%sVnP+PPJ>-8qn zWafkQsnBN1I&S_GKWEO@qORN3H|I=_e*SBm$uw>QXH`EPx%S>NM!phVd};o*?EhJ^ z>e+}*L(AL!X3j=m!zUhPKk>77MMR&RjTOaU*}fM%`osT1igy3(tGk}_rDOHnveMX4 zd!0D=bi&h1YyYh9G<8&s`1QO+p-Dsz$j;PyXHtO=hI30Fj>J9co^)Q?eIX_G;`g<9 zO--HZ%X0@8?r-?J<e5bA*G0*^3qQ@-yW(uWx5GwJ@Hc8LhCC~Oc>jma zl!)rc7Tx-knxUIf2{#W#-i+<;UvPPdj=y`z?s(KT`yBBDlE4kRp!oI$n=YM6u8Nv7`*M`&&eUiB(JU$#wI^{!zaf?PR|G~= ze>%uE&X-kq6j!V(`FmyjwJDd%T7sgY*1G=Z=fmoF^zp%%8;=eqr#x=oZEB8k8B-fO zIXC*C%(NiX$n|^T_2nPNQ?9pm^=^2>IZVoyH9G2fNB1*j zf55z-l3R?PyQgu=%^i#i|vUEWDIWBi9d~1s^VVMBbU3jgGb1>7h*UDA& z8vb0UT{Wk{j#F+MIJI@_-uS7nE26&te1b3UUWylMzx!PYFHct}nHeSFss8`(Fj4Qq zeV|+3fxhL4ccQOG?;~H3Ta_Bspka3 z>EUk%s;RZpmSArI{N{6VIJG4}QDQs*SDxaKN{=PK`0XtSn~x7Oa`Xkg6?!rR%bntd zc~DnTv+6q+WGzP|6&oQvhWLxWNaoLXTb04z=FB-8vnmddJQg2ff>h#OIyoz)Xra-A zTx~Pb>si9@AE#zgCIDxi4%^UQ|;O?nTtBK0lVHnS_@BReA2anF*Ri zyxVs5ZQtt;72Z!SojU6JFz@EPn|rp;(Inh6@>FAsd1L?dG8FFT+W&Z}E${ft@;=U+ ziuL3BdAIi4LsM3t^g#LErWZq30L+8375_jEw|3iTkD$&0bN35jR(OZE?)-pkW(3_i?NGb+V35iPdDsi6w(`0KP zU4iHxnwFjQDTdVmBQ3#{dt*Gnr5@xjwgLW#MH?&Ywhe1!9k=zKBC|M91z3Oax6`s) zd5BSct;wk~XMmmo;8yTou&H-)$)bX@UHTw5FpcBAua(Bf88P~&%V%7k$ zU3``wr+&o$L3w--7$5+XNF{O)Q3f(oOFXMO;x7RQb^$l8PW50|XoBmk1U`LjM`OuwV)m+Eh$mw)9J$e9}sg5rMxe z7uq7kN0uhEfpoDz2dsyb>ES0`MTUq$L!H#h;`IfCgwW>BkG)53e&CyK>upaC^R&6x%c2Dq7?JMqoyct}ncV~x%(@_2;$a)gXfya5 zixxY`ddWy@SnP4lkhrLk>5_hSaM}Ba)L_iVWp6(>2w@atShQ%mqhuw~u)~^v$kHzxfuNqHj=>1@$ZwA&K;i{od)a!k zw3pGpVoSb_L3)u)?m6&a7L#5sPN1&i8Pu%X(E2+ShuUB^`wp<>`%&3hpD^0(gpvrGrIjG?{IZ#QUx1JwMM)P5E^0a1;hhimvVXt?jx=-SzD6Zx^slP~4 zKS0~Z%{!vap*KrK{=_4wj9zXUu46Vw!qCWsjloq+y1P6F-#KH}iq$7Ps4-`FArSE- zYYadiB_;hDmKZ@0Iww$Q3lp{r|Cb3ZfdQ@rwGd^KRwYp*3{=m0?ij%ZUa(43>9!bz z3V1Q`=z!*5JM33BGaJaXtitDzxzEXs zd>2w&2NT<7J#}-bcNTt~+11OfFPTyZGs@aFaO7)C*jH#DQ45E@W^&XWKyu1uR*I3! z?WCje5mtZ+Fkl@Rzomw2T`a_^rt)0fHQ-(gxhZp;5!>Ndf(@{aE42jqfwR2JXMPVq zk=#<^osB(E<*UM)t%q>L1?Y#bxI;{69`urnd{>rsV)iXKO%FX(!rdwPq5yjANWZuN zy^21ix9TCy$eqCsdpMu9!Cj1|5gGtgh3fERa@d?FSr5KZ!cGSsMto!(A>gq9Toyy7 zMQUed-y}Z`VU-%aY(2;%E5@txIS0#SmqAC35rE!WYj?J{OBc7|_aM#MA+0+JSnvpp zkP95~9SHNYkD<118=x0u!iTopD*Po;OPn>s=B16R~R@J2gI zyxrB!Wa5$RVVHS0Nxb*K6h16H030#joG;A-j5T6e;$65($Pp)j_Rz^h0H$@&)d8g* zXFUW9jh>KL3pu%NO#%~?tsNwyQvQ)J&Ef+l=Gw#5>$g`bQiA0lCs~u8D#sf-d7;jB zT~HG@h#H_P!F&(mV2Nk12V`g(PwR^SArW;TzBbl$C#)N{7z8H#$WLq$UU|tk43%&~ z!IUyuo_05!as!qbogdp*7Oa_Ib@JKAj`sk1Mx+XVixMD z4r?hQK)4}Ut8_){(H?qpWH10_4N=QFo(!Gx9xQ8|)&Ih?I~*gjSE>%&Wp`U?8z|I> znRFtF_cXEt8#d=Nnn7!ZGTK9Af^Ar^`nh7&7VLuBG+>0jcWhj8^QV07eLCKLRVviR zYI>7>@wx1Ja-%e_XpWPu6aK!P7&4R-uBpI$9Ox%RJqDzXp`OrN<+2OvSH=9zJiiqF zT-z`s|(ZcNKx{N6Y>om#KMi$1cu1 eMV!Qy0fnXysR(~w)8e-wM!S1%KO*m^PyJu!(_?}F literal 0 HcmV?d00001 diff --git a/dat/archives/difffile-small.bz2 b/dat/archives/difffile-small.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..2f6d5657687a0f4b23d5b1ba48e48f7b188e9dcd GIT binary patch literal 7028 zcmYLu30xEB);?;qiPx%$kf?24hQt!gB1o$sE>K1%Qx-`837dcsfr28NY;H7GVAMKu z2g?r44S{f75D?i>inqW;)QAhpSmqmgjlS!Pzg|-o{C} zM4{|#uPUCb$@+Bc?YM5y=1-qK?R|W=A70*@Et+k%&diJ%Y=39l<^4xX%-}Zj%M3l@ z1G>ad)G~gVp-#qmzCAOzcSBSDoUqHD)912ctv@7MTQebXM0<1 zl))#L3TKyn-d5TC3b~9KX~!%&%n$w2?n=oQ57(JyhugHg$te}G-*t0bm;B)&^^H~jVLb*22p z^Ov~hEm^03U#6a);#PiT_56G{yWH~dE!WJhcG~rM^#1&ecv`XSWX^i3DE6(Pi0UuD zrEkjpPZlqMaf*2GYII=xo)Z&6Ck_StXO3s~mW2y~=l)@n6g7~!!ag_go&EBSS6068 zo+8#fL)3FSk7tnkt`1xad=#{(*joRMo{LqXP3qw?$>sBm%ReGcNT->7ZKfvpt68Vj zJ%RZ-bLJefe)s^<-!b}x1>6cec)TL@;ELt@Y!($rWV<9Wj%>Tv&g$HXtZ5ngWX<64 zGl@F0BAvf7lbp6;@>Fl8oz=2qGp59LC6vzW<83_7aI^N|`&F#BA{f4HLp{=RCN(C8mUMxvC6gqgJ}g2m?2r7hHgB;5wWfU!yVXjy@)nwd7Gl-T zBGUzXowyliMvzf<5<4oHy^Wz9V^)7uD^GJ%vFbX)fgNU4ro+H+^hmmB4@dNty$un4 z;)re$_T)CkW+&cd)QHx15V2xA)2z&DCS0}JMX7-uJ!7_xAR~wot$TzPYl)*o9dQm! zm((VD&EA&DP0gsTBvv3jqaq`kZ(66rv>bbH3E^&>S~f zQJpTjNi0K;9IzCzx6~0Xfy~<0CSn=!J+tLLmmQJPQHNZuBpjL5HN^MGrRPXDaxtU& zJyxB|-9>JD!4Au)c2T~`s1AiAz#t~P`CrRzNB&IaZii!-?!}(mSkt2SU}{IKiP@OZ z=;FuT5zx`ZtQF2j#$5s#0UP9^=cXktnvC+wv`)I{30mZ$d~UjO1nF^sGc6-lhl*0$ zeP19wD&;-o&z)fO1lZLjHg^pLM*%yYLyxGH{b+Fr@3Cp`3nq&a!4Pot5g6C=g8Myt zOQ`6t|G%*uFxIwYZWLOqCLBAe-(uC>#M%sE?KxttJ$J9C=@E}y>Ou36OWkOpI!Nu8 z2J4zmWW!BiZ#&_2IC;VgT@)jlV%�buXM75TW_Ilnoo?Dq)GyC+V6Oxe0J zoVU0uu>a?PnT+Z+d`#nn*S~9=g!0sviXH`$XxUGlKn2ha@xvS zy_o5A)DbBSzwdL*=I|X(<%KEM=d!ccV|1|%ZBhsRSn^hXz6 zr$@4|Q+S6Sq(@8Fu46u)t>XvDrRT^b+~Tg+q0cjT9m1-R^W3dyFTt#~MW2u<<=++x z(`R&KzvtvmCuFX>_3l%L^uke@DkcT=vdCzuxi3NN^@$t7Yy&ca|$$m+7AA!JzNa28F8Z5k0Gg9(EoC%lE-GLhh(EhfMBhrXa;q6V}z?Ll^;k+V5zgP7mmpEB#k0ofa`7}ueC5kAGed2EqCZRgItq4%EhKh z<&rAt3y8QEaKL9+JwJ#N8~xz(D4BpY8N>#ukSF6_klRA6@`GZ<#z1~hCl_n3l9-n< z%FN5|;amOi;C5YmPz1M4qW0~sSU)PEq%1Bh`Vi?yDQSvu5Zus9-xl^m)b{-&4{ajq z!IAvU0Yn5?Y7|Doj7_k0X*_Wp>;>E3i43C-f>nkhM%hXFDFi?;eoK%{6;D^_h4=6% z`lDT$T^YYD6YSqczcJ(?Lr9l40(njXzoiX|J8B2Q?$}CM;9{)N=vT49j*yG7=21x> zgsj$=OwlSK9y4c61}{Te7RD-?h5I+uqW6&(B-qd(rle}31yU#G=!te;q)lWYQ~NS} z(PK6_$Io3-{T^5)9VSx@6232bzjSq^!taK~lxy!Gy~9-pe&d*o6rc^@h_PC%k+Hc7 z&GHWOP;%K}a_OR#kPq+q0S4)@^c*skBf`#Nt+lB37b=%=vL528N)aLm9CD9vv-(P4 zBW%MXJ!8ozn5UuRjMtHOJQZ;s`N%AC@k81qZ6fw=hG}!iSVrq3$jlCO7`fs2_()Rs z<4XbWCNjC~U1T!z%nAFBRuK^kiF@e*IQD%uHiFzELU@^6MxZfhvX~K&(c}`u2vP^Z zw6B>>%=(Oac1i}YjM^7@-t$$+-8)zAUb)fQ8u;wv_P~kT-R1Qi^;kpK21Zbu_`6e4 zL|fSq8Aqn2^_FRlroPf4x#>md6pn?O;F}EfR}+Q_|T1j}3P%igjiB$H=lB;z7dRY5MB z=W#Pyl2WioB03?2C+7%kJkY4bsGY{lRE^?##%M#J&2#(?$>Sw$cw+G zyA%W37P({u*xKleJ^`E^1tpWqWk;cJG8$rs&Y#Tv@3!^v7aJnchscLf$q=`lc!ssc zqQe03L7lu>$j;LcCeZ)~cVUrb!SkY0ir!wmbL-aFCyNu2daFMZ4jgSr?LFXEeqHm; z?c2A9U-i$AmswFV{*Wi1l23MtCC`3{KJsDsWB%4z0BV!jwt^WNBnnw|KsyR#%2qVq}wI&!+`vH*7m7u8R$eZtl2hyQ3-T z+XD{qNmx_lv8z>oE&h=eofWer79i<+josxIWULU~HjIZ30dn~%9I8sp+c;MpB zc=Co2iYGN&Aq3gr_B&oW%n> zbMr1b1e~q+-9%k1pYtOk4H11;nw#w+4LhQv3l%K|31=N%w%>5vwo7bt ztf9;=u3psEJyUs{yiu|gujZK*l>RFwXGoIzXd?BI&+#Wuj$I#kI`6a*kN?g2!Pk>x zpOiYti@q5lwi}=QlzMDc!>VecZ0U^}qJEYBW@BYync2yFn^pgeNRvx44f(oK&08w} zN5Y6F%k%yjoc&a|c+^@u4&gh-P=1#e&GOT`>0PViZt!`->f@7h=yrCfLNJAs<88?i z0jzgASD{CJOzNE;hm1ILz%#LQZHVyGq@{F83^Spfc&FN|11gFqy3lsTJrD)2N*%p) z={{*PH^EAQ9dM!%zRXg*0Pt!e##I22{LMQ7LA%g#7VinUH-LEEQAZ{V9EI*ekJG}5 zPB%kwPu8zq^r*Zr(;XDh3aW@RgWRL!EqDhM)C^#q%=Ub!1^S4hKM38Ombws+ye(m` zPmw45%@2@qHIc~+C->CzthKuUZCd^&nioNspbhA4WDE!*4ia!o8>r_M3aWHZTJc@>C zpYr{+0n`kv4$k?}kYBnwH@VFxDSeZW_Yi8VY;Kr|ogTvR(?uYy+C)Fimy0bhgMOZq z8;kd7c1pxFB&SmG8n~pm8moi-?Erm21DAE0G!`cxjM&BeB4GLQX=cBK1)obDcbqsy z{Pa`Yj_6Q@jDP00T|dc$*Uy}Y;OpcvaRi_Gkt5@0%NuK`&RiKEkmEPa`F-10O`CLf zUhdD6YR{*S8>EMkv8kc@g(Bi_GLnAJFFP!Jg@4h*snq0T9mO$74W5j2ZH+ z7FsJPg_^VXJGp&FeMbvN`WTKfz(1Eg02(mPw8P@Tti$P>?&C46KG=tz3Qqp-`z8}_l*BT_Cn_R)yb-K}Cf`)$6rFp~2DG61yYhEF( ze8MErl0mWwfjAnxIVN3V1-l1aj)!BYhziss>F!#SlvwKrpn91=EiEiXRZuQxuXRw! z+|OlaeIXQ{7wWm7kiMZrpLJK3cI(s?V6v9m^0mtZJ3+^-p6Z!Uy5_qnm4dj;sZ|QL zXFuI1)R-uQXMv3~Th4P)+ly_R?4c3>vC}DEC6_)%K5C?G=sk2?wK)y_WRL(+xdhZc z{O@lw1HxMLJbNA}aEV+JD~SLx2*x%EP*czWyPD$9o_pD)AI)@w?90OwOP2{^WTxWY zn$(*l_&N~krlsx+99eGWM}V3Guv#*Py&e5!JE{@ETFYnjqXycfaaEAP_}+bZpRfl{ zV4UpxEPUf7l*A=a?I!@(tnH8P155WnIzKq$*|l+{(*|2~Jd-;r51=G6u3;MTuVkTC zM-_1LwY6jSRUMk6fNnxfUIJ-*G%{haYRwjH>=nq*6FHt9;3n)-{goVYi{AC`# zf`m@jbf3S1KEA{{Fv3M8>~n%R=XSzMnCaZ44I0Y`?3xB&zlMxd(dV*3 z(c6F;yiC6o*l|un`7_yvajJ-A163GD+7A-s9VM#Ra0O{Y)kNKArEkw002B-2NYl}A zTamYA3)(DSlg!f+7m#7dMQPgqD+vUyRDS6)3gBI^ruP^$62hDhr7yv%CQ-02na3+U zQmb1W0#@bw&8EAw@qiBf@TcZ9$QAp@zsVFpR6UP#02H68NoA1xXH-IQU<012tk}?p zd^if_C7@5c&T7G^qTiahjqg&QO2qeQ6nF4sRhdxukjfRTy(r9@*69j?2_>kGajJ>_ zn+1jJJFF#_YoaVJ2Q+vMgz=bGTMO^S8x?u_1#(G6^5DNzL?2jz@5}eEASsDlYR`j! zFyYM*q=5@)skn`+422+_l2pfrxLQBt3U?a=wkD{(lcAD%H?yX!1IofNd6C5w zRQMmd`(^2OP@d(Q8fRedOb=^C2d9Q^FS~-(Kws>r%WJ+b;Ccd?jMZPWOy;t94g!;2 zdxWQGy`mW>M?tl5q>*3=Yw{J=GFiHli-`V+C)7k}c@w2LE=V@&WbTWXntv(tScZ?5 zFL1z9&#(DhC-Pe z4stghLcJa^j#v9b4t`rmd8@p6EaAQ*377$`&_XXy3|^uj2%w&m79!8&g_v6+{h1!r(APzCZFPMtx)DWLKNE7d1uA~H$qk5zt#Gq$&i zAia*rLA+>{0-JU1Ix1i0*0w1JvfzCyy7z+a%=@|jT^=1)?ce1;Y;#QW8)RAo)`@Ln8Gd@A-c0-EE>UEQTuJ>kNt>@W%=~it{ypbE2tpn$*##Uu-H< zhw+s3O@4|J{JpVajGi@>aZ={7Q#ge0>U5WR=s@PblzF(&pXjp3R1se{6#vjYJi`!0I{`Y6duP4vfk*(fdZf&;-Mcf_AY;rej)P+Vg*J(-gGoz&9M+K zcAD>5fd<7bJQ7dRue%338*;^Wvi$HQhQ-lR zyR@-nJP>^)83NkQB-6wnW6}FgZpHwpA_)qT2oN&+Z|Ep=Lc1pufFcsDM~2C*vya4@ zW|BjdPDVmdbB^nU`-1VOrQG{L{n{upo=gFFSuhC7DH1@+e5ST65=g1t)a;5xAAtI; zA!7CO;l19uUS`V*{H*f+f^%p@WEusH7dddVk>E(GfT3f>P{P;4M$bY|DJE+M)csX- zFMVMOz|>aA`0H@mGoI%G=Q)KL{+YZBu-ze3t84dn0*7D`1XbKkKNPHhF`!&tVfEgYV{&Pv zexZJs28N8PjHKD>^|~_3|A~)l%47EkrmXXnB+YI z&cEXIYb?mOMmfm;U(hjQke*jpv7v`v+9j;SUzV;#6i_g%`9S|gCQeP&27>zK-66M5 zT_Xg&ag$7|lA04ESj$RNR?3TL=5SUQf z*C02&m#~A0v38&Vp2RK67#mSl{dL|oknwDlV)-+0ZPJEM(2**z!c>DwkA43G%<5)) literal 0 HcmV?d00001 diff --git a/dat/archives/difffile.bz2 b/dat/archives/difffile.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..5cec74ebfe032b0e82b37d1dc1a83f21e34bfa8b GIT binary patch literal 7030 zcmYjW30M>7)<#8}cx!7?n5fmZj)^rG5(L~pDpE!!DTpLN2&-UZQQQz05LCF>5=OmF zI<#RCl@7$Ds1P8^=0YPS6c8g?z?}vacM%oENJA7I0~FiQBGUUX7G}6Y}B1hh2AX_QJ~>yKg4idE41BRxZ4m(VF%ToxR%* zzPv7-!j>N$Uph8Oa>RSQqug$m-2uC)dygKr<4W^*L2N4cz$AU(w&aNnc91u7bm>H< zL|)>A(t2tvPcBi(b*Q%!C82_x=xm<+nfrt(ctS$r0lRm&-577%`gT(ay^Hl_2hQ4Q z{KxIK>$IC`XE)0I>;zd4Z~6f{rJdcFiSF*5aP7F=QzqTcxfC#Nw>#YBK6zZhxZM+` z*qPi%uTgvZo|g@#`I`eRQ)IoeONld!bJ8^5zX-7Focz`D30_OP+{a6O7&HBS3cr^e z`px%6;3&Fl%w!52hkJf+MzWPqzohV&N(kH~fIe}Zh zpFGDs;D^hRGU*RZ%t*G3t)cGZ3A65cFK8MyC?2H|#OCXx{U6_%Iu+~O9$zVV{`tyA zMPb&gnqMmIJLA@h0@fuZw2wz#1o?hpCmxlb89V7``=6=2F{^2Sn44wfAG2_9%FByv=-yI>%Gkmt#wp|1c{r zThn&HfOZoMBP#~U4qXyH-tQVKfru5fT`y3sKe=|D+8H-sY5`s;-%G}zCStU{Nf65n zWgFBQ>TI5B8PlH((o0rLWe%V6W-x#0oZH;|{QST6#ZOr~*|_FSm7AMeaM-|mdquY5 z8m7Sx(uyO93*ka6))2m7!z~TjQTE|q`6|vKJ6#1IYLO(Y*dln2c4RARk(IcP=p|oRx)WCP%&F?a3Sg5Rw}_#f21YGw z{X#PSK59iDqfc2e_zf4r%U98d6%PvTV})dVDw2%0=Ts#Ntk^-Y=S&K*%w|@Wi0!

iRAYs#IIH3oI08=o>&8upXA5kj>ErP>8w>?g zvf$k_^eOE9Au9oE+zhAPbOP~+mBQLIjaJ;i4wb{2MLAX7uvEOgq8BUnRXk(GZ$h@S z;!)VM1}m;azMGCL!mIL;?TpI*^M1CX5B>AD&G39=hbizt}KV)0}om5hHv#=j)v@1hqvu|tOm4;GxZ zv*HKIc&R7`IW!se632=^OL%1~9t6*b+7&Dj0}n-UTxL!5 z4(SS~M!KeXtyyAcUhX1nJ~ncBZ^G_h;(gwvisrem^n2m`Wv6DsC!EZ~f0r=6oY}Q> z7nQQ)qK<#WL0zWuo<(~1SN6pjrq6ifZ?){+?>9Y#J+!4O^m2J|(9DeA80MdNBR-6x zdu!T!5xT_pj|Kj^-(w!W@+!U%U)A$xPjN?7v|r@F;M)hy>?(&(E4XLNCF1YwqX)q8 zBaC`%hJ@ZwAMh$n;&`~6k@sB?;zaJ%O}{MPhgYIc$QVv45{CtMNR*VRY{_hPKF@2Y zj5j7(h8{h$nopOh3oQlA2x*}>VAd4zW-=Dj(`&GHvbA%+I}y;dG`zl4ACk>_TNq?ODo7Ju6+nTf{ze*nV?viJ5PeWc2X6bN3(4Q~66` zWusT%3f4-(wd4`nBxobIlzQANeJs^{(ddlk-|d5go}y2A%Wp zL0Cg7Ad~UB^KHN}?X<$-P16c>fh1!{n=47=>k!sPv`tB*avtLieV+|!(_~_Q$<9HU zIFQXTVrrpUK&Dxv`^e2?GAwly?ZpQ1lVqxRaXbGeZ=PfeZz0c}I_uYj^`KouB7&bH z)47p@!enQ&?OaK8U~17qq(sz-<^O|PunxFx#2}P9TNQ9UH_{-oCsGkQ96wX)_?1a3 zm8HpYWd$;J5&M`mdNg(y9fDkKAzawU`GGz%@iIzVZ-1QrHHqMctX3g*km0Yh8w=`piJ5|U{{(5z6|YxDUk8`>K}EO*L2OjRQviR1Uy5+it{LCAKtM$pl@Se_1<0h?&BIA=#PD)Z(0tdX!u0l5Zi z#j1a1AGFA7__WrcY)C8pfdYTH0}zs7OZe$p!~&i&+k&J(pMsq`Y(9hY8<>fxL>~bv zz*;3?5S#g#v$sozO26Z39kelU+XV>400eFmI+&XQNmZoQuxof8Y7Leh?Ls6w8+%Uf zC7Q5SzG@j=mK8GDmUss(LNfrC4kgoQ+cQ+0Y{H0DL%>YL-)JknLkUlt%%O=o%z!;1 zx3x4%g>1)DgncNMrE?+dpaM3#Icg>k%nDHw56Co&kQ<6wu|DkBS}HjDGC<>ohFl#1 z&`kj#Z^UcR9`ru?2CtNqn;$?TwqjO4wljXl0O|fZfv@6}U@GwM-vC)1a7Z`YwvO8^ z4%x?V=a-IAmht98gp$c5+z2rW)BB|p<-|GkZPy@r5n*jX&v81iEJ#IB1@*p(t{v>Cldv=DB?5T?_m(nX9@z%6}PCMT7%n^?j@ zMJ!Gxrvk37^Mr) zA@ow%%a#W8om7|@=r@`Ffc|;{Kc{S^HaRorXe;m#w~XgnauKnHvewT1=?U0j{0K{c ztpdFc`Xt#ocWKSkYY>u=nDX=G_3-ODs!6? zw~QMt0eDR2v|u(hbjs!+BP%^tfZoBf!&w<>VNu=2wPndY7Z19vFR)QkF$TLNGuWa= z^kwi2sc0bwas*6x2KfOwI%7iSZkO&!WBwIz7aZ#vfB*KeLE=3Z3he~bV1 zgO^n;E|LEA!<@Z2aYpP|KFKZWnEGbH+FyD%^xu~69|DNpbqr|*$i$!{OfV(FMjy^} zIDQhZk?&(A^7H93AiqvY7rV~G!y|3P({s_z#a|CuiuEeR&sRn-mddUMWi*Lsf^nuB zGaB2C`lS}F6?{JeQmzMJ&o#o@eOMlT1MAk7G-+btC|2G3f8RYrTW=(bn4DePGH#Y{ zy}Q$G=YquMwGl_}|K&D0c&hr~$>!>@i}$NrE}RR%4T4ec2JTxbT_5W2jolfT%6a%s z^_aO}?8=b6M-GQ9sNtMoT%6-x5LPkU{JZPJ<+58v>+=6_Qw$U}yqkA5{bq>si(?Dg zl>LjWk;~V^%>8YCusAA4Ld|lo8-%i`PZy}?kt`XAJM*j z_~FHZwi`D?LTk5wyL#c(X^z`l3|~+i)^}YzCb$|<^kPb=rqVSoye`xDI2zg<0dOVwv}hBmk2f@!Mj%jQ>2YuvIwQgt=%#22-my31Go z2?#3N=Xk-{xFzY=ZOd1*=Uyo|K5FjT-GL4#H?_ZMe{-d(^mzEI{_~fvob>#1)pkiuw>Q z8KJ=7b zD;aky?~*$BZL;Vxl!H2K08lf8$I6CEJre`$%ZDumlJ!u{X>A)68hdRgW%(f$$m=ng zh>j#eU66`;@iR)|4IO@1f%hL_A1|Zg(z>-W3m8TY2B^w?~ z*6}>)GW+9J`F6JGJUn&S8tFuqU{8Z*KoxjIZdGw!;ir3Gxo$43+ArV#n#2D*Or~d@ z=Nn`x)H9x^rBGcYE#xg4Sf=9NhXOml)Pwpi>u9YwFq3cQpO<5I7A`p-3R7JGxLPF6PfiVEdbXJ<5wu zkldo)Phn*%g5qMaE7;p)XS@Q-4h1INw@QMQ=%xhEn8iPWzLy4PaDPNK6|#Pt0y6VY zi#Gr%sYQI75Kv49eU?O7WV3iX7w}w~=Vb0)5D~R_M*d%Sl80(_vlX;j^7wZ?SG%yi zUvS5PR_kfCcy_&*tN!2bh}X~WUieiQQTw74#NTdS1~V{^e@}hz#nL6S&+%UZQ@k_> zddRNM`r62@DADBZRgK*fltlGHkI&0G-do zrA)MG#{q0e!2iJGb)xZMw|-b^99CXUy2=ZZB2wBmNOV9Y2n#f0#AV>2K;J_wq412cLx|D_zNX8Y~g zMbJO+TzE=$9aq$kzO#=$K%6B8(2+jTbMzL$sK)+UA5pupzj^I5ytd^Ol#pbQbDKf0 zZie#5jiBMcjc}TZz~{!SnHHNQYXT*kPB@Vb1UHoD$_$fiD|OG^2c^PPW`E2gtK=Wf zYjm+vqFs4}?!>C3>LEsb$5*HizcN5bS(O z+-7wlm{WWp?KT=p zOSua9e)OB+JRH<^9bip#J*OJWx3yjHV|(eS!F$kW*~eA<1CkrmL&(EBV?Cw97If=J zEhH@%^<`Fwdzl#8KCV2KeXv#f`!R1**>uPa@VG%Y1@_G@ZT1k-zT2~tVIq)1*Gq3 zJ_79eu{!`=;9UbVAm|5CXGYcZrAxlxDjZjUuVb;-$}mvzwu-?Gn@F|NDX{iGWUMTO zU6;r|#oJoCNaqjrpwV%v^x!}MxR5>xJtteR3hrKQf1;8<9LzZBh#4S14yQ8%m&l{u z$eP)Wum9D7J#RTJCrYqEkm9?-WDXP5`M_Kz@BuS&AaJ7OsRVeVjcNr4!1JM*6C;Cx z9=?TgAhHC#&_&#jKGHuoPq1|&V97c3I+&1bvrNoM1G>2boV`(9oXT(aX-pROAas-% z8G!y3baT9Y7}{pTcLQW|D#DF+0C0gWZb=shqM0SsZAo03xG=Ng`S?6K}m_wRqX|+2Uo)K!4(K>G&S`e z%wpxt$wnieOYtg3hu&Av?ngyo1}w2zvKHXKtiDaZbKh@7IOB zW>hVJ#4_lns%(j5B$M@iVgzphF${r_Y?LSu$IAAMol1v73ss4>=%FV^%p6C27~Z{e z8!BMFQ25xYTpwlK6O!ySFDrzrJ**eG%0`D2Ku?f@pMD5TGi*=X#5h?pTD)R_|J?qV zgO(!P25p&rjktw3u!XrY_M!1INH}-45eA^1AXKC8kqOukYn3aAB3o^k9g-=r*(bS%8XDKQ`+W|7tp0gw*gHKbEDUxA1Li5 zo~N|XaxhtTQ?hBimjMO@U~)B?rpGg?!M~4NV6VQwdyj05pZC6-ag4`2{>r zrS=zQBr`x=WYMteEr&doW`zt$wv@W>c?g;IkgI@su`$V9sjCioE7@j(mDLIfVsPB4PNJnzk|$+wg)2` zY>EqJOfc~P)ntUsP>c2hrL#rp#OM`6W#VPx08nrNgD{ubD7gbnU=C2{v(llxhSCFB zJFChC^qZ@V4^~TUFA(z{`F<(PSHuWgfIdOnOyI6v8ge_Jo3oH3#mtazx6yM_+lT<5 zCaM4#Qv-@*D{jc~gHmII542e|z+kG$Fz0sRrAUd5C)P>l*=Rf%H-DZAN~s2%o%@M{ zRtl@D5GV*;5Nwc$NWXM0oJ;p4tD!!F{&c4X0DBibdstI3(M!yt4)1mun z0P+321gdQ=y+aLsb~l;mFk%io3#dy4L1S@RqzcFi(ea1C0T%ctkcU)w1j?=)DB=lj z$c{>ZSzi$ad|pkB=mLFc+lVLHA8POou*O6U(;yEYVL>US@GlJ8gl)%tvK2c8r8gR? zpHRiAgGpc=?f$Wm1x!Gp?t~(GWAwc2on6!;$@b}6TMSqqHM`Mw#%0HlXJm$tGb;&w zZ%0^RR$HO>hat%msK+J3h=QIL>!sCk3+L)>Lz9-W`1>FM(`S4*e~nz`!2PQ2Qp(x? E0pet!{Qv*} literal 0 HcmV?d00001 diff --git a/dat/archives/samefile-html.bz2 b/dat/archives/samefile-html.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..d50e0fd968f0ff6e1a0e5b27744c6569ff292963 GIT binary patch literal 7045 zcmXX~30xD`_C`b{JZnvaiEGtiVvPi%NL6r!GCG;EXaYhAi_nOI)CF+?sUi<8I9Q!= z=o4iVLqe$f*pXGGs0pHCZ~@$?#sw4?#Nvkj&-ngae#!ijn|sea_nhzh&hZFZ>pII_ zIZdIQeR}LR%lz~&e++!oP6_++<;$)o_dDV3gT<857E3HFtXH{xx2ARf^y!O|EG#TW zBu}&>3unk}ZI;WEj``UxUp{2XbccI?9UPK3KEFWhVIltMVDyYXB2i`t%H&yC3kr)^ znZOENVo^xqSdoX=0{6(UDI&3{n(M~=1Q$BhrEO`_mQoa=8>RZ^7YxpVo08a z#n2`5#t%>7} zuRUFOLd zqG;okbE)6|`v)I%*roO((r<>eAdUgsEVU8QSlx|tQ+6-Kg4@nh(}I=LqI=)JJ@(4q z{v2vVh#JD@5AURoIWg^<507iwaMziBg=A5G8);bU4~XSr#=bB<>EDE9DBo zVOurDQi45e=~YDOj1vrLaR?{3-&QUD3_=t}aQU8x>g#4}E{BA3u!eVDN)>$_2f^kL0iE z1KYyX)OEBEZGX#OW2JnTTK3tjEJ1dpmfgg&t;=F1;2M~H(H&Vl6-i7{8mPrGWIYZh zBugvte+>0%RaR;h+QwPZO3kDe5M{0S5wr!pI-2_68R{9FS~by7_Q6nXT}RZV1j^^8 zqgUOLczR7838*!an(uZEPgn5gyf4R}a}-MFy{na|k+Ho$miD5H_>G&m$h`4~6j5AZIul}g|q zONeX2UVa>Z)1=h0YGhY9tm(>MQ%=o6uUMCrAPK2u_c$k;@vKx>BOFQa3>-);dCYmt zfFBS@8YR!UYlx8S>_%d^PapArK89@PuX&DsG6!uzFCL^O5nzv1;Ct@vG&RAxgmXd5 z|BuVuwlR3_L298|`Hp~V$~{aiE~gf|B0G~MgH~`0@VJ&*oDL4&L6m>wY&neQ3MBu~ zYYP1KCwvi>^oGCq^~>bfRlgj1`S!>0(JNj5bg~$YIP|hlr+N#0{jC2rGGjc z6~kSo@FL@u6UTS|G>Y(QOAacVx!$eZLKL&$G5VXz^$k z8d*9s0?C|&r0ln2>v~SKa{=i-v8Y| z{j-G0b`DGTmFsA}<b*rS>^-)Xd`$i# za>!AMfgzAkWKUx`w}QmJnAlT}z8o)Wz2;)GXMM4R9`Tjj(V@l%wcxW z-9hFpTBMfRQgTP4nA(l}jH#Ghx#DczHqm_M2pqH<@Vk|L4o~|Of}Bj@fF{@+49mP% ztBCq?tyveO7!+ii6lxs_Gh|-8&^Vo&Lgvk!pf{oK47G-8Llve(AK;8Mn8HGlO@QB(*nTO5;X!xO)#vok&Z$;!LCmHDZMjO@kZok$};-Md{VSV zFAu=L#gF7a+7ZpnB(n#3))lggJ_nR+do3VDB=+lck(6*ywgP8ML(4~5>-UKSm-KD6PL5kcp+vjbA%W2 zj*`JgMPSqiaCsdNU!B}ZCalEk;LbFmdZC)SNw239G$EMEjxc^T$gDEd5cQ0N-k}MG z%daNRSW)(JiJpNUlvCkC4@soIeY{X61oyhIU2KOq%@>19j+*fVJarFmh5$YS8=U7Z zCM=kW5?;W2hzgE%>og(iFbtfZh7eU>4_8anJAY?VG_p^~P2?)_o}jKrT8%yd5B!3D zRtl9unW98oFTTnCV>-gku;<*y4;Oaw*W;D9=e(igiE3cEdw7v%GwgAlx{tmB7j{CT z=HrZ`IS?k)f(xVZE^xKd??4>YjNd1>irfT8WjUKDxoW3fZ?_)CqmTP_ts>p7!2vsI7ey`|{y~W{5?WD%WhppQCL-14P~K!B{6qoy+J4*|*-} zRP8Dqy`;%+_4HC4?y{KjRKZ3kZchFKFNMK<1Q%#Tx{)Ro9V7qYq)KFOUHsGR{1b?r{ zmrle~MCHC10JHh>qfEBm+oZ5nL4sGHpSft%P<1cD(|0-l#ZoV^K>QW@j^1Wn4#&5y zw^CU*SW3{xc#4Yut5t|=T-PnHM`g#|BJciyz9r5qpz5dyyuUeDplA}5Lo9D+vTfNW z>I#H1hxia-x904;6p)*pedASug3ss6p3eXAH`$}}25f$9<)p6ZjUw0Y-E5X835>SO zE!H}xrt((Vw#|0=y&LShWfyQ3VzLqcN8p5oW+EB@B?!s&bhLgvdJT!xa1iECnDmqC zC)F?7844rU_oJbqohkdi&T`RpT`4=D_w^UE@NioddE4qFlbZoa*OG4p7y#SKDIP#q z(b7KYu!T7_7xF%QGhQFDLlO6nu419S*Ef2HqBG|^yJuV~Y`t<>*>Pah&bicY3)gv@ zAFp!IP_&v2dyX2e7LKP^&CK}FcF{jAN@|R^4H51T}SUs+LBc^`^K%Er)nQ}{Ksv5gB~!=lyhWjRqjY* z=TVoKwu}VJ({xOSy0_0z-lh|bDKKZ()@s+fMZGS6qC55?c|}r^h1dJ%tdX{#nHjga z)=;XC4nO2NTYKr$@WEy3-jfwaZoa=b|M%ImDm&I?E^fqcZr4R`pX5^>I#o46A<_P| zRJ3=RL&Qmi)n7rE@?QIX(_u`%id4H?oj5EGy&ZRdUBIN-b7OTsbmiD~ZfvemmuJpe zFs8!wZsNGTTi3Zhx~=r7PQRUa<@CkfPu{s~^U^8LrDv7d2Uet)?Dbk5xlW`Vw_1J4 zr=Hx;R0Up=tiQc3a_krfyW*9Knys%_KiqtK{{+|G%?taS;Iyhg$NsH7JVxkvG*-6$ zk5O;M)wlk$H?``uSKPh7A6EUOS~EWKO5!(c$e{|i`H>+N$KAUBYt{MK=2^pqpJg2j z|Mi@x{XTkqw&S7b#6HKi9y*@M(#HsDACUE@1@FaP=qFTia!mGuDdf+iedK$v`5&BUt?4frp z`0W|F0dxt_oFG>(9_;q+_I-*kJ1?3Ka{*TcN6osxvFxWP@6VoElfo#PDT?Q>c&yRg zCu7+6M2)|_C-tCcDTHq)-cFqHqF!*>VTpe*2Xi3UjQ1OAH51J$;I%q+n1qTKx*{fN z2@qn#9gabS2|xC=D)R9+z*f~a?8~V(^f4Vzha(XjDH_mSIowyxc6C%W!jFv5kF#3| zI0f=s0j&EAI=z^ZG*N!($B-g&C+Xg!8M`myoNoh=%O{?Y2l~UT1T;DQ75TWd+{G3A0o$S^;TR+P-@mB9 zSQ>dL>dLZw%Vtn9hL#kicIkx_LC-v-cFS2Cjkl97$8`3&HMHz2Q;&H1hvC{=%KxbM){DEC?C`J?4$tT7|K^7ua77qt3ME7Ek<4L#M5DuW zC1Bj%n9@trj7K|;-7y|reEV6fY}Av4sm9j5<40XtmfiE`)WG3UFYikuPd&K&pzF%a zc4pWJOKr4vf`@D5r-A!1w^bYd3jVO&P}{1&Lgf;ooZjUEObhZlLRP9+%`xnPf)(54 zhw~y7XW8dPlh3j@Kw%yQ2?rt$({>M=#(*MCp{}9t(~xfAEyx8mrKaT4LWs^vP<7WS z4@cW{zx2{3El9BUAVlJ?_bhj_448gUC7Q(#fp9J-0Ne2M^2Oo8=X^Ca?!4R$;?Icq+uISZh%@O_KY!jXG0KkV5B(+suAn5nU_He z27)&0#2Luw*F2TTRpzrQqfO)nk-Z7jiy6O8c@{kd`Q=>$$Qe|Z0U)EeVl9RpV4%2w%5tV?6?rz}jk^P;m3c8apE4rw*O0`M7f?JzAQf=E z9dJP&Bxk&6zDB1PA0)fU^}NtMAn+eUIs&%ehw=b6ZqmxUyS*@dKFx5IA$|-|PdA`y z3N3=KCBzvmehfko%AW}Qm>*>sU<*m3_afJ){N6+*Xm((s9S~Ae>+L2Qeav8)QLw%+ z5LO<`RSf?2ADP^=<rK@DSLB}tM^6rLct0ZHWFM6P;gCb6k-i3SfgsbVIJe5bWU???WfVi5z)&{>q z$ru)k_Z)PQXNkS8ZV~In*8wzH_G||DKAy>0vKP|vGX{}|DXn}x@DyO4C@7(>=qDJ8 zIi`VhlcrNIMK&FN2fQG1JfUcd!1rkq`=l)1$B#f;<^qaV=IQFuS4GQi%bdxLyuiF@ zGQKe&b4jm8S1nh>!5IyrP2>(imK=`kHe+tV9LP%+(&CtyOPYsP5jgE11ra!4r~>4! zHk3o|eeeWTo{7GJ$}A+BhMOC?0D! z2cCnb0Mt@?#01sL*OGMu`dKf$fqs-rW1z-qr(?0eeScoS2Vo*9R%;R(e6c{G5n3^6(R6W#E1gj2F3$&I8MuzC*= zu@?`~1k!4MP9R5#>qPOUOwr%;jKshTYPta#?pSR%t!1)+HFIRuNB3TJ65mQ zS};?z6)J=*wXTtUS+Iy?a^$wqOz=B+7ai=>M5op_DRb*McdEnI((zab&x_n?0=*(~ z5mb_^V5C*hvVbCA;NL**FmgU_V4q?_Tdmb8R(DoVZOZP- z_($eHzCI_U6OQD9`r;sZO zWs^zVgb$d*cH;R^`+bxVF3-U7-(>9%FE~nJKq?6NyQEHy;%jSV+%lRG_<&}{~<~=lWp|k zso);x6}Ygy!FVaO%;5Z zB_u*Q6$Rdf;Dia%BRHfIDAosHB-aAE0vQt}o@)14LZ5SOe`SwD5Gn{J$O4x|{4n(cFSrV%TPZvm%Ln+boUMPquVYD|5KUNS|Lp zFFC?icZKb+o8-dwpy$wjkxjE^BfTTFf{auPO2l8zIb2{H*Ye=hie>f6_W$<+y*d6=DSa}m8jX1$T;bNHSg1_hb?NN9?@Hf27%OtdS!_B z2*7mv#XaP9DA=A u1Rcz^)PJT`#=5$6D1Y~kh7O8Nrfthd`C<0H^_SP%FvT9;(D}Q6+xUOs5Pbju literal 0 HcmV?d00001 diff --git a/dat/archives/samefile-images.bz2 b/dat/archives/samefile-images.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..d0efe3aa635f0162c2fd61607b4e08cdf31c149d GIT binary patch literal 7048 zcmYjV30M_U+ii^aKhq=XNU(I%yZLXxU z9M)w?HFHrXbOAFZu&ca{^z#s2H$0U92}k&7!;Pd7a6o07|fsNe3<^W z-5@fK@|anaZD1I(n6cErAk+DnZOCGyl#nOk3uYCCha0r(B8ooEomFIDJ@4=*4nK%d zd3&~uRsF3;b79w7S=TC=K7O-XLT<#A%Ei`T&f(A3dVFq39Zw0*bveGs{LrtRW8$eo zlIks;k?G~*wxQpi%2~f2-mUt5oH_H^r00Cj2Fy>g?M5&v>+~->HsCV4&6?Rju^ZQ% zTXVK%d}?AWI^*45@1v))9E6q=wx?Z9qjQzgF7s>m@A>6MX8iWW$Q#qhK9qrToWFVG z7x_%}@`wrclyOcfV`o!OvMgukT`lr-yqR1v+hc2H=2dC6^ad6==bIsm_1BMNko!#g zg%7UoO;7jEJz7+?Am!Gz#v>Qq`S@|830uSb=AXWDM%ZZ%&0>d?mi%i>S9iB-bB_MX zFds8n!mVY0t;3C?sbTkT^p;IN%v_H%c(q5SJHjkKg6IV$4qKNVu`Qmvvbkg#xpnrM zeqyetMX2Z%D_pviFy2t5Z`B~_h=~RB0>P}bVakl0-K-^Bc}vA!4i+qTihYx}Ww8xc z<>b%Wf;0=zc7kcK1)uH{vZAn@yh`U|-NVrpmUyTLR-<>hH&~n=q+Y> zDqR0g>4)CcV*ThC85Pgk#_*j?tDH)!3>ExKZp%Sp(ObGohEKDgo%n{~GtI1gh~=kM zj+0^izOBRxbXpr6N9c$>B+~B}PAnztSz)Yg@kj!*(g}v{WhMC#T7pFW%0ZI0a7;Pz zoHU5x>r~$t=xs5Q$o1_cmebSe$MRS(qVD7M2bF%iuxu=!m4H`0!?MvEtT3%_JF!w% zNpcK@erOvLCf9`6n`B+D7Z#j|_fowsd zu#>G=zOM2rvDOp`Cv35k4)9$bxh?(UkGT*N`naX_8KIZU{CK=3x1kUvxEr%lkM&`_ z*h9!>!ZUbVj(2d{v35+mkDff-yaS0rZ~MZS`K)cBf^pWi270<$!j1)FGz%sfJ`-u> zgJ_%Fw-5az9&WmiP6JMSmr5+7za2>{hXtlpzCz!}2<^!qwb;)}h+m2TLX_(J1ijHL zh{6i~cV6^!r~oFKRyl;;Mg=pYf>HFg4m(*&tj#CZS|Nu*1uw9ZZCEaPdz{=R75O43 zSx6iSiMfdtRtP5N;&)H{^(Nuof$zMNUR{j-_2tWfyGg%1zx&JW+dnSss?o%EW^69{ zHCtf4=hIm+3$g;0Rz+7`pWldAY?NGU|7yTsQ>fdVl=R)7&fm$Hz240!`gozy%iQ)G zWgElI40c;xP4GGVtYV#m%aV*TZRM&KCH`AQ-U2GaFgqr99`B1Uc|J#U6MuYWWKjA& z!+1rqtK09!OH)l}Ut6@QpGrLqUNd;c|0qKVIMU@?jd&od1(o5 zkW@g%*p@=rDiGvE7@I7RrRES@~8#9z~@KS+Q5fqUQCvg49-LOJ7eN{XQNTIlsD8~N9 z>+xFh;26R6!RzowJw4)Hh~-UeR96MB_px>|8tsEoQVB7lhnwm}PQ_?>_pg{+$2FNs0_MxVm*9Q~K;udBiv%iT_*@&0Cq` z?I;7>oonH1;H!r)&8dEWypcE$6 zOUCOeupx36L~j6{8AOD51s$mt^d8nu%+JDmF+KJd+JYzpl>QLIfAEHWKUnT=bOhoP zjXs0x{`m-)7l7utl9ft2Nm{ip$CpzBlYx2r>uNJ%6a_{Ab3a)t)ei`{n$^IID_P?K z7=iLo_eu7YtSDKfaT#>&S2v-Zgpx2Pl|(ZQ%{R=8=!59I1bL9PrBoo<%d=(Iid_J0 zW4u6!j6YtEj={Vdj*4BY)Q&Q_N|CPw{26)|@VluYNxZax?^43K2GdR825>EQBcQOe zrCX3$2y1I*n8i|?Hn($woEKyw0BOEtzqEi-RiE4XNq2BNrQfuPEy({Eq!@A+EV2iE ziN0g_lz7P}VH9gJA*~P7aNf%U^ddz{HW?2kwSzpAjwpn9xyR4_u#5<#S#n95Kj^aL zKY;XlG6I5pkBlPsk&&8j0e~VCVo386?Lb(2(I!qCmLdSo+0B{3tFU+Spl0Eowz%h+ zZHeQzPd+5KaFRKt*x86S?5*4%?p?W-OGI$`Jk7L3iZC@uAz(Hz8=U-@b*u!ZAZ}2F z$Q?;*G!(HdLoJ#08Y1^(9C*i7tBxm9Dl{jh@W?0NL7@J`&frOkg}Mu9_x3MqunIWR5&Qz+pamI3 zwEkq2^oO(lJTvBnO*YCnUt2QrZpjkwR;-igM!T!tGl(G;7!SfwAaAuo`|Y^Fhws*4 z{n%^Zp#ijmvm2Rud~jzE+Q)xF^#E1K)%DbbBJX&kUI^v51EAJPybUdg0LnbE^MPOF zweuW?`kZ77M~97)35G&e0;EMtz-P4CQtpG5gPh(u;re-Oo4>t{D*BF8#OJ)hFY%Ts z)g}Blyw&YlN_7rznB1=r;EmQoWdPoQ8e}9JVCxQ>wmiNUx5_W!z)mCXU-NDVy4Fhr z^O`Udu@evb;^@dl{bqa4o^9RbvAK_|EY z_+_L2Eu9*ef23vs+99)nC`N#8l=5Q7V_pmo|2;G`JpA5X_E%|E&gw;GW4zVW2|Y$5 zY{todd(?wSWwhy}G@E))sett&_~|Z6AE1k^(&glS{_`~J>sG7o-1>iyOD|S_D;3S> z{Pfe&xQNG(8y>43hK2ojG|KHs*~Y#SE8jPS*xA{*QS)HK;)V5dTaDix8Wr_Sf8EXA zWjuDLbh;0%i;(A3zk|4yS5$)ylI@6ez|94Te&Ldw}_X$(R*qK3C+P6 z%fauXE^Yc<5is!N+~?i7QwzNV-CL=F-Y0i9SiQ!p{;n*EIbQI&-IOeA^JPyb`;ev| zBG@igUrP!Q1Nm1D422Qz&p-4zt~5wd)*t^Lv z7~@mwJ8l)*ZSQLqfZ5M{vYMiT!zEgc6+fdC9LYMZ%1zS3r>j#kS0T`V^Jfd^PD*n% zpgPm+lSAyQKl=cxyYLsA8$nQ@hbAkdqHXL@VKm-@XE66^|(W$b&Jo=pC#O z0(uX{a}q&)hn4=iI{fk!Hq8z0KtJ?@fR=&Y#gK>UIPdxc@GG{bg6**p5WfZ(@u}$} z)AY@~lAU9`Ws1UdezHY-#xKT_LuF9Pda94vfxh(w?Ey8u#8f|*Bvw(q)PPiWpL%8# zD0Y=YRdzAy(yy1qmaNq0De~EQyw&|`J~p8Yq^r{?IC{1{H<&HUkR6u1knAg2A$GmF ziCJml3k2lw^`tU*718r(i8ov1fUv?sHS_0s;dDdAl!4ssMDJrSx&F$4E(^A5OvPJG z>kWId*(=^*p)#0)cF4mw8+1HL1&RsP$M9#CpNYV$Jk2D^t+Q>pYY!by(0qz!UyzN1 za|wQi*Fuz4M#<`5&$CM|Yg41ZmW*{ZCA3Z~GBRWb(h`%f%Y|>>p z{C|1N#ha~V!*BGmB3^9j`4+}`RHlGr^7-Rje}$+69Y)`PkEmF0u<>u2R_k~x%YKP= zpW+6}gBKDrEu5vqq?6CqdsHViB8ilQCM#sd#hui1$pP9KmhzI8U;KN~nh)1+uD71Y zSpH?|k+qbIb?!bY$I1Cw&Pg7cTJ6cqnOU-ZpmV)Vm$P%FcGHEQvf_R_5!AS{Kgh(S zg_B9Jh1}o~@Mj7kTLA7U+GH76>&NCqD|P)7cA-?XqU4=aXhgfH0PrwDAXFZkqyjRL z_V<(UiSry{Kr5Ms)9q;n9*j17r;v;d<{NzFU^Sfw`}7>Y=T+N z|81vHz$m>NaWyMLxt|-X!`_dIMp<#>p{JZ~^n;-#K+h?lX5h~gUj&3*IfS)g%~%6C z*L)%uaF$Q|zyUaDBMR240)DSzErTUUE!jdGiqPX&Up949B4<|t03znnz608SeSLi&Be`u)(WP#jBdDFdWAyyf8ELS+fEX~+NI^~!*k@x zgl9VuU6V&U;w~tpKSR!?m0k2S%R#3U!hU5PH$Wkz=3pD%g11-XDe^k~!NPyWC2n9H zbG^kJJG!YD*VTaaPMT#Q=1g;auv#oz4hFX#G6&UpKq@r%ZU!G30Tp#{_S!ZwK_Qxj zzR;L95OeVvYtVn=X*LM>JE>)iCr zt-L9-DU?L9Yb0^0XH6{RU<*%~KS%H3jf3D;@EW`UVrDtWVG9)^I}ZC>zH2O$ON*;g zjsG``muYN;-c;^peb(ra3E@=|9q4qZkQD}mVgo6HhmFlycYm?#)hs&N7fbB*KIGma zwVbGD7U%^Sgx$s9Sd&EoUxB#E*hdnSL6d2#S?=l1k|dLlUdqT10!}j=f3t}y#S41I z5Xsf7@g@r{7%j!geG)nKT9M7Z9FMRC+`xXoB9z+Y6s#T$`J`0TgkG1f;`(=)JtGtP zgD9dFer+5T&^$!j>7BiQE=9h z@7Q#;J(cWBJ%3bkAboQ>|0!=p%Vr~Jc&7E)MN!cDKtF6P36cCG0SaNL$4f8QA%Nl* zgbw_DAkhO#WevO+y2)~(|Kx-=T-ZQ2KWqURLhdNr0PR?V66mBEgRV(eOUB@hTD5)h zedq-v_>X|1penIqK^wCQ%c0>NkF+2VhsIIJZ5#BBZ>0q{Kh2QkQmvEF$tA#|w?Jm) zn)J;KbrBB?)#fJN4-gj}ngD_J*InYRROB0a^{YInCs0MtpsiUQW4UHUwcuq6=FByuqE(h+cDLUQ3vtyk98FKc_$fqb0Aa{QDC%sDbH7Q&~LwFEK*LkEHgH|4W1?^P?)ZJJ*$Btu-4Uz}Afst7| zC2}*g^rG0=C}7qC*jYRV3Dh8XIsdpstIpw1aMjLKzhj>6LdNO0Y)dJ`GQl{JLG+R_ zWgDUTF5(Srp{LnnbP#<6t*5W~#v52ps*lu$QDgju4Dt5m0M|il$fsMYQTXqHfqTK- zLp-iH6MvJ?Y6k!V-6LbTJ{hMkV>2<(yEG8V$d7DGF(=aWJ1M}9>+kS&1kw)~P*|p5 zePtUw&0ez(Sqs`=MuM`9rm$+hiz2_tA_H~?Ku1(k89TqlnVN(4dzw*%A*_h&Qxpmf ztx`3T)kn2pAO1V`e$Rr|XmQg0o|@^MM!Qihh<}0cxiODu#<^Ja)s(_P#MA5%I)T@7 zgFT2l=sOg9?Is%__i0S)_+yN-Ch9_}bxNrkQ!9yQ+#o*3iQopq|1wE9FA7MQR-;6T zka;DFn6D5*rvadBL?^*+)M!kbu`yja%v!4!FRCqB%G=9Zy~RQSVt6Qg<6!AGvFzHC zHGQ&9YFLpkJ^8bEH~Lm8DnVzYqLNtKG zC>46-VemrLZeOemKOP7>CAq*>a67s`7-gI%p>V*btOEM>Q{*bLJrS-SH$dqF?Uo)I z@%k<^*qhRpZ5X8+;~2PjFV9X<=*xeW;>}gH0GTn)jj6j#i?W6#@$6jKoXHWpdK@9a z8HwqpEomVk6(tf-yFh@DjrwEmKfChy~dVvFOfWFp)l(k`v zQhOb}#SnpTg9RUXl;MY7N5Wt;It=jqaj%+gHILWOm^cM%O(meUt+axzlgE%jTa#WG zr4wkN7LE%Z5NN1{2I3(Z2O{&3+>ckJ(U7O>1NJPc!QHaYu$+}4k^!+x*T#Hav}r7v z0Gs5ZT*w5_p=!xOc7Yh;HAe4U=w;>nI`GMR8D~u+F^yv#-OKA~XSWYn6-w^19fvjx zeAq=x=R`n_+99+%1r?*Ma;@}Jh@3CXn)C!w768$`f`r|(hzFQ*14o5gdTVF#AgIIO z=0c@<5v!5cfllavL%>zXmTh#0`6^(68qO`WWsZ@*Q&|=D*x+Yq{?=N{Xp?N`5g;u{ zUaS}WtE=bIO9$zTSE`pvrn%}uqaYKtvCO8MJkTGsCS_V%Fn-Od|gFMv!F*hjWX zSKy7QerW4;sWtX~F8;5s+-(hHwceZ@=B;6Xv(xa$OV)IPnR(SNnO2yuROB(vALCC0 z%T}W^onVzZEgqmRVH4w^R8XX@$3}GZ%2jkZ4@wR^1-W}wvKkMnLjaYQY|#V2_hs8M z%T(2pd0_Un>Nv>hE})~!pgw_YQ55kPY + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/Thumbs.db b/dat/cache/Thumbs.db new file mode 100644 index 0000000000000000000000000000000000000000..d91ff9ec90648da70875fbd6ba56f8eaecd39133 GIT binary patch literal 23552 zcmeFXbyQqIm+0HLYk=VH?rwn~9S8(>LU4DNU;z@`0>Rzg-KBAN_r~4zb!NVA-d%US zd28;h`_HWP?Owk=b*j#(+O=!f?$f7gVjOEDtBPA(D& zU;+Tpki_5f*SEK~f6oK}AjyBp{~!yzKy>{(et)5b3?dwazhjO70TBWc1Y`&(5KtkY zK|qIq0RiFy04xZ9?|lb3;y}QKfCu3{1bhet5C|aip|K5a9&y0C)jk0UQ8h06V}0AOQFVNtr@Eh7i61xFIFH zko12hi~wk;zj5eqoqzTC&#wDl^I;(;gMS?oBL8fk55NU!kNY257(=w;fV6J%Z#w+@ zmH*%0w2&zH&;I{c+sB4fb^mv=LFAw98$;Uu+g}cd1$ZDBK{WZB!v)FXg5>^Z0_p$% zar=Mks`-cg|Bl%|?f2I%|DE~&w?F?k=l@^R{Acr@1yaTefeivXguj;Igun%X8v+jm zUI=^;_#p^D5QHEEK^TGv1W^e8iX;E-wSQyu-?@|W4}U;_gZ`deceVAl@U{WK{3H#O z20%gmV`9H810(@(FtD(&FmRABI5;?X1XM%>h+v?gAfaMmU}IxpU}3$(BYyu5hY%MF z3!eg?kc5PcjO^WeN@_|{YGP6{(!Z5JL2gBWM?gnJL?^|;!Xf=XmbXp-79v0&-~$6i z34q3eg294%>;3zi0tE-r_CFMcoI}IFLbOCgLPmjHP=^VL7BDc-5d9$?fRy?`$^o!g zaM%39eM6vhz~S_d$wH)(sOrL1o;;`KGIR_;LdJWKPe4dROGnSZ$j!sc$1fl# z`B6$*Mi%%a4 z=H(X@78O_5)YjEEG&VJN_w@Glg9ZkNrlx0R=jIm{mo~SycXs!{`v->?msi&}w|Dms zkAM3G1%UbYZv98k{X+b<|+x4#|7f`y~tfXDuzgz(Mb9VMqfB925% zR#g`g6_@fkuA$>3G9ESe=0C^3>L2ki_kHIgNBbk?|Ag@`{%exJ5T8OP`exA`=@9R3 zte=D`zX48=$2emZbTPW~RT_OZK!+BZth(5qmCpyu{esDPmyvQ%_fw^V6C894UxX6* zye6o>o~bF;Vqy&4KdQiW$6an;f1N2}U2EweHAhJl-aPtL zO}bb-%zCDDjT7*>z2j#tVIp58I9Z7b>kTkpoUI_V7m^fjhCucS#&9F%Ntpm&-J;QH zWm>*0-ASR_kq5OsKVFvO?!GjRt&P;J4G-N(V@&bvHJ-@-<#8B088t)O^*u+yt$#+V z#rFx3Bd$@>+IF)xy!RZrba_{8OhRMC&X3dE@!v^jG`;)%{wODb+LW)1$htxEXrGM3 zuQkYi<_aY|p9)POU91%o;JA!(QDgA~oj#in)0Mhy zw*mB5V*=w~tyc#U3$>(>FQTPzcoI#~BcpEs7T~i*x`j$m%K7-cnp6Z7YG0CQ9it-p zWtP2YZLs{*Ko45n!*te);+;&nMY^%aLn3K#JP-w{uDw-x4_(=so#ewam%PmzU=8Jd z>xcU#lA%l{f7Tqlfa>#@1p`{9)+-t2573Jt|l&qGNZeQgL^o@ zL^34tLFxAQ01A1r#F};5D5y{%5AP6xlU?j|(pe!tBo#!)iE)q1&%d4iy-s{Nz6btW zIyii0IYwGD9Q|QbA*dvwH{5--^ExYcy9qb_jz;lxYenP(F14d6OP@rBggN{$kp8&f zLfbth)t<40V?p60*AsQttTCb*WdJ;Zs-hiw%bhgYd_tKMEdlR_`)tJu1a!Xa2?dYA zu`TsaG)W-Tsr_`6x`{!tSv$I+%>7EAYG*3?`_DY`s=8P?y<9}W?zizgC?`c{52kwg zsS{-=WzfN>nNMNHrec|VgS_ZvC_0Zg=qPi*QtzuXY zF-otX$Qub5#oI`h;M$S9k9o1URAfYFS-3c4{P9>NvxFI#UXTZ)@^e@3&l{kbLF<+& z$&Go?jkhPvv0z2*eQRn)vb>jb{w!)s-dIGPMDX%1}Jjc|)zwgJ3YZ-YpNw zf_fak3;dum^$0hV!57m7P-jbSJaoFwaT^}^b{6WLy=OklcS^Kl%9OFyRRHp)wkfw4 zQ=F=rQ$xjAduAL-JPVihmzfIo2PShN@!Cd=gfxhA+!W{U&R}W<^9#?uvma3~HSoHU zMFfNC+NHREIkxwwYQ%A2WJErQZEFZ5Nt3AT^Qohnr2H86^b_kY?XhwNnlz-z6#lAu z*b0uGHcbk4p?k+bnrHF!4ratWWga)#a7O1lIz#S{WvO3gpni(%UX7}Ua{mAq#$`+u#;NKo_vd&k zQk?2_^x$And_QS5I^=pjoXxJRM{%PZq;my5jB-l(I}H>nBRHZ>z5&MR-vDPZpJ>!{ z84F4M471F_Nw<>zj9;jS_Ua|Ho_@b!_%qAdGo$R0R--81^y?jy1I!ANE6}Xs$y> z|IY`G2A5*`HO)~QvZOucu=I5XvZP{Kqve=uVfATAQyiq^t%DGRkvPjYz&g|T(MLxq zJXH1`tbR_+cMs`S?hQ8b)Hy374LT2rBf$iz=y|Hqj3esJ;lG-))ZPH)kvR{^O*}KP zse?=nPoqj6t!mVZ#Dj><-opWQEYl*cw)`&~DrJr8d$-bLHzU3gl6%RD?9)5%YnfB5 zBr=8Lnn*5l9tnlhL=>OB5Z(Zu(yu?%>>ti#b<%4eFw>;TWi9SsmZjFnPs>h{D@zzzrlLy&2hKvT{a$Z2)@!Z#64yAUrqXdDl>aXzlLNvX11{TNiL~%uzb#HoIurNQ&1njK)Mi8B zNq)D!XYIquFliAuva<98))UqLx|l^kWRxz|$I>U|RHIHW!g+c#JV8$h^ZG&B{rRC# zA&DoG(_*RD5$X-VOpE`ut0v}waQsSVE|preE<%@?u|#$*fzvr{JB#m`2E~jmu6S7_ zYYZmt&+>jx)X|ChdS5d&7ou^@nlw};x;@6W*0e0)l9c(>7u8*SW4@{i(e}v`J0ASG zA?fK|^-eW{u!DxmM=Z_BE{WfAgAHW8Q}u#*nqEZ=9%UGM0Z)p}bjDGbROFT8mqn;V z!Tb3@gs;)y>mz-`20lTeAG6L)?PFrQdy7k&9awjX7x;JOpq_ThsU<9t6bVOB4Qw;Y z>~hXD+HDKEz1ruo!i_ZJJQSU>wDp~co4VI4OrJg(ZaFfUz5Kd)^$WrN;fd2eE#7E7 zry;)LdYN4*VQZ77AbB*|Hq-?E{L_-FeYXNp`6{_%h3UsxhT0Pe;)lv=AFF!YZ!AfD z{GZs?B;B^62i118R4>uko5)^^XU2A`=-NEk`d$pt*!t@+SIzI1LM;;v7xC7_TYftI z?wP_BajO$!suIWNIo&FeaR}5wEbGlA zP^MaMWn}Hmx_b;AbR<=hRaKBrpk6(@&DbULVG<>gM+|IKO9mk9>g{DYY#&fVDwuQj zFogM$JOI8LtPr?2aw$3_!*(&}LEKcIE|SQwi)lHI9wMSsOu|0q1f43|a2mZZiv-3yu62x9GVJ`%>H zwZT$1xo}bJQ@BWB9CrqJZ*ulF$WV~4ke{F^c3L8HcJ@{XO$M|EGo?oL zx==r3JMa+8Fh8ua&WVk)y^wl4>fX^G6-K4rP+xa`^}#gZ3O?dwvi)0Nx+YBcc0_jL z&vxAV3%j7E$>0fxy_6r97e~=fk7i44UY%qp&Md6_Y;|F>XFP}l6nYK4KRi)Uua5Mc z?QK=|QtW1KOu{4h9lL1u4er_cNJVTYMWl}uz5Y}~2MN)byq>Gf_=-vDXKZ5p#B)=o zDOjRzXx*Qi2jm1^3%~yUwM~>_F07Ta1ab~@aG@uaH9*eyFp33yb&9;1w(@)f^t3P) z(xyC#>2=ihfH)tlqcgs8w5y%;0}uKfjViCR&evY0?~!NCSS_^I%-ngjC}a8aO-z@Y zBA+Rv9DVadF$gpZ4Tjc~!JNcF&mva+&kkF|XZQ!_``<|#L*;tx_(Zp)zA^-)ax9^zJAZ8~%|JYiv2weUucQwZb<{oiuwc|Ae3ib+H1f<=sJ&?M zIF{jK%Z94;(KW-`Awh3oMA2oOiYh~&N$AUcTCO=Br-dk)sP`$7SNMte>Ubk=-KVJ? zhk~YYg>aE-Q}9Wl4TxRk-cJn#-%eqv6+yg8!8uveFJD; z7tO_5tyEufszg=CQ?YzicY4J?XY^^c(x9@hH2mz!c^ zJH3AThB|*mP>#OkCgv14eO{vOn#f5XbEBiGPOxw=ReR$6WJh1SlvWe7N<=o+hV1@` zL{qh^-eqV)M^~gVl83E!B!|Yi6WyGgbw@t)23SyE?<%H%Jbw7z9GOIBzD|yvtIaQR zK932`TIt9!>7=BTSZNxj9|S5=7NSwW0OHm|SKk0Xys_eEC`FU-U+dy_yV(dAR{QaZ zZM&9yv2;`_kTc-(dFaP7dP{{y^48ULfGM^{O%1*|lXx+%J8%gr4Vk{Lb=s-=BXrWa zEF)!(fa|QoyJxEAdWT(^n=5z*bpH~J2RD`L7~lSa<>^;r^a#aWhO@gIUmg=@JG{C)~TI=^ycnrDvIYR=^3*c>Y4Z3-x3#%xRs} z2VYMgKp$f^qi{DL}Hnx1wav7XQc`n z^M$E(BZFiN zxYs)WBY$^ft{}f;W_Pzeq}2QSq>Bh%&xfWsEw7Nawd!SBJZcIm`+-aV)D_1%{-M<{ zbgl!JyrfWcd}M+Cx?CQQBv5afAnhxkk}eIna< zK>}Lddjq6nVOL=k9j<4V7b;B+nmf*vXWs~S^pIjUUr@u@7%nrl5B$Q{eT=(*v07+- zcW(7LN-8NBW6o#SBmC!vfkO&R634!*v@=` z$?K`Noe-7R%8dC8qK@nLS$J}qYJ1;JhPqj^Ug#dWeR3C(fEi57Bl_?Jx-Rz?#ag^N zwENX3#WPf@aUNN9!KGhoRl+lE5G0E{kIi}Z25>`m6gkR@fBqs%lA9v2gdo-y{RTL$ zbC;dF#Gu+i&SmuP+>T_5xd2DGun=BJH#A3XE%jT->5T)FsQM9yifmzw+N^}(Nthb( zmHW2@$_O-1L`e_QSzBX)btNTo?uw5c)d9wK_V%HkRA z4grzwmzP|ro>AJJjrY^HO=!O({|p+s1!60xt$HkwT*PvOpDd?)5cKKaJ8V9Us%Vii z%${sEG=yhV=}7x)h^>J#PYylGnML8oa$KXhHy^c&sL5pzy4$ju)S7%I{bQG zXnVbmzlwdSYd%PExNkD}!c@2}lce9q%p%CSSCDgQePKDDre<*%sjx0_p=*tD=*qT_ zG8i?D+hFnrK(Z-53BLLiwZi-(qc?d9L$0~51j8nG*_YSo(@Z;T;y@(P8vsA>%F>np zHsTF%U)(@iw$&-N!(iNTdwTK)sG0e2E;RMWq4F#xvt5pl z#;RPie*)ihpql+m);{!rW#2_&NLlOWd=#Ny>3GuX#9?FT90R9fgi~k=7*cT)?<`hH zmDsvM(qfD+@Qh$%MaO{PSA^^Gz@BxaXO_G{;&~L_97f{T`-qTNXdxdbz5d59H;kzo zk}}#h+B*}a_Pte-gffKTjM;vGTj-4T5`;Vqbz_Ao8)Y9jM?!GmGe^bOloJ&>AS=*jRmz3n7S^-7ymhtKA>pAK&H+15y_dsw$RBCGX_N%F$&U0oT@j*(Bk^IO z1GlGHo7d}X1#{?5PkUd_Qo^*B0&b{ZE$5kaA6nL;8@7QzGkoVF*0n2Ij-(Gi7aDopeszFU|1bd;alP@ZW^=;+;YfhI8z)=KT=Cgo z?E`47L&}>YW+3;^`O|2uSV%g|`7zt(t*Z5?G<@N-2XUXT%-SsEVZ1ts3e*E6C$y|R;u@UG%B6+m8z6PoXYJZ9AF+}&(MJRACXY@0-Ra|0@HLNS9qYDKzt$?Gg<#Q+ zGFFHp&G9_qM00-YVD8RJq64{(r~?6ipX`eiv~f$} ziY4tny$HjCY@!QMQCW9B13dxlA)k*W*WE#r&>MhITys@=`%A|PnRX%!mH(6<3B=gF zBo-YYc_c{(x#pa>vt;w9;p<#Z8;F`4D;H{e)TI1HZ~(cEwRk>~H-KP7^LLzmai;0E zFBll(p2|0RgUI%>1r@8$=FkSu7t&`}$pH#DMxi*V-*KSc79nf6{~h_~`rpPs_9HxL zeoUxfqW|?jVf`=jU+aJWSl9j^zy5bW6v`-TWI+UQ5Jv+T#5x?PEc7tP6-z~rc6Rky zSS;}+OA3tFS>J0&{dS>!l4?Q>+%@Dx8i)6zo+Q`NjJ1k)OHg=Eb?V>emVhTm64Mw> z-);P8Hocbkc?xgSFM-DyG(_Mr?(|$zIaRyMT-^Ch9E4L&nGp4jdTwH9GKkgx=QC6B z)G@OE?;~|xlnU&j4X>jiSVM3^ETDn@OKmYp~x480$y#{D!?eUvcy6$y$gs=;n#lQNLr% zQ>NKc)=0$<=y_NFQAxc%n6GoI=dD4(7oE3zy6udXhR1ol$?kHBZk@JcIm5eGh(gYi z4$9eZ>M<*qdBB;i*P;!21GwroX;!xpS&Sc~*SYD|&(*$|LLPIEWAzU%{RwlGF>yS% zt2VA8U#zmKr%Kf_tmRAptXE4T6hPv3UV&pXeue>*xPbzKic*@0R!yx@p7U4JV71YX zGZeaBPiScI%vsn^M@A%|@EbV33oMqNx&xl0q zGRBC++_bB66ly5I;CwMYtjc!B=L@J;s;WmMwPM(|Lo z=8_Z%hwO9iwZPe_h?L`3i`KfN{1szntoFE$RNIWF47SbyKcRIhU8?e)mz)HoJvIQa)we{G*v;EOO8(6E6uvIV++u1=Z7v+jTBi z#0>2ftx2eGxjVI^Wf(L%27F7{3oYizGIFX>BvW$x^y1gZ_v^_9CX)&-^!66D03|6L z!2LvvVZHMayX;o+!Gv*m1<&+>Yhzcx6g1lb-dDHKBj*xw1?Y>DwZa3uPFE0V-ModX z^-yu+oq?11`&ut{grPP;Kc>QI=EWUVtm=zcozM_q6>=v1WBTv81J_oYopX*p3Y6S~ z=kndXW+9z-ow_i~B8>HM7WP+tT%UJ0+0R*#DU?wID7Oh$DE()}8Z;)LUm>A+v!K3Y;hp)&yJFJY`ymQBOw_|;t=IYAI zdzlRnJ?Q8n*FWX=mWX_@t{sg8W_Kzhy6l^Ssx2ba2LlQ&omWKEC@$f0#~Uvlakq~a$iZs%%j ztUQ0|tv{d}|AC4~s;~I<>uZ}!hG`S3@o$N${Uj2``YaPGH<+cB-Z(0Br6y3D5*

  • O) zYW=n@~702HHZb zJ;9(FMlNoH)NA;rmLr>qLCW4Qr$>=>2cG%K+`% zYmN4u=Fe+8*rUurqGJgoNQSLMj4sOc9TC;hVSQKjLfOT5In0*l@-p57O z?9h`)h@`{Jjjk;W@YKNnLy|F zsS*9TxGrmv?e%5si{(g-<#<%rosu*TK9!`!vd1B90s%ZPo{zj_l8H*_PpQY=2b@Ehht#n+W{Ai`A!X0I_JA`RvH&;IK?wTTk2#B{=R5Bx6QPG`_G&Zmj zV2j{<+muYzCUq=CfTCNa945M1!`tPa-*GK&AEAL~2TE}m#H3;&`~@r0JPC;;bvyI2 zdilS_-Q1XE$s){4t#D%*s$>aIXkOQ&GcXGTs1sSn5P>Tr@#7m*xDg ztQ<LpworDNE0vgv3dHJUtMDS z2n__>5thpib-s*~-KSl4!+Fes&c>{YbH%-Xs5Y(&0^377;|a`dEUU=Ib~82gaD-A7^FiT(ko}Sf?9bF|uxC{ke#>M*wTh&n-t0 zUmwV0FkGZ(E_s)bH0MSI7^9^^Ek|4ZnB|c*v%s@qr9#c{MPT+3c$_b~U+(d>aB#6r zO8dhUER1z@Z`eAsU%fV>E>f7S$nxu3*U8yZLJmKgCr`$(YC|M!I3{#CC)dm?{;8*$ z?DKHg2l)Q*{;ZFFsF3YMhvh?%SLh8wib?gHNN|dDq;-kDCJq(`c>Ghq_X+ya(jK5T zYOYZpuddsGs?PGv4ZK4uTD>dbHDe~yeo)7@-so+H5oD3XTyuu=Qv6s^II_RVM<2_~ z{!)(V!I6W1IW^h9i4Uo292fU%6B4)7*4Tss6!9#wfu~(a8Fla~RjeeH@$*{U+yUXfX&mSpZP0>DOgv5Xmo#5j>-mXITWru*)%oW*WtVHo zzUcJX)G;uSV zC$3A}NSf;k_8;GcEPK})MfiI^Vc6+=&b6oIFRXpW-8t`_W>|^ClysWeG5ifODy?_F zN!_xwPSmNl+SIO)yp#rtI5L#<%9=$1wuhWLeE-pIm>6FT58k zsYb4xOzD#@P#y)A>dozqLs$L1EYt9se@HnRFP0-2D5?_*wrni&6E;@YX~L)ZrF2=L zz~MP$k1|LEhT_QZKx?S`Y4tBL zm}8jeKcWH8_Z3hnAVJuvg`FuQMapb$ zNY)H9=$||7YY8vsy1y>yE4R29cf7JJ#uLfx?qrKwCgGZ|D5$e~pOvDW2B4zzzki%% z+H)+Au~CcB-8{y7GzWQ3Z0pJvJ9b=-L@71VpRt~DR_(*5^9Gz8`8~_eC@RPwmo3AtLGP13a%hj(;0Cu`y1-KeG#XM7+ zb!dw#y0};sTD;n8aLBW(T}2CGT8#=zZ91Uln_dVadO# zH5@-nZB5jW(?MawaP1>57A`(?tHU&DU6^x=?pAY|q=h5AFC&p8>%YWvew5o6kAiAP{{La>3xk*28tx3l#BvLp#_@`o4QRc#M z$xBSR2?u3uxxX@gn4{#*01KX-_h@?1+q6=V(DeDY#LU)Im9A2lzt@1(A2l74U`2xVPl*CC^) zCezhhuHjYxw0}8Ha_`lv&fycLI(?>MQ`e&N=?%~ty^#1qrU5|dq z@;K8u?UvE`=_`qwdp%eZv|Mb!7~w2g6m_iVf1?+iYlE~RI!4S_bf z$SpC(L0aNpIJ!jBj`U5k5}9UhW4I-pP^9?@RutDDes0UV&9AIzyB_2&7W`~ivEu%| zufcbD>rqd14$0KKHKlMS2d#XkxwsY6=m+m->EJXvd-hQ=B%IP?58ar z!?VXu48-r$kAl7oMH4{ER zdL8mMU@J1S{~`q9pasId8{EDq^48lL$IcJjC@ERT`kdWYs3Y`st;?F4sJ=)-6}@1> zs3>nNbjS3xCU137B9V{d=kJB0t{qa(?fK+hxnI{$0~H4Hf&m(y=Z+luF@!QMSxX=X zy5$f4DDnqU>>J)Yu5{&0RC<-Q?QH=T{2b>)f}D}FABpozia(TC#J*&2$+D@*F@F1D z6WM7To}n`8IIrC|ba0^qY9c^lp*Kpn9d+ePCdu_o0kY0CFlXcUKz4EZvT1|8Kl|h_ zk7F+m)SpsE6MXc*YJkZi%_+RjL}yb?)(K4cCHEU&8I&A=f}+KOx8Zk^{^3~0@_>bT z(l-52sIMjT<3pqXvj^nq<%Sozk=#!f=lDIpkCjY-2Tt*ybKf5>Bv#N*GWDUyV@>!1 zD3J)b%lZLLke9|_9&(@vedQQkFRzoXAmY~{wLzow&)@VtI7V2yE6MGxDrRtEtx{$- zv}Apodm8f*>@wfG%ckO?x@!RjZp%v)O*h4l=2JEJ@;Cg)+z|q`r62L5nI}hMR~T=| z-3CM$C`j7!df90oay2L1=%7n1msUYbXvMIyUFs6K;3@=xyV9p$G|63R`mhn_WMd>y z2iH7J1v-*EsbaSEkruzj=}bif{*crsIqWU zEY4iAW~kc|ZOFvYO;m09r~!-kTu&u(xz^UfxYm2&xzK9sJ`CR0l=Sf1*xwkufcL@HQ8- z^hy&r-u%=iav60k-&0_f850>9iW*T2^f=YVOvH?NAb^g~%9&k;mqjGD zHolJ9x5yge0|Uoygx}qHy&T_``xuTzP)B8-?nUvZp9(=0nfr;*nh7u6@Y~xK{)i?)qp7w504KZkKj$p+SwT}PX>D1LJ zR3Ddq&z*KnJ2!Luoj|7SkPKN^vQW>GeOdRgUkT@qrJ8;lrM7{Xe(-yGe6w%R+PvZg zZKBnd4ocw-3oD|pkE`Bx;_zlvHdd+^)PY`EFBWj~!8wf`WP;#TunAi@?Qk}yDB9yrcF>2u7!0?=ok2G@h^5H$(w0?N9OzD*=(n9G{>Q za7*pSp4?b&roG%l7u5PSo3+f$%%Q~c-KxZNN5apFx=O`DWT)^~H9HWY@KWZaXjl2c zucCt(pz(nl#WF)IO+=*(^(6<0ItoPf^PEPd4N?R*)+q5ENBVM7l@Iqxk7SgkL4!Y z^3l)f5@7(0n^dHA`0ikhFhgOU8^6NYG=X4lci`tR8vu?3iJ)^k+^}rf{d3NgQFVq| z>}Cw|LqA1ZjXmw4z)?)pT%naHt{$gQncS1yUiuai4!1Aw4yve1OL*`&3_h$;vbs;` zo(SWbPQ~$)`C0g9`>KkRU1-d9QEQknuH;=89a+QX^vB0XvtJk~#QNU`z^R^&;-!k{ zA8k*mldY2Ua)>^D|Av6DF2Z;grfgNlb%&N9gJ2Fg1(SH*l_Anz;8mF}36I*j5l=bm z#RhbOiQ2s8Q`QEM%&cp$fg)FW#Gb}ni_t@q)%C(XJ;pBE(^J)jLYpjK2hvkH{E z9%6TwB#OT3sQMwM= zeDBdnHr#%hii>{PZX)55cqe!QqZE69KisLz>&F!{UglgsF8~_({(IPBDm!}X^<%LdmVF!F#}6)Wswm3$UB;lY2sv1{U0O9mMg(3 zH!mA2vy`NInArDJY?0k@FdE&l9MxJ`wRqp15{y?AD=C}ZSwjcVk1O$SV8rG_x2_|! zM;3K{G=_7b6*oOpBZ!TaSuCYCoMVZ^NxdsqYaQ7!ijov3()PJ&i_CGdO~i0=qF=3B zK&?E9r-4tniv>(DgB|?Q(4db3&ksT@D7t6$s zvQil@Vhu-v8*VbuaMGuHF;`?KYWaTV5cmvbIv>2^JXN5$+o{$DKB-97CENQ6r?@up zgZJ?1u1XcrBsrSi%SRD=hx1CGbvJXkI^1<|C4bh7Fo(R`?tZsfandl;A7{axhvi_O z|KW1O3^wLYTF_HNk9Zi>irBI$Xj4rZI!atfopRMUwSjbIQw*wFHj4?yCWXZrI#z+> zNU5wFIKKyyzb?&hQn}pw(Wv{fy>bPDIZ#ca9hNT%D0!$75Sz-vt`4vVifE=YMb^%r zvC<_!tl?HQ3@q2i_6WN@Er1&8Y?sytzM zHj;N{4qrr^!jXemfjjWyS9#xpE4GBZj1z>k+*WdIm;!&?h-L&iVy;N?mPUC|Rm(28 z?o?faE416T&{(Dj&dPG#{xtmA@5PF|?{kdcN-G`91ebdfLQ$2nkAK^eWid$lBQ`=r z)-&e&LEH2EYBQ4BA}1b(+L40F2wKp8zUaj&t?dH0t_z*~H|r#h3O9xi;QriG^t2&qQ{;?79V z5{j`X_3x;GNXCzn^V}R`64t34eFPn({A>oT?~oBt(tQbgX0(NEP1Qis{M$S%Coi?< zNYASiAi6L71KSrzn(5T$xix4)z@1>!O?U+%6_}(8xYqhH5-?{7HFR&B?#@$Q{KpnI zKKZ%&HWxbwN|qK`Wu7IzH^3)wxz=o839ie&3|SfA%O4@RUH=3+0P<+Fa%?p&(S6p5HXEfue?~ML!gYv1CM{!h##39a9wUYbT^V9#W=Vd zjqXXxq>gm{-4O6R$}Y$xl+el2CDO*o;QZuuG{~AP;f9t8vx2I|0#A=Z8mhI+%JK7 zv%!{*nlM@y`%~O_xrKif@gLYYWu75cB$x3In%NTXgQ?cbnHUk;q#FaaM_ico8Auuc zA|iz_1&x2W!gsbOrddy42lGcAdP*G9eJjUFpg1o{N`;R-SvGl6&8iHN&}+f-{ShcMAKrlg*`bwzr~Fnm#V@S(Y~w;~nEtgX``hD*d#t71ls7 zC}L6O;jjxmQb3iZ(wu8b_mhyxYTFLgl==&MFW8O5w_sE2-7sb0_u^hZFS4r`J-jSC z(#%6!3fCpkhi%dob-Wf67rP{um6tReD8ilU#}{)LUaN;cl)q9vJeJ2%GCqasNu1=E zFC7||@PGwE#Hzt@q@G* z$}B-oBHjz1hB;$)cb;?RiWk@Q^z{Qh?1+lJpB6bPUCC#C9N^|^puu-0h|C2doW6zm za47UUv1=C6b3*c#WfNxYR;;J}F6&oxFaqQ7&03)#eA!Ml5(LYk=I9!}DL?+FB9!mM z$k~pg{h!TOwFhGG#Js*w4xe{E5cV9L_eu57?YcYztF>& z>xyDBz>>DlIxcApjQl7RK+%kmb% zEN1;NbUZ^&wHE5n!+mGhW~5i7<-Yky1ot;SS@=DKifyGq4t+Nxm?K~SlV%T3wQTj^ z9v;+(Yo+C6|MGN+!}C8w8~`(+kixu{X3b3t;}sm#m`E!Q7kU~pCc!4*oC@yFbl26m zsB_#D;Shv$5k{S)J2SfT(xa4!V$Bnnn@mJoO*8(77Im8mxbH55Hzj;raAI7j+eM{E zzv9!;x5WwVfuJ_MfG>ap&B+0THtk@Qm@x+b2GmZ&G7ukCa$l%!%&2a#JZa8FCR*X{ zgFxSB;-0B$!hM-{Tt>)TN(YG=@8xM-rGA1mdbJ^%J;FIS6`6X7n_v9WR8z51vdhNL;+{iRoS%MCCb3 znH3|=2PKCZ19@1^3}>^uN)|WQ)fcSa;J{~!L}E+t^l^}So<~l}bQ%Ag>v>naxA_IN zIzRz1#%a-EuKp0{-4;~_&<^m>+g4u*mzE_d)>)M%5@Q=R6z&%99Ea&R(u%lTMQWW6 zR=G5bDpQxLZ)%JMvb+I2QiVvLjV=x()ZuN`hq>#cP?fo*Le>#r(J>&q?@JCQKy9q) zo8WH0a8N!YjXf3lPKAQUR&IdiEW+;wgAJR5K92WsN}MB;y^_{Kx|fKei#Wq+pYRJb zwQa(C4WLrvruUf`<%XH8f=L~;^s0x4oubZj+0a&}Q z9Mtqvnph?KE}Cepz}85{^cs{ko$AtXeclzQ9X=9V*6)#d>2PSA4lXJwiHrE-f81q<%l9;mLunql|UlQ<=sGO>ATF@%T|&%A>i3 z$?ULX<5z;zB!bDBV!;;#SLeElxXEuQx0Qiq+LCI{>&G;7snhOof}mJiIS>~F4d)A) znDTdLzOR%xS8SMv?%}lJxYxL=KRz1TM8dmjECExPgqgOiF@K46?oJStjK1@_fZXU7 z^;sMy9Oz_u?x=^6hmsDy{n=Q_-l@QlK(fL8o0>7yqY*T}{XYhVpdEKoa@P#utwFsrYmt|0uB_8V2R=H! zy+)xg)unUsvT1DmeSc8w#8YPVW;@H{U5x^fpK`u&8RbSn(PYipHIBg=ytTB0m9j)j z-GJX#h>i*WVVHQn>g}=o1{*OsTla5x+#%faci+rMGF{ulqx~ChK%C)X`)KI-O?^*p zr&ayq*0XRMX_MKUbAMD{%OufcQMiHRWxnbc5;L?}1Da-k{^JlI!XwjxEJPVVk_R4E z8b9m(87f`Uo%;K!{VCmNrYJw!j;HNMor37g_#HgFnU{(P@rPr?0&tjB%H(&2Kixi! zh7Zc9o_YxGyc`z!?B&K1>q0uu^aJLVl)_CPa#v})am=KtJi5+IS019RHJK*?|4w(354osx+97tnp}{T`*D_@X@o zneN}0rfL}3%o8tc-Yt}GpP2^d?|+nAkE~J}ZEFN8xnos|!8ApY+z+dVf}Qf4KwcSnO)?v&F2@AkP)OeRSaqTOLX?1wk6rS>9-Bg7(Vr&M*rm`-9> zI1DZ@;kJEj<+j~m)Ao7_V)k9%H`(H(VJ#>hs#CC?c=V>oa)(?fohCb@@3d3RZ-xGP zQ2x@wEH&q+uU2>JQD5O;HOX^QgI7Et=bf2_*ueWv*4RT~(GtrgR})p?FgcN3r+hDT zu#N1=lb(D|dpE~>y@SgUQyfNd-vUDN<~6);JoEII(A*4u{wc?4BkFiYoSPHM?PwQX z(Kw&KFiE^%l+p_Jb*%GiHhTeR_n#?xAITw+;${cpKJ0?UlW zPqri0N;HEDsYsL0)!SGl`BWFrp1M2OF0ct`uaq4QqT@2|l6Sk$UxsPsecohET@H{z z&jV>?og0~J=xvw6z&U~AWS-Mm)nDhH>Vylx-rN6GgB>G1Y|JGCo^392>jWo{Xb~|U z%PGRWu6HZ%t>koZ^@L;xzc8olyfUKN=m$;irG86`JzB0BZQgiLHl|r{{OEg2y$&Sy zDpRtql)2=GP=ay1*XGiy?X^d5lTz*^^hcE>~eDlnws|iumkDpnFW!O1*2(ihN zhIA}_y!s@HjN$+?jS>BZzp$4r=F?`bCXHmdePYh1?G2qQ)!~YxMfBG%+HR99$qnyt zPJb-Yk7mAwMskEvQ7zT}#$uHo8L2{9+2A;NGF<*w&KX)fq2Pcz|IAOaqnEGe z9&S#$(nJM&=sho;?roEUW0B4F@kZwmH%3Ce@`>4z?wnwVVMV=nd0{vs?jK06H0&8% zcNIax-#f6$H2>~kQT=N`vmVf%u`J18_4j3Q@!;%k8IaV038#~oS=Kx9^gzFz6WlW= zByFFplG->|k$h$R?Z=1PFD_fH5eo3RSu*X&yyyM5;AV6x0<54`qHLPAF-kdUy^gTc zIAbQvZUI(YPL8(*R0e;eqzMXNe(do3fh_jkKI=C)+a7wXnRM{OFvw?HSKo(P1_$?h z%ElGOy(!t5Pz04XjZi1ZU&nr=Rf%h3Vjk)`> zK5_lQKrf37Y%q9N>&#avzToK3ZM$sOpKpG>!nH53{7J`*eqM(KTa))QdhZ0%s3NC8 z#QH*I9ZjyYU*dX#I1K2#?srfgaMUn*_EiPXsZ`sT^~%fliJD=WFYwnyR0eAV93&yH zTG_db0lq^g{{rX}$V~A4+kFp1yG7)C9SyzN)qD7(Kob-Ttm+}=As^a9HuepZOIS0C zpHH;%c@Aq(q0LQ$^m$p8*5C*_D=4@9<=K3ZyQq2?r3hP-Vajo~=k8u$C5!ryWu%(4 zwR={@TL^SJumOQWH}=R#W~=s}Nbi>sEru7NTCSv%e#>S$jO8JIecf=eqB&aW$t%2E1%> zT|R^XiSCJ=#*|WBf-|WWZO{~yq2d$WGlOHTRp3WT3t_jvgaz;iy9A5I6P$+qVsyn{ zX=KH1?9#Ol{4js>WmT`=aKj`j7(HyC_qkSCw=5{;>8?j* z9a@q&k}tWru$od8!@GP8DO5p8?_3LpLPPc=)#Is zuFI~2uKQ1g`^=v9Nb5gJBOR94i1SDiqqAduW1aV^u1=b0uTZYZD9&^&ODG&1DG2Hu z%xaMYgeI7)*K@C?7sURleP|}I3_orAeORSRR-H#H$9ODKz89gqOWXl6!JtDLvv|4g? zZ(&58GjS_Ni-=!F#ZilPadT$7&7oP?v z6#v3r9X6Bx`O(-(O{h#zc57QrFt~cxMz2h$_X<$Zw|73CBu6L;dd?v+pujzlv)K** z#ZH9#8X`RQ^O7EdBbJ(Hjh}rODJYsB@V!VSfxGJp_%d#G+=!roIrsnq$6L8JkVpsq zPvkS$!X2|C8qov_ogo25-Bwfld-P2k5^(Ka0f3$7g!@kM*&m^m7ko+2e$lsPvY2D1 zqPQJU&0?38e*xex=mU>azSY`2RTm9>1RKqabYg`9I=1<&VbOs+Sf-m@$zprdtwnDb zC3+%m?$!ba8e&+~XbnJM8rOQ@UWOc9azVu@UJ|o~IY$QivkIQJM4eu`1dmbJ zmRM@tryMyU+0=)OT9x-_BC%S#cSO#)2U%}rgd^iq#qQmFw<+@_uf&`n`8|rQf26#o z!*-bs{v30*n!sOBNMbYTYtq{Sg~Z9*=gyX8wt3G?Y56N){wZI4*d5MooW(!RLn6;r82u8&pj^^r$4Yxhi{uW==|CjTPaysh%^keD}4 zXv@8yvwrn@vASKH+TWnkEy)sXvZ9nZs`M&)p|KdPkHroaC^L)4Xbaoc`V{5772RW^ z(+l56v=$)b&P4=1oWAb^8~OCP@O0c2;8CvnVL}u!&6P98AmKqw*%N^+W(F6InwRRl Mo83&*{>RewKTj0~{r~^~ literal 0 HcmV?d00001 diff --git a/dat/cache/difffile-large/0/CacheHandler0_0.dn b/dat/cache/difffile-large/0/CacheHandler0_0.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_1.dn b/dat/cache/difffile-large/0/CacheHandler0_1.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_10.dn b/dat/cache/difffile-large/0/CacheHandler0_10.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_11.dn b/dat/cache/difffile-large/0/CacheHandler0_11.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_12.dn b/dat/cache/difffile-large/0/CacheHandler0_12.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_13.dn b/dat/cache/difffile-large/0/CacheHandler0_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_14.dn b/dat/cache/difffile-large/0/CacheHandler0_14.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_15.dn b/dat/cache/difffile-large/0/CacheHandler0_15.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_16.dn b/dat/cache/difffile-large/0/CacheHandler0_16.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_17.dn b/dat/cache/difffile-large/0/CacheHandler0_17.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_18.dn b/dat/cache/difffile-large/0/CacheHandler0_18.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_19.dn b/dat/cache/difffile-large/0/CacheHandler0_19.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_2.dn b/dat/cache/difffile-large/0/CacheHandler0_2.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_20.dn b/dat/cache/difffile-large/0/CacheHandler0_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_21.dn b/dat/cache/difffile-large/0/CacheHandler0_21.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_22.dn b/dat/cache/difffile-large/0/CacheHandler0_22.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_23.dn b/dat/cache/difffile-large/0/CacheHandler0_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_24.dn b/dat/cache/difffile-large/0/CacheHandler0_24.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_25.dn b/dat/cache/difffile-large/0/CacheHandler0_25.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_26.dn b/dat/cache/difffile-large/0/CacheHandler0_26.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_27.dn b/dat/cache/difffile-large/0/CacheHandler0_27.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_28.dn b/dat/cache/difffile-large/0/CacheHandler0_28.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_29.dn b/dat/cache/difffile-large/0/CacheHandler0_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_3.dn b/dat/cache/difffile-large/0/CacheHandler0_3.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_30.dn b/dat/cache/difffile-large/0/CacheHandler0_30.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_31.dn b/dat/cache/difffile-large/0/CacheHandler0_31.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_32.dn b/dat/cache/difffile-large/0/CacheHandler0_32.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_33.dn b/dat/cache/difffile-large/0/CacheHandler0_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_34.dn b/dat/cache/difffile-large/0/CacheHandler0_34.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_4.dn b/dat/cache/difffile-large/0/CacheHandler0_4.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_5.dn b/dat/cache/difffile-large/0/CacheHandler0_5.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_6.dn b/dat/cache/difffile-large/0/CacheHandler0_6.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_7.dn b/dat/cache/difffile-large/0/CacheHandler0_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_8.dn b/dat/cache/difffile-large/0/CacheHandler0_8.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/0/CacheHandler0_9.dn b/dat/cache/difffile-large/0/CacheHandler0_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/0/CacheHandler0_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_0.dn b/dat/cache/difffile-large/1/CacheHandler1_0.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_1.dn b/dat/cache/difffile-large/1/CacheHandler1_1.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_10.dn b/dat/cache/difffile-large/1/CacheHandler1_10.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_11.dn b/dat/cache/difffile-large/1/CacheHandler1_11.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_12.dn b/dat/cache/difffile-large/1/CacheHandler1_12.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_13.dn b/dat/cache/difffile-large/1/CacheHandler1_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_14.dn b/dat/cache/difffile-large/1/CacheHandler1_14.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_15.dn b/dat/cache/difffile-large/1/CacheHandler1_15.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_16.dn b/dat/cache/difffile-large/1/CacheHandler1_16.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_17.dn b/dat/cache/difffile-large/1/CacheHandler1_17.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_18.dn b/dat/cache/difffile-large/1/CacheHandler1_18.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_19.dn b/dat/cache/difffile-large/1/CacheHandler1_19.dn new file mode 100644 index 0000000..7168f0c --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*4 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_2.dn b/dat/cache/difffile-large/1/CacheHandler1_2.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_20.dn b/dat/cache/difffile-large/1/CacheHandler1_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_21.dn b/dat/cache/difffile-large/1/CacheHandler1_21.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_22.dn b/dat/cache/difffile-large/1/CacheHandler1_22.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_23.dn b/dat/cache/difffile-large/1/CacheHandler1_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_24.dn b/dat/cache/difffile-large/1/CacheHandler1_24.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_25.dn b/dat/cache/difffile-large/1/CacheHandler1_25.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_26.dn b/dat/cache/difffile-large/1/CacheHandler1_26.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_27.dn b/dat/cache/difffile-large/1/CacheHandler1_27.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_28.dn b/dat/cache/difffile-large/1/CacheHandler1_28.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_29.dn b/dat/cache/difffile-large/1/CacheHandler1_29.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_3.dn b/dat/cache/difffile-large/1/CacheHandler1_3.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_30.dn b/dat/cache/difffile-large/1/CacheHandler1_30.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_31.dn b/dat/cache/difffile-large/1/CacheHandler1_31.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_32.dn b/dat/cache/difffile-large/1/CacheHandler1_32.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_33.dn b/dat/cache/difffile-large/1/CacheHandler1_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_34.dn b/dat/cache/difffile-large/1/CacheHandler1_34.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_4.dn b/dat/cache/difffile-large/1/CacheHandler1_4.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_5.dn b/dat/cache/difffile-large/1/CacheHandler1_5.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_6.dn b/dat/cache/difffile-large/1/CacheHandler1_6.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_7.dn b/dat/cache/difffile-large/1/CacheHandler1_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_8.dn b/dat/cache/difffile-large/1/CacheHandler1_8.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/1/CacheHandler1_9.dn b/dat/cache/difffile-large/1/CacheHandler1_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/1/CacheHandler1_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_0.dn b/dat/cache/difffile-large/10/CacheHandler10_0.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_1.dn b/dat/cache/difffile-large/10/CacheHandler10_1.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_10.dn b/dat/cache/difffile-large/10/CacheHandler10_10.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_11.dn b/dat/cache/difffile-large/10/CacheHandler10_11.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_12.dn b/dat/cache/difffile-large/10/CacheHandler10_12.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_13.dn b/dat/cache/difffile-large/10/CacheHandler10_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_14.dn b/dat/cache/difffile-large/10/CacheHandler10_14.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_15.dn b/dat/cache/difffile-large/10/CacheHandler10_15.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_16.dn b/dat/cache/difffile-large/10/CacheHandler10_16.dn new file mode 100644 index 0000000..8ed43fc --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)/19 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_17.dn b/dat/cache/difffile-large/10/CacheHandler10_17.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_18.dn b/dat/cache/difffile-large/10/CacheHandler10_18.dn new file mode 100644 index 0000000..cde4f6e --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_19.dn b/dat/cache/difffile-large/10/CacheHandler10_19.dn new file mode 100644 index 0000000..627cd48 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 12-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_2.dn b/dat/cache/difffile-large/10/CacheHandler10_2.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_20.dn b/dat/cache/difffile-large/10/CacheHandler10_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_21.dn b/dat/cache/difffile-large/10/CacheHandler10_21.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_22.dn b/dat/cache/difffile-large/10/CacheHandler10_22.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_23.dn b/dat/cache/difffile-large/10/CacheHandler10_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_24.dn b/dat/cache/difffile-large/10/CacheHandler10_24.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_25.dn b/dat/cache/difffile-large/10/CacheHandler10_25.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_26.dn b/dat/cache/difffile-large/10/CacheHandler10_26.dn new file mode 100644 index 0000000..0726947 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-2 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_27.dn b/dat/cache/difffile-large/10/CacheHandler10_27.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_28.dn b/dat/cache/difffile-large/10/CacheHandler10_28.dn new file mode 100644 index 0000000..fd826ac --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_29.dn b/dat/cache/difffile-large/10/CacheHandler10_29.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_3.dn b/dat/cache/difffile-large/10/CacheHandler10_3.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_30.dn b/dat/cache/difffile-large/10/CacheHandler10_30.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_31.dn b/dat/cache/difffile-large/10/CacheHandler10_31.dn new file mode 100644 index 0000000..88d4397 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/random() + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_32.dn b/dat/cache/difffile-large/10/CacheHandler10_32.dn new file mode 100644 index 0000000..e0999a5 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_33.dn b/dat/cache/difffile-large/10/CacheHandler10_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_34.dn b/dat/cache/difffile-large/10/CacheHandler10_34.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_4.dn b/dat/cache/difffile-large/10/CacheHandler10_4.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_5.dn b/dat/cache/difffile-large/10/CacheHandler10_5.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_6.dn b/dat/cache/difffile-large/10/CacheHandler10_6.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_7.dn b/dat/cache/difffile-large/10/CacheHandler10_7.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_8.dn b/dat/cache/difffile-large/10/CacheHandler10_8.dn new file mode 100644 index 0000000..07667c8 --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+2 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/10/CacheHandler10_9.dn b/dat/cache/difffile-large/10/CacheHandler10_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/10/CacheHandler10_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_0.dn b/dat/cache/difffile-large/11/CacheHandler11_0.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_1.dn b/dat/cache/difffile-large/11/CacheHandler11_1.dn new file mode 100644 index 0000000..627cd48 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 12-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_10.dn b/dat/cache/difffile-large/11/CacheHandler11_10.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_11.dn b/dat/cache/difffile-large/11/CacheHandler11_11.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_12.dn b/dat/cache/difffile-large/11/CacheHandler11_12.dn new file mode 100644 index 0000000..07667c8 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+2 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_13.dn b/dat/cache/difffile-large/11/CacheHandler11_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_14.dn b/dat/cache/difffile-large/11/CacheHandler11_14.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_15.dn b/dat/cache/difffile-large/11/CacheHandler11_15.dn new file mode 100644 index 0000000..e0999a5 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_16.dn b/dat/cache/difffile-large/11/CacheHandler11_16.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_17.dn b/dat/cache/difffile-large/11/CacheHandler11_17.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_18.dn b/dat/cache/difffile-large/11/CacheHandler11_18.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_19.dn b/dat/cache/difffile-large/11/CacheHandler11_19.dn new file mode 100644 index 0000000..8ed43fc --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)/19 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_2.dn b/dat/cache/difffile-large/11/CacheHandler11_2.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_20.dn b/dat/cache/difffile-large/11/CacheHandler11_20.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_21.dn b/dat/cache/difffile-large/11/CacheHandler11_21.dn new file mode 100644 index 0000000..b5d7024 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_22.dn b/dat/cache/difffile-large/11/CacheHandler11_22.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_23.dn b/dat/cache/difffile-large/11/CacheHandler11_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_24.dn b/dat/cache/difffile-large/11/CacheHandler11_24.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_25.dn b/dat/cache/difffile-large/11/CacheHandler11_25.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_26.dn b/dat/cache/difffile-large/11/CacheHandler11_26.dn new file mode 100644 index 0000000..dea93f4 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_27.dn b/dat/cache/difffile-large/11/CacheHandler11_27.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_28.dn b/dat/cache/difffile-large/11/CacheHandler11_28.dn new file mode 100644 index 0000000..fd826ac --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_29.dn b/dat/cache/difffile-large/11/CacheHandler11_29.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_3.dn b/dat/cache/difffile-large/11/CacheHandler11_3.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_30.dn b/dat/cache/difffile-large/11/CacheHandler11_30.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_31.dn b/dat/cache/difffile-large/11/CacheHandler11_31.dn new file mode 100644 index 0000000..88d4397 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/random() + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_32.dn b/dat/cache/difffile-large/11/CacheHandler11_32.dn new file mode 100644 index 0000000..e0999a5 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_33.dn b/dat/cache/difffile-large/11/CacheHandler11_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_34.dn b/dat/cache/difffile-large/11/CacheHandler11_34.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_4.dn b/dat/cache/difffile-large/11/CacheHandler11_4.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_5.dn b/dat/cache/difffile-large/11/CacheHandler11_5.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_6.dn b/dat/cache/difffile-large/11/CacheHandler11_6.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_7.dn b/dat/cache/difffile-large/11/CacheHandler11_7.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_8.dn b/dat/cache/difffile-large/11/CacheHandler11_8.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/11/CacheHandler11_9.dn b/dat/cache/difffile-large/11/CacheHandler11_9.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/11/CacheHandler11_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_0.dn b/dat/cache/difffile-large/12/CacheHandler12_0.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_1.dn b/dat/cache/difffile-large/12/CacheHandler12_1.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_10.dn b/dat/cache/difffile-large/12/CacheHandler12_10.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_11.dn b/dat/cache/difffile-large/12/CacheHandler12_11.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_12.dn b/dat/cache/difffile-large/12/CacheHandler12_12.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_13.dn b/dat/cache/difffile-large/12/CacheHandler12_13.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_14.dn b/dat/cache/difffile-large/12/CacheHandler12_14.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_15.dn b/dat/cache/difffile-large/12/CacheHandler12_15.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_16.dn b/dat/cache/difffile-large/12/CacheHandler12_16.dn new file mode 100644 index 0000000..451c75e --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 14-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_17.dn b/dat/cache/difffile-large/12/CacheHandler12_17.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_18.dn b/dat/cache/difffile-large/12/CacheHandler12_18.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_19.dn b/dat/cache/difffile-large/12/CacheHandler12_19.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_2.dn b/dat/cache/difffile-large/12/CacheHandler12_2.dn new file mode 100644 index 0000000..627cd48 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 12-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_20.dn b/dat/cache/difffile-large/12/CacheHandler12_20.dn new file mode 100644 index 0000000..9334046 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*13 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_21.dn b/dat/cache/difffile-large/12/CacheHandler12_21.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_22.dn b/dat/cache/difffile-large/12/CacheHandler12_22.dn new file mode 100644 index 0000000..b5d7024 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_23.dn b/dat/cache/difffile-large/12/CacheHandler12_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_24.dn b/dat/cache/difffile-large/12/CacheHandler12_24.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_25.dn b/dat/cache/difffile-large/12/CacheHandler12_25.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_26.dn b/dat/cache/difffile-large/12/CacheHandler12_26.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_27.dn b/dat/cache/difffile-large/12/CacheHandler12_27.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_28.dn b/dat/cache/difffile-large/12/CacheHandler12_28.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_29.dn b/dat/cache/difffile-large/12/CacheHandler12_29.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_3.dn b/dat/cache/difffile-large/12/CacheHandler12_3.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_30.dn b/dat/cache/difffile-large/12/CacheHandler12_30.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_31.dn b/dat/cache/difffile-large/12/CacheHandler12_31.dn new file mode 100644 index 0000000..fcc56ef --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 11/random() + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_32.dn b/dat/cache/difffile-large/12/CacheHandler12_32.dn new file mode 100644 index 0000000..e0999a5 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_33.dn b/dat/cache/difffile-large/12/CacheHandler12_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_34.dn b/dat/cache/difffile-large/12/CacheHandler12_34.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_4.dn b/dat/cache/difffile-large/12/CacheHandler12_4.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_5.dn b/dat/cache/difffile-large/12/CacheHandler12_5.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_6.dn b/dat/cache/difffile-large/12/CacheHandler12_6.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_7.dn b/dat/cache/difffile-large/12/CacheHandler12_7.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_8.dn b/dat/cache/difffile-large/12/CacheHandler12_8.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/12/CacheHandler12_9.dn b/dat/cache/difffile-large/12/CacheHandler12_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/12/CacheHandler12_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_0.dn b/dat/cache/difffile-large/13/CacheHandler13_0.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_1.dn b/dat/cache/difffile-large/13/CacheHandler13_1.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_10.dn b/dat/cache/difffile-large/13/CacheHandler13_10.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_11.dn b/dat/cache/difffile-large/13/CacheHandler13_11.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_12.dn b/dat/cache/difffile-large/13/CacheHandler13_12.dn new file mode 100644 index 0000000..0f6afab --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_13.dn b/dat/cache/difffile-large/13/CacheHandler13_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_14.dn b/dat/cache/difffile-large/13/CacheHandler13_14.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_15.dn b/dat/cache/difffile-large/13/CacheHandler13_15.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_16.dn b/dat/cache/difffile-large/13/CacheHandler13_16.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_17.dn b/dat/cache/difffile-large/13/CacheHandler13_17.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_18.dn b/dat/cache/difffile-large/13/CacheHandler13_18.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_19.dn b/dat/cache/difffile-large/13/CacheHandler13_19.dn new file mode 100644 index 0000000..451c75e --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 14-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_2.dn b/dat/cache/difffile-large/13/CacheHandler13_2.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_20.dn b/dat/cache/difffile-large/13/CacheHandler13_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_21.dn b/dat/cache/difffile-large/13/CacheHandler13_21.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_22.dn b/dat/cache/difffile-large/13/CacheHandler13_22.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_23.dn b/dat/cache/difffile-large/13/CacheHandler13_23.dn new file mode 100644 index 0000000..9334046 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*13 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_24.dn b/dat/cache/difffile-large/13/CacheHandler13_24.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_25.dn b/dat/cache/difffile-large/13/CacheHandler13_25.dn new file mode 100644 index 0000000..b5d7024 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_26.dn b/dat/cache/difffile-large/13/CacheHandler13_26.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_27.dn b/dat/cache/difffile-large/13/CacheHandler13_27.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_28.dn b/dat/cache/difffile-large/13/CacheHandler13_28.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_29.dn b/dat/cache/difffile-large/13/CacheHandler13_29.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_3.dn b/dat/cache/difffile-large/13/CacheHandler13_3.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_30.dn b/dat/cache/difffile-large/13/CacheHandler13_30.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_31.dn b/dat/cache/difffile-large/13/CacheHandler13_31.dn new file mode 100644 index 0000000..fcc56ef --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 11/random() + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_32.dn b/dat/cache/difffile-large/13/CacheHandler13_32.dn new file mode 100644 index 0000000..e0999a5 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_33.dn b/dat/cache/difffile-large/13/CacheHandler13_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_34.dn b/dat/cache/difffile-large/13/CacheHandler13_34.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_4.dn b/dat/cache/difffile-large/13/CacheHandler13_4.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_5.dn b/dat/cache/difffile-large/13/CacheHandler13_5.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_6.dn b/dat/cache/difffile-large/13/CacheHandler13_6.dn new file mode 100644 index 0000000..627cd48 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 12-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_7.dn b/dat/cache/difffile-large/13/CacheHandler13_7.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_8.dn b/dat/cache/difffile-large/13/CacheHandler13_8.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/13/CacheHandler13_9.dn b/dat/cache/difffile-large/13/CacheHandler13_9.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/13/CacheHandler13_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_0.dn b/dat/cache/difffile-large/14/CacheHandler14_0.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_1.dn b/dat/cache/difffile-large/14/CacheHandler14_1.dn new file mode 100644 index 0000000..e0999a5 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_10.dn b/dat/cache/difffile-large/14/CacheHandler14_10.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_11.dn b/dat/cache/difffile-large/14/CacheHandler14_11.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_12.dn b/dat/cache/difffile-large/14/CacheHandler14_12.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_13.dn b/dat/cache/difffile-large/14/CacheHandler14_13.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_14.dn b/dat/cache/difffile-large/14/CacheHandler14_14.dn new file mode 100644 index 0000000..0f6afab --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_15.dn b/dat/cache/difffile-large/14/CacheHandler14_15.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_16.dn b/dat/cache/difffile-large/14/CacheHandler14_16.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_17.dn b/dat/cache/difffile-large/14/CacheHandler14_17.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_18.dn b/dat/cache/difffile-large/14/CacheHandler14_18.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_19.dn b/dat/cache/difffile-large/14/CacheHandler14_19.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_2.dn b/dat/cache/difffile-large/14/CacheHandler14_2.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_20.dn b/dat/cache/difffile-large/14/CacheHandler14_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_21.dn b/dat/cache/difffile-large/14/CacheHandler14_21.dn new file mode 100644 index 0000000..451c75e --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 14-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_22.dn b/dat/cache/difffile-large/14/CacheHandler14_22.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_23.dn b/dat/cache/difffile-large/14/CacheHandler14_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_24.dn b/dat/cache/difffile-large/14/CacheHandler14_24.dn new file mode 100644 index 0000000..9334046 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*13 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_25.dn b/dat/cache/difffile-large/14/CacheHandler14_25.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_26.dn b/dat/cache/difffile-large/14/CacheHandler14_26.dn new file mode 100644 index 0000000..b5d7024 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_27.dn b/dat/cache/difffile-large/14/CacheHandler14_27.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_28.dn b/dat/cache/difffile-large/14/CacheHandler14_28.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_29.dn b/dat/cache/difffile-large/14/CacheHandler14_29.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_3.dn b/dat/cache/difffile-large/14/CacheHandler14_3.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_30.dn b/dat/cache/difffile-large/14/CacheHandler14_30.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_31.dn b/dat/cache/difffile-large/14/CacheHandler14_31.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_32.dn b/dat/cache/difffile-large/14/CacheHandler14_32.dn new file mode 100644 index 0000000..fcc56ef --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 11/random() + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_33.dn b/dat/cache/difffile-large/14/CacheHandler14_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_34.dn b/dat/cache/difffile-large/14/CacheHandler14_34.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_4.dn b/dat/cache/difffile-large/14/CacheHandler14_4.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_5.dn b/dat/cache/difffile-large/14/CacheHandler14_5.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_6.dn b/dat/cache/difffile-large/14/CacheHandler14_6.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_7.dn b/dat/cache/difffile-large/14/CacheHandler14_7.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_8.dn b/dat/cache/difffile-large/14/CacheHandler14_8.dn new file mode 100644 index 0000000..04b26cb --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 8+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/14/CacheHandler14_9.dn b/dat/cache/difffile-large/14/CacheHandler14_9.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/14/CacheHandler14_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_0.dn b/dat/cache/difffile-large/15/CacheHandler15_0.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_1.dn b/dat/cache/difffile-large/15/CacheHandler15_1.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_10.dn b/dat/cache/difffile-large/15/CacheHandler15_10.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_11.dn b/dat/cache/difffile-large/15/CacheHandler15_11.dn new file mode 100644 index 0000000..1a417c7 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_12.dn b/dat/cache/difffile-large/15/CacheHandler15_12.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_13.dn b/dat/cache/difffile-large/15/CacheHandler15_13.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_14.dn b/dat/cache/difffile-large/15/CacheHandler15_14.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_15.dn b/dat/cache/difffile-large/15/CacheHandler15_15.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_16.dn b/dat/cache/difffile-large/15/CacheHandler15_16.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_17.dn b/dat/cache/difffile-large/15/CacheHandler15_17.dn new file mode 100644 index 0000000..0f6afab --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_18.dn b/dat/cache/difffile-large/15/CacheHandler15_18.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_19.dn b/dat/cache/difffile-large/15/CacheHandler15_19.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_2.dn b/dat/cache/difffile-large/15/CacheHandler15_2.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_20.dn b/dat/cache/difffile-large/15/CacheHandler15_20.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_21.dn b/dat/cache/difffile-large/15/CacheHandler15_21.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_22.dn b/dat/cache/difffile-large/15/CacheHandler15_22.dn new file mode 100644 index 0000000..adb6367 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_23.dn b/dat/cache/difffile-large/15/CacheHandler15_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_24.dn b/dat/cache/difffile-large/15/CacheHandler15_24.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_25.dn b/dat/cache/difffile-large/15/CacheHandler15_25.dn new file mode 100644 index 0000000..9334046 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*13 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_26.dn b/dat/cache/difffile-large/15/CacheHandler15_26.dn new file mode 100644 index 0000000..2e8d0c2 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 19*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_27.dn b/dat/cache/difffile-large/15/CacheHandler15_27.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_28.dn b/dat/cache/difffile-large/15/CacheHandler15_28.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_29.dn b/dat/cache/difffile-large/15/CacheHandler15_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_3.dn b/dat/cache/difffile-large/15/CacheHandler15_3.dn new file mode 100644 index 0000000..e0999a5 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_30.dn b/dat/cache/difffile-large/15/CacheHandler15_30.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_31.dn b/dat/cache/difffile-large/15/CacheHandler15_31.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_32.dn b/dat/cache/difffile-large/15/CacheHandler15_32.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_33.dn b/dat/cache/difffile-large/15/CacheHandler15_33.dn new file mode 100644 index 0000000..fcc56ef --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 11/random() + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_34.dn b/dat/cache/difffile-large/15/CacheHandler15_34.dn new file mode 100644 index 0000000..0f6afab --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_4.dn b/dat/cache/difffile-large/15/CacheHandler15_4.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_5.dn b/dat/cache/difffile-large/15/CacheHandler15_5.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_6.dn b/dat/cache/difffile-large/15/CacheHandler15_6.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_7.dn b/dat/cache/difffile-large/15/CacheHandler15_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_8.dn b/dat/cache/difffile-large/15/CacheHandler15_8.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/15/CacheHandler15_9.dn b/dat/cache/difffile-large/15/CacheHandler15_9.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/15/CacheHandler15_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_0.dn b/dat/cache/difffile-large/16/CacheHandler16_0.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_1.dn b/dat/cache/difffile-large/16/CacheHandler16_1.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_10.dn b/dat/cache/difffile-large/16/CacheHandler16_10.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_11.dn b/dat/cache/difffile-large/16/CacheHandler16_11.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_12.dn b/dat/cache/difffile-large/16/CacheHandler16_12.dn new file mode 100644 index 0000000..1a417c7 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_13.dn b/dat/cache/difffile-large/16/CacheHandler16_13.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_14.dn b/dat/cache/difffile-large/16/CacheHandler16_14.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_15.dn b/dat/cache/difffile-large/16/CacheHandler16_15.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_16.dn b/dat/cache/difffile-large/16/CacheHandler16_16.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_17.dn b/dat/cache/difffile-large/16/CacheHandler16_17.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_18.dn b/dat/cache/difffile-large/16/CacheHandler16_18.dn new file mode 100644 index 0000000..0f6afab --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_19.dn b/dat/cache/difffile-large/16/CacheHandler16_19.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_2.dn b/dat/cache/difffile-large/16/CacheHandler16_2.dn new file mode 100644 index 0000000..e0999a5 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_20.dn b/dat/cache/difffile-large/16/CacheHandler16_20.dn new file mode 100644 index 0000000..541b5f2 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_21.dn b/dat/cache/difffile-large/16/CacheHandler16_21.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_22.dn b/dat/cache/difffile-large/16/CacheHandler16_22.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_23.dn b/dat/cache/difffile-large/16/CacheHandler16_23.dn new file mode 100644 index 0000000..adb6367 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_24.dn b/dat/cache/difffile-large/16/CacheHandler16_24.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_25.dn b/dat/cache/difffile-large/16/CacheHandler16_25.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_26.dn b/dat/cache/difffile-large/16/CacheHandler16_26.dn new file mode 100644 index 0000000..9334046 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*13 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_27.dn b/dat/cache/difffile-large/16/CacheHandler16_27.dn new file mode 100644 index 0000000..2e8d0c2 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 19*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_28.dn b/dat/cache/difffile-large/16/CacheHandler16_28.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_29.dn b/dat/cache/difffile-large/16/CacheHandler16_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_3.dn b/dat/cache/difffile-large/16/CacheHandler16_3.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_30.dn b/dat/cache/difffile-large/16/CacheHandler16_30.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_31.dn b/dat/cache/difffile-large/16/CacheHandler16_31.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_32.dn b/dat/cache/difffile-large/16/CacheHandler16_32.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_33.dn b/dat/cache/difffile-large/16/CacheHandler16_33.dn new file mode 100644 index 0000000..fcc56ef --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 11/random() + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_34.dn b/dat/cache/difffile-large/16/CacheHandler16_34.dn new file mode 100644 index 0000000..b437d79 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_4.dn b/dat/cache/difffile-large/16/CacheHandler16_4.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_5.dn b/dat/cache/difffile-large/16/CacheHandler16_5.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_6.dn b/dat/cache/difffile-large/16/CacheHandler16_6.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_7.dn b/dat/cache/difffile-large/16/CacheHandler16_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_8.dn b/dat/cache/difffile-large/16/CacheHandler16_8.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/16/CacheHandler16_9.dn b/dat/cache/difffile-large/16/CacheHandler16_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/16/CacheHandler16_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_0.dn b/dat/cache/difffile-large/17/CacheHandler17_0.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_1.dn b/dat/cache/difffile-large/17/CacheHandler17_1.dn new file mode 100644 index 0000000..e0999a5 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_10.dn b/dat/cache/difffile-large/17/CacheHandler17_10.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_11.dn b/dat/cache/difffile-large/17/CacheHandler17_11.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_12.dn b/dat/cache/difffile-large/17/CacheHandler17_12.dn new file mode 100644 index 0000000..1a417c7 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_13.dn b/dat/cache/difffile-large/17/CacheHandler17_13.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_14.dn b/dat/cache/difffile-large/17/CacheHandler17_14.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_15.dn b/dat/cache/difffile-large/17/CacheHandler17_15.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_16.dn b/dat/cache/difffile-large/17/CacheHandler17_16.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_17.dn b/dat/cache/difffile-large/17/CacheHandler17_17.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_18.dn b/dat/cache/difffile-large/17/CacheHandler17_18.dn new file mode 100644 index 0000000..0f6afab --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_19.dn b/dat/cache/difffile-large/17/CacheHandler17_19.dn new file mode 100644 index 0000000..69c171f --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*3 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_2.dn b/dat/cache/difffile-large/17/CacheHandler17_2.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_20.dn b/dat/cache/difffile-large/17/CacheHandler17_20.dn new file mode 100644 index 0000000..adb6367 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_21.dn b/dat/cache/difffile-large/17/CacheHandler17_21.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_22.dn b/dat/cache/difffile-large/17/CacheHandler17_22.dn new file mode 100644 index 0000000..cde4f6e --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_23.dn b/dat/cache/difffile-large/17/CacheHandler17_23.dn new file mode 100644 index 0000000..adb6367 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)+nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_24.dn b/dat/cache/difffile-large/17/CacheHandler17_24.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_25.dn b/dat/cache/difffile-large/17/CacheHandler17_25.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_26.dn b/dat/cache/difffile-large/17/CacheHandler17_26.dn new file mode 100644 index 0000000..9334046 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*13 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_27.dn b/dat/cache/difffile-large/17/CacheHandler17_27.dn new file mode 100644 index 0000000..2e8d0c2 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 19*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_28.dn b/dat/cache/difffile-large/17/CacheHandler17_28.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_29.dn b/dat/cache/difffile-large/17/CacheHandler17_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_3.dn b/dat/cache/difffile-large/17/CacheHandler17_3.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_30.dn b/dat/cache/difffile-large/17/CacheHandler17_30.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_31.dn b/dat/cache/difffile-large/17/CacheHandler17_31.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_32.dn b/dat/cache/difffile-large/17/CacheHandler17_32.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_33.dn b/dat/cache/difffile-large/17/CacheHandler17_33.dn new file mode 100644 index 0000000..fcc56ef --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 11/random() + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_34.dn b/dat/cache/difffile-large/17/CacheHandler17_34.dn new file mode 100644 index 0000000..b437d79 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_4.dn b/dat/cache/difffile-large/17/CacheHandler17_4.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_5.dn b/dat/cache/difffile-large/17/CacheHandler17_5.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_6.dn b/dat/cache/difffile-large/17/CacheHandler17_6.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_7.dn b/dat/cache/difffile-large/17/CacheHandler17_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_8.dn b/dat/cache/difffile-large/17/CacheHandler17_8.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/CacheHandler17_9.dn b/dat/cache/difffile-large/17/CacheHandler17_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/17/CacheHandler17_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/17/chromosomes.txt b/dat/cache/difffile-large/17/chromosomes.txt new file mode 100644 index 0000000..5f712b9 --- /dev/null +++ b/dat/cache/difffile-large/17/chromosomes.txt @@ -0,0 +1,35 @@ +index = 0 +index = 0-nthMostFrequentlyUsed(0) +index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) +index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) +index = 0 +index = 0*nthMostRecentlyUsed(0) +index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) +index = 0 +index = 0-nthMostRecentlyUsed(0) +index = 0 +index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) +index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) +index = nthMostRecentlyUsed(0)+nthMostRecentlyUsed(0) +index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) +index = 0/nthMostRecentlyUsed(0) +index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) +index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) +index = 0-nthMostRecentlyUsed(0) +index = nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) +index = 0*3 +index = nthMostFrequentlyUsed(0)+nthMostFrequentlyUsed(0) +index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) +index = 0+nthMostRecentlyUsed(0) +index = nthMostFrequentlyUsed(0)+nthMostFrequentlyUsed(0) +index = 0 +index = 0 +index = nthMostRecentlyUsed(0)*13 +index = 19*nthMostRecentlyUsed(0) +index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) +index = 0 +index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) +index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) +index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) +index = 11/random() +index = nthMostRecentlyUsed(0)-nthMostRecentlyUsed(0) \ No newline at end of file diff --git a/dat/cache/difffile-large/2/CacheHandler2_0.dn b/dat/cache/difffile-large/2/CacheHandler2_0.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_1.dn b/dat/cache/difffile-large/2/CacheHandler2_1.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_10.dn b/dat/cache/difffile-large/2/CacheHandler2_10.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_11.dn b/dat/cache/difffile-large/2/CacheHandler2_11.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_12.dn b/dat/cache/difffile-large/2/CacheHandler2_12.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_13.dn b/dat/cache/difffile-large/2/CacheHandler2_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_14.dn b/dat/cache/difffile-large/2/CacheHandler2_14.dn new file mode 100644 index 0000000..b032ee0 --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+15 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_15.dn b/dat/cache/difffile-large/2/CacheHandler2_15.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_16.dn b/dat/cache/difffile-large/2/CacheHandler2_16.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_17.dn b/dat/cache/difffile-large/2/CacheHandler2_17.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_18.dn b/dat/cache/difffile-large/2/CacheHandler2_18.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_19.dn b/dat/cache/difffile-large/2/CacheHandler2_19.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_2.dn b/dat/cache/difffile-large/2/CacheHandler2_2.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_20.dn b/dat/cache/difffile-large/2/CacheHandler2_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_21.dn b/dat/cache/difffile-large/2/CacheHandler2_21.dn new file mode 100644 index 0000000..7168f0c --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*4 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_22.dn b/dat/cache/difffile-large/2/CacheHandler2_22.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_23.dn b/dat/cache/difffile-large/2/CacheHandler2_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_24.dn b/dat/cache/difffile-large/2/CacheHandler2_24.dn new file mode 100644 index 0000000..954e3b6 --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+16 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_25.dn b/dat/cache/difffile-large/2/CacheHandler2_25.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_26.dn b/dat/cache/difffile-large/2/CacheHandler2_26.dn new file mode 100644 index 0000000..351e233 --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_27.dn b/dat/cache/difffile-large/2/CacheHandler2_27.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_28.dn b/dat/cache/difffile-large/2/CacheHandler2_28.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_29.dn b/dat/cache/difffile-large/2/CacheHandler2_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_3.dn b/dat/cache/difffile-large/2/CacheHandler2_3.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_30.dn b/dat/cache/difffile-large/2/CacheHandler2_30.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_31.dn b/dat/cache/difffile-large/2/CacheHandler2_31.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_32.dn b/dat/cache/difffile-large/2/CacheHandler2_32.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_33.dn b/dat/cache/difffile-large/2/CacheHandler2_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_34.dn b/dat/cache/difffile-large/2/CacheHandler2_34.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_4.dn b/dat/cache/difffile-large/2/CacheHandler2_4.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_5.dn b/dat/cache/difffile-large/2/CacheHandler2_5.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_6.dn b/dat/cache/difffile-large/2/CacheHandler2_6.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_7.dn b/dat/cache/difffile-large/2/CacheHandler2_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_8.dn b/dat/cache/difffile-large/2/CacheHandler2_8.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/2/CacheHandler2_9.dn b/dat/cache/difffile-large/2/CacheHandler2_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/2/CacheHandler2_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_0.dn b/dat/cache/difffile-large/3/CacheHandler3_0.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_1.dn b/dat/cache/difffile-large/3/CacheHandler3_1.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_10.dn b/dat/cache/difffile-large/3/CacheHandler3_10.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_11.dn b/dat/cache/difffile-large/3/CacheHandler3_11.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_12.dn b/dat/cache/difffile-large/3/CacheHandler3_12.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_13.dn b/dat/cache/difffile-large/3/CacheHandler3_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_14.dn b/dat/cache/difffile-large/3/CacheHandler3_14.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_15.dn b/dat/cache/difffile-large/3/CacheHandler3_15.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_16.dn b/dat/cache/difffile-large/3/CacheHandler3_16.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_17.dn b/dat/cache/difffile-large/3/CacheHandler3_17.dn new file mode 100644 index 0000000..b032ee0 --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+15 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_18.dn b/dat/cache/difffile-large/3/CacheHandler3_18.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_19.dn b/dat/cache/difffile-large/3/CacheHandler3_19.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_2.dn b/dat/cache/difffile-large/3/CacheHandler3_2.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_20.dn b/dat/cache/difffile-large/3/CacheHandler3_20.dn new file mode 100644 index 0000000..9261fe9 --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 18*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_21.dn b/dat/cache/difffile-large/3/CacheHandler3_21.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_22.dn b/dat/cache/difffile-large/3/CacheHandler3_22.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_23.dn b/dat/cache/difffile-large/3/CacheHandler3_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_24.dn b/dat/cache/difffile-large/3/CacheHandler3_24.dn new file mode 100644 index 0000000..7168f0c --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*4 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_25.dn b/dat/cache/difffile-large/3/CacheHandler3_25.dn new file mode 100644 index 0000000..c0b2fdb --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)+3 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_26.dn b/dat/cache/difffile-large/3/CacheHandler3_26.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_27.dn b/dat/cache/difffile-large/3/CacheHandler3_27.dn new file mode 100644 index 0000000..351e233 --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_28.dn b/dat/cache/difffile-large/3/CacheHandler3_28.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_29.dn b/dat/cache/difffile-large/3/CacheHandler3_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_3.dn b/dat/cache/difffile-large/3/CacheHandler3_3.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_30.dn b/dat/cache/difffile-large/3/CacheHandler3_30.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_31.dn b/dat/cache/difffile-large/3/CacheHandler3_31.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_32.dn b/dat/cache/difffile-large/3/CacheHandler3_32.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_33.dn b/dat/cache/difffile-large/3/CacheHandler3_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_34.dn b/dat/cache/difffile-large/3/CacheHandler3_34.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_4.dn b/dat/cache/difffile-large/3/CacheHandler3_4.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_5.dn b/dat/cache/difffile-large/3/CacheHandler3_5.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_6.dn b/dat/cache/difffile-large/3/CacheHandler3_6.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_7.dn b/dat/cache/difffile-large/3/CacheHandler3_7.dn new file mode 100644 index 0000000..cde4f6e --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_8.dn b/dat/cache/difffile-large/3/CacheHandler3_8.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/3/CacheHandler3_9.dn b/dat/cache/difffile-large/3/CacheHandler3_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/3/CacheHandler3_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_0.dn b/dat/cache/difffile-large/4/CacheHandler4_0.dn new file mode 100644 index 0000000..cde4f6e --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_1.dn b/dat/cache/difffile-large/4/CacheHandler4_1.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_10.dn b/dat/cache/difffile-large/4/CacheHandler4_10.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_11.dn b/dat/cache/difffile-large/4/CacheHandler4_11.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_12.dn b/dat/cache/difffile-large/4/CacheHandler4_12.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_13.dn b/dat/cache/difffile-large/4/CacheHandler4_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_14.dn b/dat/cache/difffile-large/4/CacheHandler4_14.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_15.dn b/dat/cache/difffile-large/4/CacheHandler4_15.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_16.dn b/dat/cache/difffile-large/4/CacheHandler4_16.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_17.dn b/dat/cache/difffile-large/4/CacheHandler4_17.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_18.dn b/dat/cache/difffile-large/4/CacheHandler4_18.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_19.dn b/dat/cache/difffile-large/4/CacheHandler4_19.dn new file mode 100644 index 0000000..b032ee0 --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+15 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_2.dn b/dat/cache/difffile-large/4/CacheHandler4_2.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_20.dn b/dat/cache/difffile-large/4/CacheHandler4_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_21.dn b/dat/cache/difffile-large/4/CacheHandler4_21.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_22.dn b/dat/cache/difffile-large/4/CacheHandler4_22.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_23.dn b/dat/cache/difffile-large/4/CacheHandler4_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_24.dn b/dat/cache/difffile-large/4/CacheHandler4_24.dn new file mode 100644 index 0000000..7168f0c --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*4 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_25.dn b/dat/cache/difffile-large/4/CacheHandler4_25.dn new file mode 100644 index 0000000..c0b2fdb --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)+3 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_26.dn b/dat/cache/difffile-large/4/CacheHandler4_26.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_27.dn b/dat/cache/difffile-large/4/CacheHandler4_27.dn new file mode 100644 index 0000000..351e233 --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_28.dn b/dat/cache/difffile-large/4/CacheHandler4_28.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_29.dn b/dat/cache/difffile-large/4/CacheHandler4_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_3.dn b/dat/cache/difffile-large/4/CacheHandler4_3.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_30.dn b/dat/cache/difffile-large/4/CacheHandler4_30.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_31.dn b/dat/cache/difffile-large/4/CacheHandler4_31.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_32.dn b/dat/cache/difffile-large/4/CacheHandler4_32.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_33.dn b/dat/cache/difffile-large/4/CacheHandler4_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_34.dn b/dat/cache/difffile-large/4/CacheHandler4_34.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_4.dn b/dat/cache/difffile-large/4/CacheHandler4_4.dn new file mode 100644 index 0000000..627cd48 --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 12-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_5.dn b/dat/cache/difffile-large/4/CacheHandler4_5.dn new file mode 100644 index 0000000..4e54031 --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 9-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_6.dn b/dat/cache/difffile-large/4/CacheHandler4_6.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_7.dn b/dat/cache/difffile-large/4/CacheHandler4_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_8.dn b/dat/cache/difffile-large/4/CacheHandler4_8.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/4/CacheHandler4_9.dn b/dat/cache/difffile-large/4/CacheHandler4_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/4/CacheHandler4_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_0.dn b/dat/cache/difffile-large/5/CacheHandler5_0.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_1.dn b/dat/cache/difffile-large/5/CacheHandler5_1.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_10.dn b/dat/cache/difffile-large/5/CacheHandler5_10.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_11.dn b/dat/cache/difffile-large/5/CacheHandler5_11.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_12.dn b/dat/cache/difffile-large/5/CacheHandler5_12.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_13.dn b/dat/cache/difffile-large/5/CacheHandler5_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_14.dn b/dat/cache/difffile-large/5/CacheHandler5_14.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_15.dn b/dat/cache/difffile-large/5/CacheHandler5_15.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_16.dn b/dat/cache/difffile-large/5/CacheHandler5_16.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_17.dn b/dat/cache/difffile-large/5/CacheHandler5_17.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_18.dn b/dat/cache/difffile-large/5/CacheHandler5_18.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_19.dn b/dat/cache/difffile-large/5/CacheHandler5_19.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_2.dn b/dat/cache/difffile-large/5/CacheHandler5_2.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_20.dn b/dat/cache/difffile-large/5/CacheHandler5_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_21.dn b/dat/cache/difffile-large/5/CacheHandler5_21.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_22.dn b/dat/cache/difffile-large/5/CacheHandler5_22.dn new file mode 100644 index 0000000..3c39931 --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 15/2 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_23.dn b/dat/cache/difffile-large/5/CacheHandler5_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_24.dn b/dat/cache/difffile-large/5/CacheHandler5_24.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_25.dn b/dat/cache/difffile-large/5/CacheHandler5_25.dn new file mode 100644 index 0000000..7168f0c --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*4 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_26.dn b/dat/cache/difffile-large/5/CacheHandler5_26.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_27.dn b/dat/cache/difffile-large/5/CacheHandler5_27.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_28.dn b/dat/cache/difffile-large/5/CacheHandler5_28.dn new file mode 100644 index 0000000..351e233 --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_29.dn b/dat/cache/difffile-large/5/CacheHandler5_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_3.dn b/dat/cache/difffile-large/5/CacheHandler5_3.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_30.dn b/dat/cache/difffile-large/5/CacheHandler5_30.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_31.dn b/dat/cache/difffile-large/5/CacheHandler5_31.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_32.dn b/dat/cache/difffile-large/5/CacheHandler5_32.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_33.dn b/dat/cache/difffile-large/5/CacheHandler5_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_34.dn b/dat/cache/difffile-large/5/CacheHandler5_34.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_4.dn b/dat/cache/difffile-large/5/CacheHandler5_4.dn new file mode 100644 index 0000000..cde4f6e --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_5.dn b/dat/cache/difffile-large/5/CacheHandler5_5.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_6.dn b/dat/cache/difffile-large/5/CacheHandler5_6.dn new file mode 100644 index 0000000..e0999a5 --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_7.dn b/dat/cache/difffile-large/5/CacheHandler5_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_8.dn b/dat/cache/difffile-large/5/CacheHandler5_8.dn new file mode 100644 index 0000000..627cd48 --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 12-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/5/CacheHandler5_9.dn b/dat/cache/difffile-large/5/CacheHandler5_9.dn new file mode 100644 index 0000000..4e54031 --- /dev/null +++ b/dat/cache/difffile-large/5/CacheHandler5_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 9-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_0.dn b/dat/cache/difffile-large/6/CacheHandler6_0.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_1.dn b/dat/cache/difffile-large/6/CacheHandler6_1.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_10.dn b/dat/cache/difffile-large/6/CacheHandler6_10.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_11.dn b/dat/cache/difffile-large/6/CacheHandler6_11.dn new file mode 100644 index 0000000..627cd48 --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 12-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_12.dn b/dat/cache/difffile-large/6/CacheHandler6_12.dn new file mode 100644 index 0000000..4e54031 --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 9-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_13.dn b/dat/cache/difffile-large/6/CacheHandler6_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_14.dn b/dat/cache/difffile-large/6/CacheHandler6_14.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_15.dn b/dat/cache/difffile-large/6/CacheHandler6_15.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_16.dn b/dat/cache/difffile-large/6/CacheHandler6_16.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_17.dn b/dat/cache/difffile-large/6/CacheHandler6_17.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_18.dn b/dat/cache/difffile-large/6/CacheHandler6_18.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_19.dn b/dat/cache/difffile-large/6/CacheHandler6_19.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_2.dn b/dat/cache/difffile-large/6/CacheHandler6_2.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_20.dn b/dat/cache/difffile-large/6/CacheHandler6_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_21.dn b/dat/cache/difffile-large/6/CacheHandler6_21.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_22.dn b/dat/cache/difffile-large/6/CacheHandler6_22.dn new file mode 100644 index 0000000..3c39931 --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 15/2 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_23.dn b/dat/cache/difffile-large/6/CacheHandler6_23.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_24.dn b/dat/cache/difffile-large/6/CacheHandler6_24.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_25.dn b/dat/cache/difffile-large/6/CacheHandler6_25.dn new file mode 100644 index 0000000..7168f0c --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*4 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_26.dn b/dat/cache/difffile-large/6/CacheHandler6_26.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_27.dn b/dat/cache/difffile-large/6/CacheHandler6_27.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_28.dn b/dat/cache/difffile-large/6/CacheHandler6_28.dn new file mode 100644 index 0000000..351e233 --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_29.dn b/dat/cache/difffile-large/6/CacheHandler6_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_3.dn b/dat/cache/difffile-large/6/CacheHandler6_3.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_30.dn b/dat/cache/difffile-large/6/CacheHandler6_30.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_31.dn b/dat/cache/difffile-large/6/CacheHandler6_31.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_32.dn b/dat/cache/difffile-large/6/CacheHandler6_32.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_33.dn b/dat/cache/difffile-large/6/CacheHandler6_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_34.dn b/dat/cache/difffile-large/6/CacheHandler6_34.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_4.dn b/dat/cache/difffile-large/6/CacheHandler6_4.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_5.dn b/dat/cache/difffile-large/6/CacheHandler6_5.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_6.dn b/dat/cache/difffile-large/6/CacheHandler6_6.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_7.dn b/dat/cache/difffile-large/6/CacheHandler6_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_8.dn b/dat/cache/difffile-large/6/CacheHandler6_8.dn new file mode 100644 index 0000000..cde4f6e --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/6/CacheHandler6_9.dn b/dat/cache/difffile-large/6/CacheHandler6_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/6/CacheHandler6_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_0.dn b/dat/cache/difffile-large/7/CacheHandler7_0.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_1.dn b/dat/cache/difffile-large/7/CacheHandler7_1.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_10.dn b/dat/cache/difffile-large/7/CacheHandler7_10.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_11.dn b/dat/cache/difffile-large/7/CacheHandler7_11.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_12.dn b/dat/cache/difffile-large/7/CacheHandler7_12.dn new file mode 100644 index 0000000..cde4f6e --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_13.dn b/dat/cache/difffile-large/7/CacheHandler7_13.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_14.dn b/dat/cache/difffile-large/7/CacheHandler7_14.dn new file mode 100644 index 0000000..627cd48 --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 12-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_15.dn b/dat/cache/difffile-large/7/CacheHandler7_15.dn new file mode 100644 index 0000000..4e54031 --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 9-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_16.dn b/dat/cache/difffile-large/7/CacheHandler7_16.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_17.dn b/dat/cache/difffile-large/7/CacheHandler7_17.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_18.dn b/dat/cache/difffile-large/7/CacheHandler7_18.dn new file mode 100644 index 0000000..b95d3a3 --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_19.dn b/dat/cache/difffile-large/7/CacheHandler7_19.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_2.dn b/dat/cache/difffile-large/7/CacheHandler7_2.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_20.dn b/dat/cache/difffile-large/7/CacheHandler7_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_21.dn b/dat/cache/difffile-large/7/CacheHandler7_21.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_22.dn b/dat/cache/difffile-large/7/CacheHandler7_22.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_23.dn b/dat/cache/difffile-large/7/CacheHandler7_23.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_24.dn b/dat/cache/difffile-large/7/CacheHandler7_24.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_25.dn b/dat/cache/difffile-large/7/CacheHandler7_25.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_26.dn b/dat/cache/difffile-large/7/CacheHandler7_26.dn new file mode 100644 index 0000000..7168f0c --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*4 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_27.dn b/dat/cache/difffile-large/7/CacheHandler7_27.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_28.dn b/dat/cache/difffile-large/7/CacheHandler7_28.dn new file mode 100644 index 0000000..fd826ac --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_29.dn b/dat/cache/difffile-large/7/CacheHandler7_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_3.dn b/dat/cache/difffile-large/7/CacheHandler7_3.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_30.dn b/dat/cache/difffile-large/7/CacheHandler7_30.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_31.dn b/dat/cache/difffile-large/7/CacheHandler7_31.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_32.dn b/dat/cache/difffile-large/7/CacheHandler7_32.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_33.dn b/dat/cache/difffile-large/7/CacheHandler7_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_34.dn b/dat/cache/difffile-large/7/CacheHandler7_34.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_4.dn b/dat/cache/difffile-large/7/CacheHandler7_4.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_5.dn b/dat/cache/difffile-large/7/CacheHandler7_5.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_6.dn b/dat/cache/difffile-large/7/CacheHandler7_6.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_7.dn b/dat/cache/difffile-large/7/CacheHandler7_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_8.dn b/dat/cache/difffile-large/7/CacheHandler7_8.dn new file mode 100644 index 0000000..914b79b --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/7/CacheHandler7_9.dn b/dat/cache/difffile-large/7/CacheHandler7_9.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/7/CacheHandler7_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_0.dn b/dat/cache/difffile-large/8/CacheHandler8_0.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_1.dn b/dat/cache/difffile-large/8/CacheHandler8_1.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_10.dn b/dat/cache/difffile-large/8/CacheHandler8_10.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_11.dn b/dat/cache/difffile-large/8/CacheHandler8_11.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_12.dn b/dat/cache/difffile-large/8/CacheHandler8_12.dn new file mode 100644 index 0000000..914b79b --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_13.dn b/dat/cache/difffile-large/8/CacheHandler8_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_14.dn b/dat/cache/difffile-large/8/CacheHandler8_14.dn new file mode 100644 index 0000000..cde4f6e --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_15.dn b/dat/cache/difffile-large/8/CacheHandler8_15.dn new file mode 100644 index 0000000..627cd48 --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 12-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_16.dn b/dat/cache/difffile-large/8/CacheHandler8_16.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_17.dn b/dat/cache/difffile-large/8/CacheHandler8_17.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_18.dn b/dat/cache/difffile-large/8/CacheHandler8_18.dn new file mode 100644 index 0000000..b95d3a3 --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_19.dn b/dat/cache/difffile-large/8/CacheHandler8_19.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_2.dn b/dat/cache/difffile-large/8/CacheHandler8_2.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_20.dn b/dat/cache/difffile-large/8/CacheHandler8_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_21.dn b/dat/cache/difffile-large/8/CacheHandler8_21.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_22.dn b/dat/cache/difffile-large/8/CacheHandler8_22.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_23.dn b/dat/cache/difffile-large/8/CacheHandler8_23.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_24.dn b/dat/cache/difffile-large/8/CacheHandler8_24.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_25.dn b/dat/cache/difffile-large/8/CacheHandler8_25.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_26.dn b/dat/cache/difffile-large/8/CacheHandler8_26.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_27.dn b/dat/cache/difffile-large/8/CacheHandler8_27.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_28.dn b/dat/cache/difffile-large/8/CacheHandler8_28.dn new file mode 100644 index 0000000..fd826ac --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_29.dn b/dat/cache/difffile-large/8/CacheHandler8_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_3.dn b/dat/cache/difffile-large/8/CacheHandler8_3.dn new file mode 100644 index 0000000..4e54031 --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 9-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_30.dn b/dat/cache/difffile-large/8/CacheHandler8_30.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_31.dn b/dat/cache/difffile-large/8/CacheHandler8_31.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_32.dn b/dat/cache/difffile-large/8/CacheHandler8_32.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_33.dn b/dat/cache/difffile-large/8/CacheHandler8_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_34.dn b/dat/cache/difffile-large/8/CacheHandler8_34.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_4.dn b/dat/cache/difffile-large/8/CacheHandler8_4.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_5.dn b/dat/cache/difffile-large/8/CacheHandler8_5.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_6.dn b/dat/cache/difffile-large/8/CacheHandler8_6.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_7.dn b/dat/cache/difffile-large/8/CacheHandler8_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_8.dn b/dat/cache/difffile-large/8/CacheHandler8_8.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/8/CacheHandler8_9.dn b/dat/cache/difffile-large/8/CacheHandler8_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/8/CacheHandler8_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_0.dn b/dat/cache/difffile-large/9/CacheHandler9_0.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_0.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_1.dn b/dat/cache/difffile-large/9/CacheHandler9_1.dn new file mode 100644 index 0000000..219cc47 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_1.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_10.dn b/dat/cache/difffile-large/9/CacheHandler9_10.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_10.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_11.dn b/dat/cache/difffile-large/9/CacheHandler9_11.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_11.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_12.dn b/dat/cache/difffile-large/9/CacheHandler9_12.dn new file mode 100644 index 0000000..f8991fc --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_12.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_13.dn b/dat/cache/difffile-large/9/CacheHandler9_13.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_13.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_14.dn b/dat/cache/difffile-large/9/CacheHandler9_14.dn new file mode 100644 index 0000000..914b79b --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_14.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_15.dn b/dat/cache/difffile-large/9/CacheHandler9_15.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_15.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_16.dn b/dat/cache/difffile-large/9/CacheHandler9_16.dn new file mode 100644 index 0000000..cde4f6e --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_16.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_17.dn b/dat/cache/difffile-large/9/CacheHandler9_17.dn new file mode 100644 index 0000000..627cd48 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_17.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 12-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_18.dn b/dat/cache/difffile-large/9/CacheHandler9_18.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_18.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_19.dn b/dat/cache/difffile-large/9/CacheHandler9_19.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_19.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_2.dn b/dat/cache/difffile-large/9/CacheHandler9_2.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_2.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_20.dn b/dat/cache/difffile-large/9/CacheHandler9_20.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_20.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_21.dn b/dat/cache/difffile-large/9/CacheHandler9_21.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_21.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_22.dn b/dat/cache/difffile-large/9/CacheHandler9_22.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_22.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_23.dn b/dat/cache/difffile-large/9/CacheHandler9_23.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_23.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_24.dn b/dat/cache/difffile-large/9/CacheHandler9_24.dn new file mode 100644 index 0000000..ba9b0dc --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_24.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_25.dn b/dat/cache/difffile-large/9/CacheHandler9_25.dn new file mode 100644 index 0000000..0726947 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_25.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0-2 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_26.dn b/dat/cache/difffile-large/9/CacheHandler9_26.dn new file mode 100644 index 0000000..b0adee8 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_26.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_27.dn b/dat/cache/difffile-large/9/CacheHandler9_27.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_27.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_28.dn b/dat/cache/difffile-large/9/CacheHandler9_28.dn new file mode 100644 index 0000000..fd826ac --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_28.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)-nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_29.dn b/dat/cache/difffile-large/9/CacheHandler9_29.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_29.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_3.dn b/dat/cache/difffile-large/9/CacheHandler9_3.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_3.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_30.dn b/dat/cache/difffile-large/9/CacheHandler9_30.dn new file mode 100644 index 0000000..2e02699 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_30.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_31.dn b/dat/cache/difffile-large/9/CacheHandler9_31.dn new file mode 100644 index 0000000..88d4397 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_31.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/random() + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_32.dn b/dat/cache/difffile-large/9/CacheHandler9_32.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_32.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_33.dn b/dat/cache/difffile-large/9/CacheHandler9_33.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_33.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_34.dn b/dat/cache/difffile-large/9/CacheHandler9_34.dn new file mode 100644 index 0000000..ed919b2 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_34.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_4.dn b/dat/cache/difffile-large/9/CacheHandler9_4.dn new file mode 100644 index 0000000..2e42711 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_4.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostRecentlyUsed(0)*nthMostFrequentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_5.dn b/dat/cache/difffile-large/9/CacheHandler9_5.dn new file mode 100644 index 0000000..f70064d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_5.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_6.dn b/dat/cache/difffile-large/9/CacheHandler9_6.dn new file mode 100644 index 0000000..07667c8 --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_6.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0+2 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_7.dn b/dat/cache/difffile-large/9/CacheHandler9_7.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_7.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_8.dn b/dat/cache/difffile-large/9/CacheHandler9_8.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_8.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/cache/difffile-large/9/CacheHandler9_9.dn b/dat/cache/difffile-large/9/CacheHandler9_9.dn new file mode 100644 index 0000000..11e4e2d --- /dev/null +++ b/dat/cache/difffile-large/9/CacheHandler9_9.dn @@ -0,0 +1,267 @@ +/* + * EmerGen(e)tic 0.8 + * Copyright © 2017 Ben Goldsworthy (rumperuu) + * + * A program to research the utility of genetic algorithms, applied to + * 'emergent' sytems. + * + * This file is part of EmerGen(e)tic. + * + * IMPROVEMENT(S): License (probably GNU GPLv3 tbh) goes here. + */ + +/** + ** This program serves as the base for each mutated CacheHandler, + ** providing the functionality that is common to all of them. + **/ + + /** + ** @author Ben Goldsworthy (rumperuu) + ** @version 1.0 + **/ +component provides cache.CacheHandler + requires io.Output out, + data.IntUtil iu, + util.RandomInt ir, + time.Calendar ic, + time.DateUtil du, + io.File { + + static CachedResponse cache[] + static int arraySize + static Mutex cacheLock + + /** + ** Returns a requested item from the cache. + ** + ** @param resource The request item filepath + ** @return The item from the cache + **/ + CachedResponse CacheHandler:getCachedResponse(char filePath[]) { + // Converts the filepath to an array of bytes for the file. + File fd = new File(filePath, File.FILE_ACCESS_READ) + char resource[] = fd.read(fd.getSize()) + fd.close() + + // Returns the item if it's in the cache. + mutex(cacheLock) { + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == resource) { + cache[i].hits++ + cache[i].lastUsed = ic.getTime() + return cache[i] + } + } + } + return null + } + + /** + ** Updates the cache if the requested item is not already present. + ** If the cache is full, the method of determining the item to be + ** replaced is subject to genetic mutation. + ** + ** @param ncr The new item to cache + **/ + void CacheHandler:updateCache(CachedResponse ncr) { + mutex(cacheLock) { + // If the item is already in the cache, do nothing. + for (int i = 0; i < arraySize; i++) { + if (cache[i].resource == ncr.resource) { + cache[i].response = ncr.response + cache[i].resourceAge = ncr.resourceAge + + return + } + } + + // If the item is not, it must be added. + // As `ncr` was created on another component, its details must + // be copied to avoid a read-only exception. + CachedResponse newEntry = new CachedResponse() + newEntry.command = ncr.command + newEntry.resource = ncr.resource + newEntry.resourceAge = ncr.resourceAge + newEntry.mimeType = ncr.mimeType + newEntry.response = new byte[](ncr.response) + newEntry.contentSize = ncr.contentSize + + // Initialises the cache if there isn't currently one. + if (cache == null) { + cache = new CachedResponse[CacheHandler.MAX_SIZE]() + } + + // If the cache is full, determines which item to replace. + if (arraySize == CacheHandler.MAX_SIZE) { + int index + + // BEGIN + index = 0 + // END + + cache[index % arraySize] = newEntry + //out.println("$(debugMSG) replacing: $(iu.intToString(index))") + // Otherwise, appends the item to the end of the cache. + } else { + cache[arraySize] = newEntry + arraySize++ + } + } + } + + /** + ** Clears the cache completely. + **/ + void CacheHandler:clearCache() { + mutex(cacheLock) { + cache = null + } + } + + /************************************************************************** + * What follows are utility functions that a given chromosome of the + * `updateCache()` method may or may not call upon. + **************************************************************************/ + + // This method returns the index of the nth most frequently-used item in + // the cache. + int nthMostFrequentlyUsed(int n) { + int hits[] + for (int i = 0; i < arraySize; i++) hits[i] = 0 + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (cache[i].hits == hits[j]) break + else if (hits[j] == 0) { + hits[j] = cache[i].hits + break + } + } + } + } + + int k = 0 + int nthHit = 0 + for (i = 0; i < j; i++) { + if (hits[i] > nthHit) { + nthHit = hits[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (cache[i].hits == nthHit) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns the index of the nth most recently-used item in + // the cache. + int nthMostRecentlyUsed(int n) { + DateTime useTimes[] + DateTime testTime = ic.getTime() + for (int i = 0; i < arraySize; i++) useTimes[i] = testTime + + int i + int j + mutex(cacheLock) { + for (i = 0; i < arraySize; i++) { + for (j = 0; j < arraySize; j++) { + if (du.equal(cache[i].lastUsed, useTimes[j])) break + else if (du.equal(useTimes[j], testTime)) { + useTimes[j] = cache[i].lastUsed + break + } + } + } + } + + int k = 0 + DateTime nthUseTime = ic.getTime() + for (i = 0; i < j; i++) { + if (du.after(useTimes[i], nthUseTime)) { + nthUseTime = useTimes[i] + k++ + } + if (k == n) break + } + + int itemIndices[] + + mutex(cacheLock) { + j = 0 + for (i = 0; i < arraySize; i++) { + if (du.equal(cache[i].lastUsed, nthUseTime)) itemIndices[j++] = i + } + } + + return resolve(itemIndices, "r") + } + + // This method returns a random index. + int random() { + DateTime dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(CacheHandler.MAX_SIZE) + } + + // This method resolves a multiple return in one of the methods above, + // as per the flag sent along with the list of indices. + // 'n' returns the newest, 'o' the oldest and 'r' a random index. + int resolve(int index[], char flag) { + DateTime dt = null + + if (flag == "n") { + int newestItem = 0 + + int i = index.arrayLength-1 + for (int j = 0; j < index.arrayLength; j++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } else { + if (du.before(dt, cache[index[i]].timeAdded)) { + dt = cache[index[i]].timeAdded + newestItem = index[i] + } + } + i-- + } + + return newestItem + } else if (flag == "o") { + int oldestItem = 0 + + for (int i = 0; i < index.arrayLength; i++) { + if (dt == null) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } else { + if (du.before(cache[index[i]].timeAdded, dt)) { + dt = cache[index[i]].timeAdded + oldestItem = index[i] + } + } + } + return oldestItem + } else if (flag == "r") { + dt = ic.getTime() + int msec = dt.millisecond + ir.setSeed(msec) + return ir.get(index.arrayLength) + } else { + return 0 + } + } +} diff --git a/dat/helloworld/output0.txt b/dat/helloworld/output0.txt new file mode 100644 index 0000000..6798a43 --- /dev/null +++ b/dat/helloworld/output0.txt @@ -0,0 +1,100 @@ + +['Hello world\n', '1_0'] +['Hello world\n', '1_1'] +['Hello world\n', '1_2'] +['Hello world\n', '1_3'] +['Hello world\n', '1_4'] +['Hello world\n', '1_5'] +['Hello world\n', '1_6'] +['Hello world\n', '1_7'] +['Hello world\n', '1_8'] +['Hello world\n', '1_9'] + +['Hello world\n', '2_0'] +['Hello world\n', '2_1'] +['Hello world\n', '2_2'] +['Hello world\n', '2_3'] +['Hello world\n', '2_4'] +['Hello world\n', '2_5'] +['Hello world\n', '2_6'] +['Hello world\n', '2_7'] +['Hello world\n', '2_8'] +['Hello world\n', '2_9'] + +['Hello world\n', '3_0'] +['Hello world\n', '3_1'] +['Hello world\n', '3_2'] +['Hello world\n', '3_3'] +['Hello world\n', '3_4'] +['Hello world\n', '3_5'] +['Hello world\n', '3_6'] +['Hello world\n', '3_7'] +['Hello world\n', '3_8'] +['Hello world\n', '3_9'] + +['Hello world\n', '4_0'] +['Hello world\n', '4_1'] +['Hello world\n', '4_2'] +['Hello world\n', '4_3'] +['Hello world\n', '4_4'] +['Hello world\n', '4_5'] +['Hello world\n', '4_6'] +['Hello world\n', '4_7'] +['Hello world\n', '4_8'] +['Hello world\n', '4_9'] + +['Hello world\n', '5_0'] +['Hello world\n', '5_1'] +['Hello world\n', '5_2'] +['Hello world\n', '5_3'] +['Hello world\n', '5_4'] +['Hello world\n', '5_5'] +['Hello world\n', '5_6'] +['Hello world\n', '5_7'] +['Hello world\n', '5_8'] +['Hello world\n', '5_9'] + +['Hello world\n', '6_0'] +['Hello world\n', '6_1'] +['Hello world\n', '6_2'] +['Hello world\n', '6_3'] +['Hello world\n', '6_4'] +['Hello world\n', '6_5'] +['Hello world\n', '6_6'] +['Hello world\n', '6_7'] +['Hello world\n', '6_8'] +['Hello world\n', '6_9'] + +['Hello world\n', '7_0'] +['Hello world\n', '7_1'] +['Hello world\n', '7_2'] +['Hello world\n', '7_3'] +['Hello world\n', '7_4'] +['Hello world\n', '7_5'] +['Hello world\n', '7_6'] +['Hello world\n', '7_7'] +['Hello world\n', '7_8'] +['Hello world\n', '7_9'] + +['Hello world\n', '8_0'] +['Hello world\n', '8_1'] +['Hello world\n', '8_2'] +['Hello world\n', '8_3'] +['Hello world\n', '8_4'] +['Hello world\n', '8_5'] +['Hello world\n', '8_6'] +['Hello world\n', '8_7'] +['Hello world\n', '8_8'] +['Hello world\n', '8_9'] + +['Hello world\n', '9_0'] +['Hello world\n', '9_1'] +['Hello world\n', '9_2'] +['Hello world\n', '9_3'] +['Hello world\n', '9_4'] +['Hello world\n', '9_5'] +['Hello world\n', '9_6'] +['Hello world\n', '9_7'] +['Hello world\n', '9_8'] +['Hello world\n', '9_9'] + diff --git a/dat/helloworld/output100.txt b/dat/helloworld/output100.txt new file mode 100644 index 0000000..f9c05cb --- /dev/null +++ b/dat/helloworld/output100.txt @@ -0,0 +1,100 @@ + +['ampcjlcutjs', '1_0'] +['xktieosrnyx', '1_1'] +['caxedgtiyup', '1_2'] +['cqyiujnyapp', '1_3'] +['wnkwuyamxxz', '1_4'] +['rfotmkuheyv', '1_5'] +['eveudzvxhzj', '1_6'] +['ftgxinfdomw', '1_7'] +['mdjomfeoggy', '1_8'] +['fibdllxjmox', '1_9'] + +['pwfumdlcauk', '2_0'] +['bfoxwhovtgm', '2_1'] +['gqpztkejijs', '2_2'] +['drxavuclcka', '2_3'] +['wiycvultuli', '2_4'] +['uyxeayumsdc', '2_5'] +['mubbtclbees', '2_6'] +['xezoaznywmq', '2_7'] +['mjlcdtnuekd', '2_8'] +['cdzklmlaayk', '2_9'] + +['dwsvoawkono', '3_0'] +['vokazvphity', '3_1'] +['ogxdqkpodqt', '3_2'] +['rogfabbqmdn', '3_3'] +['ygtasskorjq', '3_4'] +['obpgipyogbm', '3_5'] +['mtpiqcignyk', '3_6'] +['bnzugplaclt', '3_7'] +['dekckrrqqrz', '3_8'] +['jxdbtdrzbka', '3_9'] + +['zeyofehsgel', '4_0'] +['unqpqfgncqq', '4_1'] +['vyirphbzqnv', '4_2'] +['enpjablprua', '4_3'] +['gvnikmusunw', '4_4'] +['bviefpdtdje', '4_5'] +['qogzptxbnsv', '4_6'] +['hjdvmrnewsj', '4_7'] +['kqdetdhygmq', '4_8'] +['xmxqnnwvdxq', '4_9'] + +['oyvocjrkmik', '5_0'] +['ugfnrykhfmr', '5_1'] +['xsqhoxiaduh', '5_2'] +['gkmwhksxzkt', '5_3'] +['rusllvvfgww', '5_4'] +['ozelqmixipj', '5_5'] +['ilmjpwedmrk', '5_6'] +['aptysrjsjkw', '5_7'] +['fmklqkskknf', '5_8'] +['yzekmmmuvul', '5_9'] + +['bitequtywek', '6_0'] +['iqlvnjtermm', '6_1'] +['bvahdtxyrep', '6_2'] +['skxqhsirryo', '6_3'] +['ajoexxutuhd', '6_4'] +['umwormhnxlz', '6_5'] +['htvrrhqgvzl', '6_6'] +['pzitdowgnjg', '6_7'] +['aikbtvejkvr', '6_8'] +['rxttpdhjteo', '6_9'] + +['bghnmmqxksh', '7_0'] +['eqxbhukjhkk', '7_1'] +['pjsplpilhpa', '7_2'] +['fepbzvhjxyd', '7_3'] +['brycqntqkgi', '7_4'] +['ybmnzzqkjbm', '7_5'] +['yovrjairprl', '7_6'] +['lqgfoqrtbhy', '7_7'] +['iwqvaeoyteb', '7_8'] +['cidgqfwqzjm', '7_9'] + +['qcjqmcerknt', '8_0'] +['prziehtdtey', '8_1'] +['oimlyxwgrke', '8_2'] +['nhesujrxtmw', '8_3'] +['vvkbmiupaxk', '8_4'] +['hzvigxvglsh', '8_5'] +['qbvjkftsngc', '8_6'] +['hqkqxkwqnph', '8_7'] +['vafgdyouzia', '8_8'] +['tcdxmxvmzgs', '8_9'] + +['eojplmnbdca', '9_0'] +['bxibnaghyjd', '9_1'] +['wbcjmozsszm', '9_2'] +['bsavrzfzuyp', '9_3'] +['kktmgrnajpc', '9_4'] +['gvrsehcxdkq', '9_5'] +['djgcialnryd', '9_6'] +['dvuwcklknlt', '9_7'] +['hoaxsvpmibw', '9_8'] +['oetzcsckiyu', '9_9'] + diff --git a/dat/helloworld/output50.txt b/dat/helloworld/output50.txt new file mode 100644 index 0000000..253b8c0 --- /dev/null +++ b/dat/helloworld/output50.txt @@ -0,0 +1,100 @@ + +['Hello world\n', '1_0'] +['Hello world\n', '1_1'] +['Hello world\n', '1_2'] +['Hekjo joaky', '1_3'] +['Hello world\n', '1_4'] +['hiblm wokly', '1_5'] +['Hello world\n', '1_6'] +['Hello world\n', '1_7'] +['Hello world\n', '1_8'] +['yeclo wdvld', '1_9'] + +['jmdlo warld', '2_0'] +['Hello wtrld', '2_1'] +['lejlodyowld', '2_2'] +['ijllordokld', '2_3'] +['Htlloikocsd', '2_4'] +['vvkqo wnrzi', '2_5'] +['Hygro wrplf', '2_6'] +['Hello world\n', '2_7'] +['Hellr zxrld', '2_8'] +['tehzy wordd', '2_9'] + +['Hqslo wokad', '3_0'] +['yexerzsorlh', '3_1'] +['lejlodyowld', '3_2'] +['dtvblxworld', '3_3'] +['gelro qorqd', '3_4'] +['vvkqo wnrzi', '3_5'] +['mmlty wxsjd', '3_6'] +['Hello world\n', '3_7'] +['Hellr zxrld', '3_8'] +['tehzy wordd', '3_9'] + +['Hello wonlm', '4_0'] +['ftllo wwalj', '4_1'] +['lejlodyowld', '4_2'] +['Hezun woiue', '4_3'] +['Hqmlo woyir', '4_4'] +['vvkqo wnrzi', '4_5'] +['mmlty wxsjd', '4_6'] +['Hglyo wveld', '4_7'] +['Hellr zxrld', '4_8'] +['meugm wjrlz', '4_9'] + +['Hauln wouyd', '5_0'] +['ftllo wwalj', '5_1'] +['lejlodyowld', '5_2'] +['Hezun woiue', '5_3'] +['Heplo wcrld', '5_4'] +['vvkqo wnrzi', '5_5'] +['qello worfd', '5_6'] +['Hglyo wveld', '5_7'] +['Hlulowwdglj', '5_8'] +['meugm wjrlz', '5_9'] + +['zvumo varqc', '6_0'] +['zvlgo uorlw', '6_1'] +['Hulle woslb', '6_2'] +['Hello wtxid', '6_3'] +['Heplo wcrld', '6_4'] +['vvkqo wnrzi', '6_5'] +['qello worfd', '6_6'] +['Hglyo wveld', '6_7'] +['Hlulowwdglj', '6_8'] +['meugm wjrlz', '6_9'] + +['zvumo varqc', '7_0'] +['Hzlyowwowld', '7_1'] +['Hulle woslb', '7_2'] +['Hnlroemorvc', '7_3'] +['Heltlroorld', '7_4'] +['vvkqo wnrzi', '7_5'] +['peylqxwprnr', '7_6'] +['Hglyo wveld', '7_7'] +['telah zzrod', '7_8'] +['meugm wjrlz', '7_9'] + +['iealouporfy', '8_0'] +['Hzlyowwowld', '8_1'] +['Hulle woslb', '8_2'] +['Hnlroemorvc', '8_3'] +['hezbxgworcd', '8_4'] +['vvkqo wnrzi', '8_5'] +['peylqxwprnr', '8_6'] +['Hglyo wveld', '8_7'] +['thjlh wyhld', '8_8'] +['meugm wjrlz', '8_9'] + +['iealouporfy', '9_0'] +['Hzlyowwowld', '9_1'] +['Hulle woslb', '9_2'] +['Hesho uovms', '9_3'] +['Hehcq forxd', '9_4'] +['vvkqo wnrzi', '9_5'] +['Hrllniwonld', '9_6'] +['Hrjmo wlrkd', '9_7'] +['lehoncworld', '9_8'] +['qejloywztod', '9_9'] + diff --git a/dat/output (normal).txt b/dat/output (normal).txt new file mode 100644 index 0000000..f266bfd --- /dev/null +++ b/dat/output (normal).txt @@ -0,0 +1,648 @@ + +Result for configuration 0x0: 63 ms +Result for configuration 0x1: 21 ms +Result for configuration 0x2: 21 ms +Result for configuration 0x3: 20 ms +Result for configuration 0x4: 21 ms +Result for configuration 0x5: 20 ms +Result for configuration 0x6: 21 ms +Result for configuration 0x7: 21 ms +Result for configuration 0x8: 21 ms +Result for configuration 0x9: 21 ms +Result for configuration 0x10: 20 ms +Result for configuration 0x11: 21 ms +Result for configuration 0x12: 21 ms +Result for configuration 0x13: 20 ms +Result for configuration 0x14: 21 ms +Result for configuration 0x15: 20 ms +Result for configuration 0x16: 21 ms +Result for configuration 0x17: 21 ms +Result for configuration 0x18: 21 ms +Result for configuration 0x19: 21 ms +Result for configuration 0x20: 21 ms +Result for configuration 0x21: 21 ms +Result for configuration 0x22: 21 ms +Result for configuration 0x23: 21 ms +Result for configuration 0x24: 21 ms +Result for configuration 0x25: 21 ms +Result for configuration 0x26: 21 ms +Result for configuration 0x27: 20 ms +Result for configuration 0x28: 21 ms +Result for configuration 0x29: 21 ms +Result for configuration 0x30: 20 ms +Result for configuration 0x31: 21 ms +Result for configuration 0x32: 21 ms +Result for configuration 0x33: 21 ms +Result for configuration 0x34: 21 ms + +Result for configuration 1x0: 21 ms +Result for configuration 1x1: 21 ms +Result for configuration 1x2: 21 ms +Result for configuration 1x3: 21 ms +Result for configuration 1x4: 21 ms +Result for configuration 1x5: 21 ms +Result for configuration 1x6: 20 ms +Result for configuration 1x7: 21 ms +Result for configuration 1x8: 21 ms +Result for configuration 1x9: 21 ms +Result for configuration 1x10: 21 ms +Result for configuration 1x11: 20 ms +Result for configuration 1x12: 21 ms +Result for configuration 1x13: 21 ms +Result for configuration 1x14: 21 ms +Result for configuration 1x15: 21 ms +Result for configuration 1x16: 21 ms +Result for configuration 1x17: 21 ms +Result for configuration 1x18: 21 ms +Result for configuration 1x19: 21 ms +Result for configuration 1x20: 20 ms +Result for configuration 1x21: 21 ms +Result for configuration 1x22: 21 ms +Result for configuration 1x23: 21 ms +Result for configuration 1x24: 21 ms +Result for configuration 1x25: 21 ms +Result for configuration 1x26: 21 ms +Result for configuration 1x27: 21 ms +Result for configuration 1x28: 21 ms +Result for configuration 1x29: 21 ms +Result for configuration 1x30: 21 ms +Result for configuration 1x31: 21 ms +Result for configuration 1x32: 21 ms +Result for configuration 1x33: 21 ms +Result for configuration 1x34: 20 ms + +Result for configuration 2x0: 21 ms +Result for configuration 2x1: 21 ms +Result for configuration 2x2: 21 ms +Result for configuration 2x3: 21 ms +Result for configuration 2x4: 20 ms +Result for configuration 2x5: 21 ms +Result for configuration 2x6: 21 ms +Result for configuration 2x7: 21 ms +Result for configuration 2x8: 21 ms +Result for configuration 2x9: 21 ms +Result for configuration 2x10: 21 ms +Result for configuration 2x11: 21 ms +Result for configuration 2x12: 21 ms +Result for configuration 2x13: 21 ms +Result for configuration 2x14: 21 ms +Result for configuration 2x15: 21 ms +Result for configuration 2x16: 21 ms +Result for configuration 2x17: 21 ms +Result for configuration 2x18: 21 ms +Result for configuration 2x19: 21 ms +Result for configuration 2x20: 22 ms +Result for configuration 2x21: 21 ms +Result for configuration 2x22: 20 ms +Result for configuration 2x23: 20 ms +Result for configuration 2x24: 21 ms +Result for configuration 2x25: 21 ms +Result for configuration 2x26: 21 ms +Result for configuration 2x27: 20 ms +Result for configuration 2x28: 21 ms +Result for configuration 2x29: 21 ms +Result for configuration 2x30: 21 ms +Result for configuration 2x31: 21 ms +Result for configuration 2x32: 21 ms +Result for configuration 2x33: 20 ms +Result for configuration 2x34: 21 ms + +Result for configuration 3x0: 22 ms +Result for configuration 3x1: 21 ms +Result for configuration 3x2: 21 ms +Result for configuration 3x3: 21 ms +Result for configuration 3x4: 21 ms +Result for configuration 3x5: 21 ms +Result for configuration 3x6: 21 ms +Result for configuration 3x7: 20 ms +Result for configuration 3x8: 21 ms +Result for configuration 3x9: 21 ms +Result for configuration 3x10: 21 ms +Result for configuration 3x11: 21 ms +Result for configuration 3x12: 21 ms +Result for configuration 3x13: 20 ms +Result for configuration 3x14: 21 ms +Result for configuration 3x15: 21 ms +Result for configuration 3x16: 21 ms +Result for configuration 3x17: 21 ms +Result for configuration 3x18: 21 ms +Result for configuration 3x19: 20 ms +Result for configuration 3x20: 21 ms +Result for configuration 3x21: 21 ms +Result for configuration 3x22: 20 ms +Result for configuration 3x23: 21 ms +Result for configuration 3x24: 21 ms +Result for configuration 3x25: 21 ms +Result for configuration 3x26: 20 ms +Result for configuration 3x27: 21 ms +Result for configuration 3x28: 20 ms +Result for configuration 3x29: 21 ms +Result for configuration 3x30: 21 ms +Result for configuration 3x31: 21 ms +Result for configuration 3x32: 21 ms +Result for configuration 3x33: 22 ms +Result for configuration 3x34: 21 ms + +Result for configuration 4x0: 21 ms +Result for configuration 4x1: 22 ms +Result for configuration 4x2: 21 ms +Result for configuration 4x3: 22 ms +Result for configuration 4x4: 21 ms +Result for configuration 4x5: 21 ms +Result for configuration 4x6: 21 ms +Result for configuration 4x7: 21 ms +Result for configuration 4x8: 21 ms +Result for configuration 4x9: 21 ms +Result for configuration 4x10: 21 ms +Result for configuration 4x11: 21 ms +Result for configuration 4x12: 21 ms +Result for configuration 4x13: 20 ms +Result for configuration 4x14: 21 ms +Result for configuration 4x15: 21 ms +Result for configuration 4x16: 21 ms +Result for configuration 4x17: 21 ms +Result for configuration 4x18: 21 ms +Result for configuration 4x19: 21 ms +Result for configuration 4x20: 21 ms +Result for configuration 4x21: 20 ms +Result for configuration 4x22: 20 ms +Result for configuration 4x23: 21 ms +Result for configuration 4x24: 21 ms +Result for configuration 4x25: 21 ms +Result for configuration 4x26: 21 ms +Result for configuration 4x27: 21 ms +Result for configuration 4x28: 21 ms +Result for configuration 4x29: 20 ms +Result for configuration 4x30: 21 ms +Result for configuration 4x31: 21 ms +Result for configuration 4x32: 22 ms +Result for configuration 4x33: 21 ms +Result for configuration 4x34: 21 ms + +Result for configuration 5x0: 21 ms +Result for configuration 5x1: 22 ms +Result for configuration 5x2: 22 ms +Result for configuration 5x3: 21 ms +Result for configuration 5x4: 21 ms +Result for configuration 5x5: 21 ms +Result for configuration 5x6: 21 ms +Result for configuration 5x7: 20 ms +Result for configuration 5x8: 21 ms +Result for configuration 5x9: 21 ms +Result for configuration 5x10: 21 ms +Result for configuration 5x11: 20 ms +Result for configuration 5x12: 21 ms +Result for configuration 5x13: 21 ms +Result for configuration 5x14: 21 ms +Result for configuration 5x15: 21 ms +Result for configuration 5x16: 20 ms +Result for configuration 5x17: 21 ms +Result for configuration 5x18: 20 ms +Result for configuration 5x19: 20 ms +Result for configuration 5x20: 20 ms +Result for configuration 5x21: 21 ms +Result for configuration 5x22: 20 ms +Result for configuration 5x23: 21 ms +Result for configuration 5x24: 21 ms +Result for configuration 5x25: 21 ms +Result for configuration 5x26: 21 ms +Result for configuration 5x27: 20 ms +Result for configuration 5x28: 21 ms +Result for configuration 5x29: 20 ms +Result for configuration 5x30: 21 ms +Result for configuration 5x31: 21 ms +Result for configuration 5x32: 21 ms +Result for configuration 5x33: 21 ms +Result for configuration 5x34: 21 ms + +Result for configuration 6x0: 21 ms +Result for configuration 6x1: 21 ms +Result for configuration 6x2: 21 ms +Result for configuration 6x3: 21 ms +Result for configuration 6x4: 21 ms +Result for configuration 6x5: 21 ms +Result for configuration 6x6: 21 ms +Result for configuration 6x7: 21 ms +Result for configuration 6x8: 22 ms +Result for configuration 6x9: 20 ms +Result for configuration 6x10: 21 ms +Result for configuration 6x11: 21 ms +Result for configuration 6x12: 21 ms +Result for configuration 6x13: 22 ms +Result for configuration 6x14: 21 ms +Result for configuration 6x15: 21 ms +Result for configuration 6x16: 21 ms +Result for configuration 6x17: 21 ms +Result for configuration 6x18: 21 ms +Result for configuration 6x19: 21 ms +Result for configuration 6x20: 21 ms +Result for configuration 6x21: 20 ms +Result for configuration 6x22: 21 ms +Result for configuration 6x23: 20 ms +Result for configuration 6x24: 21 ms +Result for configuration 6x25: 21 ms +Result for configuration 6x26: 21 ms +Result for configuration 6x27: 20 ms +Result for configuration 6x28: 21 ms +Result for configuration 6x29: 21 ms +Result for configuration 6x30: 21 ms +Result for configuration 6x31: 21 ms +Result for configuration 6x32: 21 ms +Result for configuration 6x33: 21 ms +Result for configuration 6x34: 21 ms + +Result for configuration 7x0: 22 ms +Result for configuration 7x1: 22 ms +Result for configuration 7x2: 21 ms +Result for configuration 7x3: 22 ms +Result for configuration 7x4: 22 ms +Result for configuration 7x5: 21 ms +Result for configuration 7x6: 21 ms +Result for configuration 7x7: 21 ms +Result for configuration 7x8: 21 ms +Result for configuration 7x9: 20 ms +Result for configuration 7x10: 20 ms +Result for configuration 7x11: 21 ms +Result for configuration 7x12: 21 ms +Result for configuration 7x13: 20 ms +Result for configuration 7x14: 21 ms +Result for configuration 7x15: 20 ms +Result for configuration 7x16: 21 ms +Result for configuration 7x17: 20 ms +Result for configuration 7x18: 21 ms +Result for configuration 7x19: 21 ms +Result for configuration 7x20: 21 ms +Result for configuration 7x21: 21 ms +Result for configuration 7x22: 21 ms +Result for configuration 7x23: 20 ms +Result for configuration 7x24: 21 ms +Result for configuration 7x25: 21 ms +Result for configuration 7x26: 21 ms +Result for configuration 7x27: 20 ms +Result for configuration 7x28: 21 ms +Result for configuration 7x29: 21 ms +Result for configuration 7x30: 21 ms +Result for configuration 7x31: 21 ms +Result for configuration 7x32: 21 ms +Result for configuration 7x33: 21 ms +Result for configuration 7x34: 21 ms + +Result for configuration 8x0: 21 ms +Result for configuration 8x1: 21 ms +Result for configuration 8x2: 21 ms +Result for configuration 8x3: 21 ms +Result for configuration 8x4: 21 ms +Result for configuration 8x5: 21 ms +Result for configuration 8x6: 22 ms +Result for configuration 8x7: 22 ms +Result for configuration 8x8: 21 ms +Result for configuration 8x9: 21 ms +Result for configuration 8x10: 21 ms +Result for configuration 8x11: 21 ms +Result for configuration 8x12: 21 ms +Result for configuration 8x13: 21 ms +Result for configuration 8x14: 21 ms +Result for configuration 8x15: 21 ms +Result for configuration 8x16: 20 ms +Result for configuration 8x17: 21 ms +Result for configuration 8x18: 21 ms +Result for configuration 8x19: 22 ms +Result for configuration 8x20: 21 ms +Result for configuration 8x21: 21 ms +Result for configuration 8x22: 21 ms +Result for configuration 8x23: 20 ms +Result for configuration 8x24: 21 ms +Result for configuration 8x25: 21 ms +Result for configuration 8x26: 21 ms +Result for configuration 8x27: 21 ms +Result for configuration 8x28: 21 ms +Result for configuration 8x29: 21 ms +Result for configuration 8x30: 21 ms +Result for configuration 8x31: 21 ms +Result for configuration 8x32: 21 ms +Result for configuration 8x33: 21 ms +Result for configuration 8x34: 21 ms + +Result for configuration 9x0: 22 ms +Result for configuration 9x1: 21 ms +Result for configuration 9x2: 21 ms +Result for configuration 9x3: 21 ms +Result for configuration 9x4: 21 ms +Result for configuration 9x5: 21 ms +Result for configuration 9x6: 21 ms +Result for configuration 9x7: 21 ms +Result for configuration 9x8: 21 ms +Result for configuration 9x9: 21 ms +Result for configuration 9x10: 21 ms +Result for configuration 9x11: 21 ms +Result for configuration 9x12: 21 ms +Result for configuration 9x13: 21 ms +Result for configuration 9x14: 21 ms +Result for configuration 9x15: 21 ms +Result for configuration 9x16: 21 ms +Result for configuration 9x17: 21 ms +Result for configuration 9x18: 21 ms +Result for configuration 9x19: 20 ms +Result for configuration 9x20: 21 ms +Result for configuration 9x21: 21 ms +Result for configuration 9x22: 21 ms +Result for configuration 9x23: 21 ms +Result for configuration 9x24: 21 ms +Result for configuration 9x25: 21 ms +Result for configuration 9x26: 20 ms +Result for configuration 9x27: 21 ms +Result for configuration 9x28: 21 ms +Result for configuration 9x29: 21 ms +Result for configuration 9x30: 21 ms +Result for configuration 9x31: 21 ms +Result for configuration 9x32: 21 ms +Result for configuration 9x33: 21 ms +Result for configuration 9x34: 21 ms + +Result for configuration 10x0: 22 ms +Result for configuration 10x1: 22 ms +Result for configuration 10x2: 22 ms +Result for configuration 10x3: 21 ms +Result for configuration 10x4: 21 ms +Result for configuration 10x5: 22 ms +Result for configuration 10x6: 22 ms +Result for configuration 10x7: 21 ms +Result for configuration 10x8: 21 ms +Result for configuration 10x9: 21 ms +Result for configuration 10x10: 21 ms +Result for configuration 10x11: 20 ms +Result for configuration 10x12: 22 ms +Result for configuration 10x13: 22 ms +Result for configuration 10x14: 21 ms +Result for configuration 10x15: 21 ms +Result for configuration 10x16: 21 ms +Result for configuration 10x17: 21 ms +Result for configuration 10x18: 21 ms +Result for configuration 10x19: 20 ms +Result for configuration 10x20: 21 ms +Result for configuration 10x21: 21 ms +Result for configuration 10x22: 21 ms +Result for configuration 10x23: 21 ms +Result for configuration 10x24: 20 ms +Result for configuration 10x25: 20 ms +Result for configuration 10x26: 21 ms +Result for configuration 10x27: 21 ms +Result for configuration 10x28: 21 ms +Result for configuration 10x29: 21 ms +Result for configuration 10x30: 21 ms +Result for configuration 10x31: 21 ms +Result for configuration 10x32: 21 ms +Result for configuration 10x33: 21 ms +Result for configuration 10x34: 21 ms + +Result for configuration 11x0: 21 ms +Result for configuration 11x1: 21 ms +Result for configuration 11x2: 22 ms +Result for configuration 11x3: 21 ms +Result for configuration 11x4: 22 ms +Result for configuration 11x5: 22 ms +Result for configuration 11x6: 21 ms +Result for configuration 11x7: 22 ms +Result for configuration 11x8: 21 ms +Result for configuration 11x9: 21 ms +Result for configuration 11x10: 21 ms +Result for configuration 11x11: 21 ms +Result for configuration 11x12: 21 ms +Result for configuration 11x13: 21 ms +Result for configuration 11x14: 22 ms +Result for configuration 11x15: 21 ms +Result for configuration 11x16: 22 ms +Result for configuration 11x17: 21 ms +Result for configuration 11x18: 21 ms +Result for configuration 11x19: 22 ms +Result for configuration 11x20: 21 ms +Result for configuration 11x21: 21 ms +Result for configuration 11x22: 21 ms +Result for configuration 11x23: 21 ms +Result for configuration 11x24: 20 ms +Result for configuration 11x25: 21 ms +Result for configuration 11x26: 21 ms +Result for configuration 11x27: 21 ms +Result for configuration 11x28: 21 ms +Result for configuration 11x29: 21 ms +Result for configuration 11x30: 21 ms +Result for configuration 11x31: 21 ms +Result for configuration 11x32: 21 ms +Result for configuration 11x33: 21 ms +Result for configuration 11x34: 21 ms + +Result for configuration 12x0: 22 ms +Result for configuration 12x1: 21 ms +Result for configuration 12x2: 22 ms +Result for configuration 12x3: 21 ms +Result for configuration 12x4: 21 ms +Result for configuration 12x5: 22 ms +Result for configuration 12x6: 21 ms +Result for configuration 12x7: 21 ms +Result for configuration 12x8: 21 ms +Result for configuration 12x9: 21 ms +Result for configuration 12x10: 21 ms +Result for configuration 12x11: 22 ms +Result for configuration 12x12: 21 ms +Result for configuration 12x13: 22 ms +Result for configuration 12x14: 20 ms +Result for configuration 12x15: 21 ms +Result for configuration 12x16: 21 ms +Result for configuration 12x17: 21 ms +Result for configuration 12x18: 21 ms +Result for configuration 12x19: 21 ms +Result for configuration 12x20: 21 ms +Result for configuration 12x21: 21 ms +Result for configuration 12x22: 21 ms +Result for configuration 12x23: 21 ms +Result for configuration 12x24: 20 ms +Result for configuration 12x25: 21 ms +Result for configuration 12x26: 22 ms +Result for configuration 12x27: 21 ms +Result for configuration 12x28: 21 ms +Result for configuration 12x29: 20 ms +Result for configuration 12x30: 20 ms +Result for configuration 12x31: 21 ms +Result for configuration 12x32: 21 ms +Result for configuration 12x33: 21 ms +Result for configuration 12x34: 21 ms + +Result for configuration 13x0: 22 ms +Result for configuration 13x1: 22 ms +Result for configuration 13x2: 22 ms +Result for configuration 13x3: 21 ms +Result for configuration 13x4: 21 ms +Result for configuration 13x5: 22 ms +Result for configuration 13x6: 22 ms +Result for configuration 13x7: 21 ms +Result for configuration 13x8: 21 ms +Result for configuration 13x9: 22 ms +Result for configuration 13x10: 21 ms +Result for configuration 13x11: 21 ms +Result for configuration 13x12: 21 ms +Result for configuration 13x13: 21 ms +Result for configuration 13x14: 21 ms +Result for configuration 13x15: 21 ms +Result for configuration 13x16: 21 ms +Result for configuration 13x17: 21 ms +Result for configuration 13x18: 21 ms +Result for configuration 13x19: 21 ms +Result for configuration 13x20: 21 ms +Result for configuration 13x21: 20 ms +Result for configuration 13x22: 21 ms +Result for configuration 13x23: 21 ms +Result for configuration 13x24: 21 ms +Result for configuration 13x25: 21 ms +Result for configuration 13x26: 21 ms +Result for configuration 13x27: 21 ms +Result for configuration 13x28: 21 ms +Result for configuration 13x29: 21 ms +Result for configuration 13x30: 21 ms +Result for configuration 13x31: 21 ms +Result for configuration 13x32: 20 ms +Result for configuration 13x33: 21 ms +Result for configuration 13x34: 21 ms + +Result for configuration 14x0: 22 ms +Result for configuration 14x1: 21 ms +Result for configuration 14x2: 22 ms +Result for configuration 14x3: 21 ms +Result for configuration 14x4: 21 ms +Result for configuration 14x5: 21 ms +Result for configuration 14x6: 22 ms +Result for configuration 14x7: 21 ms +Result for configuration 14x8: 21 ms +Result for configuration 14x9: 21 ms +Result for configuration 14x10: 21 ms +Result for configuration 14x11: 21 ms +Result for configuration 14x12: 21 ms +Result for configuration 14x13: 21 ms +Result for configuration 14x14: 21 ms +Result for configuration 14x15: 21 ms +Result for configuration 14x16: 21 ms +Result for configuration 14x17: 21 ms +Result for configuration 14x18: 20 ms +Result for configuration 14x19: 20 ms +Result for configuration 14x20: 21 ms +Result for configuration 14x21: 21 ms +Result for configuration 14x22: 21 ms +Result for configuration 14x23: 21 ms +Result for configuration 14x24: 21 ms +Result for configuration 14x25: 21 ms +Result for configuration 14x26: 21 ms +Result for configuration 14x27: 21 ms +Result for configuration 14x28: 21 ms +Result for configuration 14x29: 21 ms +Result for configuration 14x30: 21 ms +Result for configuration 14x31: 21 ms +Result for configuration 14x32: 21 ms +Result for configuration 14x33: 20 ms +Result for configuration 14x34: 22 ms + +Result for configuration 15x0: 22 ms +Result for configuration 15x1: 22 ms +Result for configuration 15x2: 21 ms +Result for configuration 15x3: 21 ms +Result for configuration 15x4: 21 ms +Result for configuration 15x5: 21 ms +Result for configuration 15x6: 21 ms +Result for configuration 15x7: 22 ms +Result for configuration 15x8: 21 ms +Result for configuration 15x9: 22 ms +Result for configuration 15x10: 22 ms +Result for configuration 15x11: 22 ms +Result for configuration 15x12: 21 ms +Result for configuration 15x13: 21 ms +Result for configuration 15x14: 21 ms +Result for configuration 15x15: 21 ms +Result for configuration 15x16: 21 ms +Result for configuration 15x17: 21 ms +Result for configuration 15x18: 21 ms +Result for configuration 15x19: 21 ms +Result for configuration 15x20: 21 ms +Result for configuration 15x21: 21 ms +Result for configuration 15x22: 21 ms +Result for configuration 15x23: 21 ms +Result for configuration 15x24: 21 ms +Result for configuration 15x25: 21 ms +Result for configuration 15x26: 21 ms +Result for configuration 15x27: 21 ms +Result for configuration 15x28: 20 ms +Result for configuration 15x29: 21 ms +Result for configuration 15x30: 21 ms +Result for configuration 15x31: 21 ms +Result for configuration 15x32: 21 ms +Result for configuration 15x33: 21 ms +Result for configuration 15x34: 21 ms + +Result for configuration 16x0: 21 ms +Result for configuration 16x1: 22 ms +Result for configuration 16x2: 21 ms +Result for configuration 16x3: 22 ms +Result for configuration 16x4: 22 ms +Result for configuration 16x5: 21 ms +Result for configuration 16x6: 21 ms +Result for configuration 16x7: 21 ms +Result for configuration 16x8: 21 ms +Result for configuration 16x9: 22 ms +Result for configuration 16x10: 21 ms +Result for configuration 16x11: 22 ms +Result for configuration 16x12: 22 ms +Result for configuration 16x13: 21 ms +Result for configuration 16x14: 21 ms +Result for configuration 16x15: 22 ms +Result for configuration 16x16: 22 ms +Result for configuration 16x17: 21 ms +Result for configuration 16x18: 21 ms +Result for configuration 16x19: 21 ms +Result for configuration 16x20: 21 ms +Result for configuration 16x21: 21 ms +Result for configuration 16x22: 21 ms +Result for configuration 16x23: 21 ms +Result for configuration 16x24: 21 ms +Result for configuration 16x25: 21 ms +Result for configuration 16x26: 22 ms +Result for configuration 16x27: 21 ms +Result for configuration 16x28: 21 ms +Result for configuration 16x29: 21 ms +Result for configuration 16x30: 21 ms +Result for configuration 16x31: 21 ms +Result for configuration 16x32: 21 ms +Result for configuration 16x33: 21 ms +Result for configuration 16x34: 21 ms + +Result for configuration 17x0: 21 ms +Result for configuration 17x1: 21 ms +Result for configuration 17x2: 21 ms +Result for configuration 17x3: 22 ms +Result for configuration 17x4: 21 ms +Result for configuration 17x5: 22 ms +Result for configuration 17x6: 21 ms +Result for configuration 17x7: 21 ms +Result for configuration 17x8: 21 ms +Result for configuration 17x9: 22 ms +Result for configuration 17x10: 21 ms +Result for configuration 17x11: 21 ms +Result for configuration 17x12: 21 ms +Result for configuration 17x13: 21 ms +Result for configuration 17x14: 21 ms +Result for configuration 17x15: 22 ms +Result for configuration 17x16: 21 ms +Result for configuration 17x17: 22 ms +Result for configuration 17x18: 22 ms +Result for configuration 17x19: 21 ms +Result for configuration 17x20: 21 ms +Result for configuration 17x21: 21 ms +Result for configuration 17x22: 20 ms +Result for configuration 17x23: 21 ms +Result for configuration 17x24: 21 ms +Result for configuration 17x25: 21 ms +Result for configuration 17x26: 21 ms +Result for configuration 17x27: 21 ms +Result for configuration 17x28: 21 ms +Result for configuration 17x29: 21 ms +Result for configuration 17x30: 21 ms +Result for configuration 17x31: 21 ms +Result for configuration 17x32: 21 ms +Result for configuration 17x33: 21 ms +Result for configuration 17x34: 20 ms diff --git a/dat/output (verbose).txt b/dat/output (verbose).txt new file mode 100644 index 0000000..3837ca2 --- /dev/null +++ b/dat/output (verbose).txt @@ -0,0 +1,1027 @@ +Result for configuration 0x0: 21 ms +Result for configuration 0x1: 21 ms +Result for configuration 0x2: 21 ms +Result for configuration 0x3: 21 ms +Result for configuration 0x4: 21 ms +Result for configuration 0x5: 21 ms +Result for configuration 0x6: 21 ms +Result for configuration 0x7: 20 ms +Result for configuration 0x8: 21 ms +Result for configuration 0x9: 21 ms +Result for configuration 0x10: 21 ms +Result for configuration 0x11: 21 ms +Result for configuration 0x12: 21 ms +Result for configuration 0x13: 20 ms +Result for configuration 0x14: 21 ms +Result for configuration 0x15: 21 ms +Result for configuration 0x16: 21 ms +Result for configuration 0x17: 21 ms +Result for configuration 0x18: 20 ms +Result for configuration 0x19: 21 ms +Result for configuration 0x20: 20 ms +Result for configuration 0x21: 20 ms +Result for configuration 0x22: 21 ms +Result for configuration 0x23: 21 ms +Result for configuration 0x24: 21 ms +Result for configuration 0x25: 20 ms +Result for configuration 0x26: 21 ms +Result for configuration 0x27: 20 ms +Result for configuration 0x28: 20 ms +Result for configuration 0x29: 21 ms +Result for configuration 0x30: 21 ms +Result for configuration 0x31: 21 ms +Result for configuration 0x32: 21 ms +Result for configuration 0x33: 21 ms +Result for configuration 0x34: 21 ms + +Applying rank selection to top 10% from prev. generation... + Result: 0_3 copied to 1_3 + Result: 0_5 copied to 1_5 + Result: 0_10 copied to 1_10 + Result: 0_13 copied to 1_13 + + +Mutating 0_6->1_6: + Mutating: 0 + Result: 0/13 + Mutating: 0/13 + Result: 0+13 + Mutating: 0+13 + Result: 0+18 +0_6->1_6 mutation finish. + +Mutating 0_7->1_7: + Mutating: 0 + Result: 0*12 + Mutating: 0*12 + Result: 0*12 + Mutating: 0*12 + Result: 0*nthMostRecentlyUsed(0) +0_7->1_7 mutation finish. + +Mutating 0_19->1_19: + Mutating: 0 + Result: 0 +0_19->1_19 mutation finish. + +Mutating 0_21->1_21: + Mutating: 0 + Result: 0*17 + Mutating: 0*17 + Result: 0-17 + Mutating: 0-17 + Result: 0-nthMostFrequentlyUsed(0) +0_21->1_21 mutation finish. + +Mutating 0_25->1_25: + Mutating: 0 + Result: 0 +0_25->1_25 mutation finish. + +Mutating 0_27->1_27: + Mutating: 0 + Result: 0 +0_27->1_27 mutation finish. + +Mutating 0_28->1_28: + Mutating: 0 + Result: 0 +0_28->1_28 mutation finish. + + +Result for configuration 1x0: 21 ms +Result for configuration 1x1: 20 ms +Result for configuration 1x2: 22 ms +Result for configuration 1x3: 22 ms +Result for configuration 1x4: 21 ms +Result for configuration 1x5: 21 ms +Result for configuration 1x6: 21 ms +Result for configuration 1x7: 21 ms +Result for configuration 1x8: 21 ms +Result for configuration 1x9: 21 ms +Result for configuration 1x10: 20 ms +Result for configuration 1x11: 21 ms +Result for configuration 1x12: 21 ms +Result for configuration 1x13: 21 ms +Result for configuration 1x14: 20 ms +Result for configuration 1x15: 21 ms +Result for configuration 1x16: 21 ms +Result for configuration 1x17: 21 ms +Result for configuration 1x18: 21 ms +Result for configuration 1x19: 21 ms +Result for configuration 1x20: 21 ms +Result for configuration 1x21: 21 ms +Result for configuration 1x22: 21 ms +Result for configuration 1x23: 22 ms +Result for configuration 1x24: 21 ms +Result for configuration 1x25: 21 ms +Result for configuration 1x26: 21 ms +Result for configuration 1x27: 21 ms +Result for configuration 1x28: 21 ms +Result for configuration 1x29: 20 ms +Result for configuration 1x30: 20 ms +Result for configuration 1x31: 21 ms +Result for configuration 1x32: 20 ms +Result for configuration 1x33: 21 ms +Result for configuration 1x34: 21 ms + +Applying rank selection to top 10% from prev. generation... + Result: 1_6 copied to 2_6 + Result: 1_11 copied to 2_11 + Result: 1_20 copied to 2_20 + Result: 1_34 copied to 2_34 + + +Mutating 1_1->2_1: + Mutating: 0 + Result: 0 +1_1->2_1 mutation finish. + +Mutating 1_14->2_14: + Mutating: 0 + Result: 0*13 + Mutating: 0*13 + Result: 0*13 + Mutating: 0*13 + Result: 0*19 +1_14->2_14 mutation finish. + +Mutating 1_15->2_15: + Mutating: 0 + Result: 0 +1_15->2_15 mutation finish. + +Mutating 1_18->2_18: + Mutating: 0 + Result: 0*16 + Mutating: 0*16 + Result: 0/16 + Mutating: 0/16 + Result: 0/3 +1_18->2_18 mutation finish. + +Mutating 1_21->2_21: + Mutating: 0-nthMostFrequentlyUsed(0) + Result: 5-nthMostFrequentlyUsed(0) + Mutating: 5-nthMostFrequentlyUsed(0) + Result: 5-nthMostFrequentlyUsed(0) + Mutating: 5-nthMostFrequentlyUsed(0) + Result: 5-nthMostFrequentlyUsed(0) + Mutating: 5-nthMostFrequentlyUsed(0) + Result: 5-nthMostFrequentlyUsed(0) +1_21->2_21 mutation finish. + +Mutating 1_23->2_23: + Mutating: 0 + Result: 0+11 + Mutating: 0+11 + Result: 0-11 + Mutating: 0-11 + Result: 0-nthMostFrequentlyUsed(0) +1_23->2_23 mutation finish. + +Mutating 1_25->2_25: + Mutating: 0 + Result: 0/3 + Mutating: 0/3 + Result: 0/3 + Mutating: 0/3 + Result: 0/nthMostRecentlyUsed(0) +1_25->2_25 mutation finish. + +Mutating 1_27->2_27: + Mutating: 0 + Result: 0*9 + Mutating: 0*9 + Result: 0/9 + Mutating: 0/9 + Result: 0/3 +1_27->2_27 mutation finish. + + +Result for configuration 2x0: 21 ms +Result for configuration 2x1: 21 ms +Result for configuration 2x2: 20 ms +Result for configuration 2x3: 21 ms +Result for configuration 2x4: 20 ms +Result for configuration 2x5: 21 ms +Result for configuration 2x6: 20 ms +Result for configuration 2x7: 22 ms +Result for configuration 2x8: 22 ms +Result for configuration 2x9: 21 ms +Result for configuration 2x10: 21 ms +Result for configuration 2x11: 22 ms +Result for configuration 2x12: 21 ms +Result for configuration 2x13: 21 ms +Result for configuration 2x14: 21 ms +Result for configuration 2x15: 21 ms +Result for configuration 2x16: 21 ms +Result for configuration 2x17: 21 ms +Result for configuration 2x18: 20 ms +Result for configuration 2x19: 21 ms +Result for configuration 2x20: 21 ms +Result for configuration 2x21: 20 ms +Result for configuration 2x22: 21 ms +Result for configuration 2x23: 21 ms +Result for configuration 2x24: 21 ms +Result for configuration 2x25: 21 ms +Result for configuration 2x26: 21 ms +Result for configuration 2x27: 21 ms +Result for configuration 2x28: 21 ms +Result for configuration 2x29: 21 ms +Result for configuration 2x30: 21 ms +Result for configuration 2x31: 20 ms +Result for configuration 2x32: 21 ms +Result for configuration 2x33: 21 ms +Result for configuration 2x34: 21 ms + +Applying rank selection to top 10% from prev. generation... + Result: 2_4 copied to 3_4 + Result: 2_22 copied to 3_22 + Result: 2_23 copied to 3_23 + Result: 2_27 copied to 3_27 + + +Mutating 2_6->3_6: + Mutating: 0 + Result: 0+1 + Mutating: 0+1 + Result: 0+1 + Mutating: 0+1 + Result: 0+random() +2_6->3_6 mutation finish. + +Mutating 2_12->3_12: + Mutating: 0*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) +2_12->3_12 mutation finish. + +Mutating 2_16->3_16: + Mutating: 0*19 + Result: nthMostRecentlyUsed(0)*19 + Mutating: nthMostRecentlyUsed(0)*19 + Result: nthMostRecentlyUsed(0)-19 + Mutating: nthMostRecentlyUsed(0)-19 + Result: nthMostRecentlyUsed(0)-9 +2_16->3_16 mutation finish. + +Mutating 2_19->3_19: + Mutating: 0 + Result: 0 +2_19->3_19 mutation finish. + +Mutating 2_20->3_20: + Mutating: 0/3 + Result: nthMostFrequentlyUsed(0)/3 + Mutating: nthMostFrequentlyUsed(0)/3 + Result: nthMostFrequentlyUsed(0)+3 + Mutating: nthMostFrequentlyUsed(0)+3 + Result: nthMostFrequentlyUsed(0)+2 +2_20->3_20 mutation finish. + +Mutating 2_21->3_21: + Mutating: 0 + Result: 0+19 + Mutating: 0+19 + Result: 0*19 + Mutating: 0*19 + Result: 0*nthMostRecentlyUsed(0) +2_21->3_21 mutation finish. + +Mutating 2_31->3_31: + Mutating: 0 + Result: 0/2 + Mutating: 0/2 + Result: 0+2 + Mutating: 0+2 + Result: 0+nthMostRecentlyUsed(0) +2_31->3_31 mutation finish. + +Mutating 2_32->3_32: + Mutating: 0 + Result: 0 +2_32->3_32 mutation finish. + +Mutating 2_33->3_33: + Mutating: 0 + Result: 0 +2_33->3_33 mutation finish. + + +Result for configuration 3x0: 22 ms +Result for configuration 3x1: 21 ms +Result for configuration 3x2: 21 ms +Result for configuration 3x3: 20 ms +Result for configuration 3x4: 22 ms +Result for configuration 3x5: 21 ms +Result for configuration 3x6: 21 ms +Result for configuration 3x7: 21 ms +Result for configuration 3x8: 20 ms +Result for configuration 3x9: 21 ms +Result for configuration 3x10: 21 ms +Result for configuration 3x11: 20 ms +Result for configuration 3x12: 21 ms +Result for configuration 3x13: 20 ms +Result for configuration 3x14: 20 ms +Result for configuration 3x15: 21 ms +Result for configuration 3x16: 20 ms +Result for configuration 3x17: 21 ms +Result for configuration 3x18: 20 ms +Result for configuration 3x19: 20 ms +Result for configuration 3x20: 21 ms +Result for configuration 3x21: 20 ms +Result for configuration 3x22: 21 ms +Result for configuration 3x23: 21 ms +Result for configuration 3x24: 21 ms +Result for configuration 3x25: 21 ms +Result for configuration 3x26: 21 ms +Result for configuration 3x27: 21 ms +Result for configuration 3x28: 21 ms +Result for configuration 3x29: 21 ms +Result for configuration 3x30: 21 ms +Result for configuration 3x31: 20 ms +Result for configuration 3x32: 20 ms +Result for configuration 3x33: 21 ms +Result for configuration 3x34: 21 ms + +Applying rank selection to top 10% from prev. generation... + Result: 3_7 copied to 4_7 + Result: 3_13 copied to 4_13 + Result: 3_19 copied to 4_19 + Result: 3_22 copied to 4_22 + + +Mutating 3_15->4_15: + Mutating: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) +3_15->4_15 mutation finish. + +Mutating 3_18->4_18: + Mutating: 0 + Result: 0+12 + Mutating: 0+12 + Result: 0+12 + Mutating: 0+12 + Result: 0+nthMostRecentlyUsed(0) +3_18->4_18 mutation finish. + +Mutating 3_26->4_26: + Mutating: 0 + Result: 0/8 + Mutating: 0/8 + Result: 0/8 + Mutating: 0/8 + Result: 0/nthMostRecentlyUsed(0) +3_26->4_26 mutation finish. + +Mutating 3_32->4_32: + Mutating: 0 + Result: 0-3 + Mutating: 0-3 + Result: 0-3 + Mutating: 0-3 + Result: 0-nthMostRecentlyUsed(0) +3_32->4_32 mutation finish. + + +Result for configuration 4x0: 21 ms +Result for configuration 4x1: 21 ms +Result for configuration 4x2: 21 ms +Result for configuration 4x3: 21 ms +Result for configuration 4x4: 21 ms +Result for configuration 4x5: 20 ms +Result for configuration 4x6: 21 ms +Result for configuration 4x7: 21 ms +Result for configuration 4x8: 21 ms +Result for configuration 4x9: 21 ms +Result for configuration 4x10: 21 ms +Result for configuration 4x11: 21 ms +Result for configuration 4x12: 21 ms +Result for configuration 4x13: 20 ms +Result for configuration 4x14: 21 ms +Result for configuration 4x15: 20 ms +Result for configuration 4x16: 20 ms +Result for configuration 4x17: 21 ms +Result for configuration 4x18: 21 ms +Result for configuration 4x19: 20 ms +Result for configuration 4x20: 21 ms +Result for configuration 4x21: 21 ms +Result for configuration 4x22: 20 ms +Result for configuration 4x23: 21 ms +Result for configuration 4x24: 21 ms +Result for configuration 4x25: 20 ms +Result for configuration 4x26: 21 ms +Result for configuration 4x27: 21 ms +Result for configuration 4x28: 20 ms +Result for configuration 4x29: 21 ms +Result for configuration 4x30: 21 ms +Result for configuration 4x31: 20 ms +Result for configuration 4x32: 21 ms +Result for configuration 4x33: 21 ms +Result for configuration 4x34: 21 ms + +Applying rank selection to top 10% from prev. generation... + Result: 4_13 copied to 5_13 + Result: 4_21 copied to 5_21 + Result: 4_22 copied to 5_22 + Result: 4_29 copied to 5_29 + + +Mutating 4_2->5_2: + Mutating: nthMostRecentlyUsed(0)-9 + Result: nthMostRecentlyUsed(0)-9 + Mutating: nthMostRecentlyUsed(0)-9 + Result: nthMostRecentlyUsed(0)-9 + Mutating: nthMostRecentlyUsed(0)-9 + Result: nthMostRecentlyUsed(0)-9 + Mutating: nthMostRecentlyUsed(0)-9 + Result: nthMostRecentlyUsed(0)-nthMostRecentlyUsed(0) +4_2->5_2 mutation finish. + +Mutating 4_8->5_8: + Mutating: 0 + Result: 0/11 + Mutating: 0/11 + Result: 0/11 + Mutating: 0/11 + Result: 0/nthMostRecentlyUsed(0) +4_8->5_8 mutation finish. + +Mutating 4_9->5_9: + Mutating: 0 + Result: 0 +4_9->5_9 mutation finish. + +Mutating 4_12->5_12: + Mutating: 0+random() + Result: nthMostFrequentlyUsed(0)+random() + Mutating: nthMostFrequentlyUsed(0)+random() + Result: nthMostFrequentlyUsed(0)/random() + Mutating: nthMostFrequentlyUsed(0)/random() + Result: nthMostFrequentlyUsed(0)/random() +4_12->5_12 mutation finish. + +Mutating 4_20->5_20: + Mutating: 0+nthMostRecentlyUsed(0) + Result: nthMostFrequentlyUsed(0)+nthMostRecentlyUsed(0) + Mutating: nthMostFrequentlyUsed(0)+nthMostRecentlyUsed(0) + Result: nthMostFrequentlyUsed(0)*nthMostRecentlyUsed(0) + Mutating: nthMostFrequentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostFrequentlyUsed(0)*nthMostRecentlyUsed(0) + Mutating: nthMostFrequentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostFrequentlyUsed(0)*nthMostRecentlyUsed(0) +4_20->5_20 mutation finish. + +Mutating 4_34->5_34: + Mutating: 0 + Result: 0/5 + Mutating: 0/5 + Result: 0+5 + Mutating: 0+5 + Result: 0+nthMostRecentlyUsed(0) +4_34->5_34 mutation finish. + + +Result for configuration 5x0: 21 ms +Result for configuration 5x1: 22 ms +Result for configuration 5x2: 21 ms +Result for configuration 5x3: 22 ms +Result for configuration 5x4: 21 ms +Result for configuration 5x5: 20 ms +Result for configuration 5x6: 20 ms +Result for configuration 5x7: 21 ms +Result for configuration 5x8: 20 ms +Result for configuration 5x9: 20 ms +Result for configuration 5x10: 21 ms +Result for configuration 5x11: 22 ms +Result for configuration 5x12: 21 ms +Result for configuration 5x13: 21 ms +Result for configuration 5x14: 21 ms +Result for configuration 5x15: 20 ms +Result for configuration 5x16: 21 ms +Result for configuration 5x17: 20 ms +Result for configuration 5x18: 21 ms +Result for configuration 5x19: 21 ms +Result for configuration 5x20: 21 ms +Result for configuration 5x21: 21 ms +Result for configuration 5x22: 21 ms +Result for configuration 5x23: 21 ms +Result for configuration 5x24: 21 ms +Result for configuration 5x25: 21 ms +Result for configuration 5x26: 20 ms +Result for configuration 5x27: 20 ms +Result for configuration 5x28: 21 ms +Result for configuration 5x29: 21 ms +Result for configuration 5x30: 20 ms +Result for configuration 5x31: 20 ms +Result for configuration 5x32: 21 ms +Result for configuration 5x33: 21 ms +Result for configuration 5x34: 21 ms + +Applying rank selection to top 10% from prev. generation... + Result: 5_7 copied to 6_7 + Result: 5_11 copied to 6_11 + Result: 5_16 copied to 6_16 + Result: 5_18 copied to 6_18 + + +Mutating 5_0->6_0: + Mutating: 0 + Result: 0/9 + Mutating: 0/9 + Result: 0/9 + Mutating: 0/9 + Result: 0/nthMostRecentlyUsed(0) +5_0->6_0 mutation finish. + +Mutating 5_8->6_8: + Mutating: 0 + Result: 0 +5_8->6_8 mutation finish. + +Mutating 5_30->6_30: + Mutating: 0 + Result: 0-16 + Mutating: 0-16 + Result: 0+16 + Mutating: 0+16 + Result: 0+nthMostFrequentlyUsed(0) +5_30->6_30 mutation finish. + + +Result for configuration 6x0: 21 ms +Result for configuration 6x1: 21 ms +Result for configuration 6x2: 21 ms +Result for configuration 6x3: 21 ms +Result for configuration 6x4: 21 ms +Result for configuration 6x5: 21 ms +Result for configuration 6x6: 21 ms +Result for configuration 6x7: 20 ms +Result for configuration 6x8: 21 ms +Result for configuration 6x9: 20 ms +Result for configuration 6x10: 21 ms +Result for configuration 6x11: 21 ms +Result for configuration 6x12: 21 ms +Result for configuration 6x13: 20 ms +Result for configuration 6x14: 21 ms +Result for configuration 6x15: 21 ms +Result for configuration 6x16: 21 ms +Result for configuration 6x17: 20 ms +Result for configuration 6x18: 21 ms +Result for configuration 6x19: 21 ms +Result for configuration 6x20: 21 ms +Result for configuration 6x21: 21 ms +Result for configuration 6x22: 21 ms +Result for configuration 6x23: 21 ms +Result for configuration 6x24: 21 ms +Result for configuration 6x25: 21 ms +Result for configuration 6x26: 21 ms +Result for configuration 6x27: 20 ms +Result for configuration 6x28: 21 ms +Result for configuration 6x29: 20 ms +Result for configuration 6x30: 20 ms +Result for configuration 6x31: 21 ms +Result for configuration 6x32: 20 ms +Result for configuration 6x33: 20 ms +Result for configuration 6x34: 21 ms + +Applying rank selection to top 10% from prev. generation... + Result: 6_9 copied to 7_9 + Result: 6_21 copied to 7_21 + Result: 6_23 copied to 7_23 + Result: 6_27 copied to 7_27 + + +Mutating 6_20->7_20: + Mutating: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)*nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) +6_20->7_20 mutation finish. + +Mutating 6_22->7_22: + Mutating: 0 + Result: 0/8 + Mutating: 0/8 + Result: 0/8 + Mutating: 0/8 + Result: 0/nthMostFrequentlyUsed(0) +6_22->7_22 mutation finish. + +Mutating 6_26->7_26: + Mutating: 0-nthMostFrequentlyUsed(0) + Result: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Result: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Result: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Result: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) +6_26->7_26 mutation finish. + + +Result for configuration 7x0: 21 ms +Result for configuration 7x1: 21 ms +Result for configuration 7x2: 21 ms +Result for configuration 7x3: 21 ms +Result for configuration 7x4: 21 ms +Result for configuration 7x5: 22 ms +Result for configuration 7x6: 21 ms +Result for configuration 7x7: 21 ms +Result for configuration 7x8: 21 ms +Result for configuration 7x9: 21 ms +Result for configuration 7x10: 21 ms +Result for configuration 7x11: 20 ms +Result for configuration 7x12: 21 ms +Result for configuration 7x13: 21 ms +Result for configuration 7x14: 21 ms +Result for configuration 7x15: 21 ms +Result for configuration 7x16: 21 ms +Result for configuration 7x17: 21 ms +Result for configuration 7x18: 21 ms +Result for configuration 7x19: 20 ms +Result for configuration 7x20: 21 ms +Result for configuration 7x21: 21 ms +Result for configuration 7x22: 20 ms +Result for configuration 7x23: 21 ms +Result for configuration 7x24: 21 ms +Result for configuration 7x25: 21 ms +Result for configuration 7x26: 21 ms +Result for configuration 7x27: 20 ms +Result for configuration 7x28: 21 ms +Result for configuration 7x29: 20 ms +Result for configuration 7x30: 21 ms +Result for configuration 7x31: 21 ms +Result for configuration 7x32: 21 ms +Result for configuration 7x33: 21 ms +Result for configuration 7x34: 21 ms + +Applying rank selection to top 10% from prev. generation... + Result: 7_9 copied to 8_9 + Result: 7_10 copied to 8_10 + Result: 7_13 copied to 8_13 + Result: 7_15 copied to 8_15 + + +Mutating 7_1->8_1: + Mutating: 0 + Result: 0 +7_1->8_1 mutation finish. + +Mutating 7_6->8_6: + Mutating: nthMostFrequentlyUsed(0)/random() + Result: nthMostFrequentlyUsed(0)/random() + Mutating: nthMostFrequentlyUsed(0)/random() + Result: nthMostFrequentlyUsed(0)/random() + Mutating: nthMostFrequentlyUsed(0)/random() + Result: nthMostFrequentlyUsed(0)/random() + Mutating: nthMostFrequentlyUsed(0)/random() + Result: nthMostFrequentlyUsed(0)/random() +7_6->8_6 mutation finish. + +Mutating 7_12->8_12: + Mutating: 0 + Result: 0 +7_12->8_12 mutation finish. + +Mutating 7_27->8_27: + Mutating: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Result: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Result: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Result: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Result: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) + Result: nthMostRecentlyUsed(0)-nthMostFrequentlyUsed(0) +7_27->8_27 mutation finish. + +Mutating 7_28->8_28: + Mutating: 0/nthMostRecentlyUsed(0) + Result: 9/nthMostRecentlyUsed(0) + Mutating: 9/nthMostRecentlyUsed(0) + Result: 9/nthMostRecentlyUsed(0) + Mutating: 9/nthMostRecentlyUsed(0) + Result: 9/nthMostRecentlyUsed(0) + Mutating: 9/nthMostRecentlyUsed(0) + Result: 9/nthMostRecentlyUsed(0) +7_28->8_28 mutation finish. + + +Result for configuration 8x0: 21 ms +Result for configuration 8x1: 21 ms +Result for configuration 8x2: 21 ms +Result for configuration 8x3: 21 ms +Result for configuration 8x4: 21 ms +Result for configuration 8x5: 21 ms +Result for configuration 8x6: 21 ms +Result for configuration 8x7: 22 ms +Result for configuration 8x8: 21 ms +Result for configuration 8x9: 20 ms +Result for configuration 8x10: 21 ms +Result for configuration 8x11: 21 ms +Result for configuration 8x12: 21 ms +Result for configuration 8x13: 21 ms +Result for configuration 8x14: 22 ms +Result for configuration 8x15: 21 ms +Result for configuration 8x16: 21 ms +Result for configuration 8x17: 20 ms +Result for configuration 8x18: 21 ms +Result for configuration 8x19: 21 ms +Result for configuration 8x20: 21 ms +Result for configuration 8x21: 21 ms +Result for configuration 8x22: 21 ms +Result for configuration 8x23: 20 ms +Result for configuration 8x24: 21 ms +Result for configuration 8x25: 21 ms +Result for configuration 8x26: 21 ms +Result for configuration 8x27: 21 ms +Result for configuration 8x28: 21 ms +Result for configuration 8x29: 20 ms +Result for configuration 8x30: 21 ms +Result for configuration 8x31: 21 ms +Result for configuration 8x32: 21 ms +Result for configuration 8x33: 21 ms +Result for configuration 8x34: 21 ms + +Applying rank selection to top 10% from prev. generation... + Result: 8_16 copied to 9_16 + Result: 8_23 copied to 9_23 + Result: 8_9 copied to 9_9 + Result: 8_17 copied to 9_17 + + +Mutating 8_14->9_14: + Mutating: 0 + Result: 0-5 + Mutating: 0-5 + Result: 0-5 + Mutating: 0-5 + Result: 0-8 +8_14->9_14 mutation finish. + +Mutating 8_15->9_15: + Mutating: 0 + Result: 0/9 + Mutating: 0/9 + Result: 0/9 + Mutating: 0/9 + Result: 0/6 +8_15->9_15 mutation finish. + +Mutating 8_31->9_31: + Mutating: 0+nthMostRecentlyUsed(0) + Result: 3+nthMostRecentlyUsed(0) + Mutating: 3+nthMostRecentlyUsed(0) + Result: 3/nthMostRecentlyUsed(0) + Mutating: 3/nthMostRecentlyUsed(0) + Result: 3/nthMostRecentlyUsed(0) + Mutating: 3/nthMostRecentlyUsed(0) + Result: 3/nthMostRecentlyUsed(0) +8_31->9_31 mutation finish. + +Mutating 8_34->9_34: + Mutating: 0+nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)+nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)+nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) +8_34->9_34 mutation finish. + + +Result for configuration 9x0: 21 ms +Result for configuration 9x1: 21 ms +Result for configuration 9x2: 21 ms +Result for configuration 9x3: 21 ms +Result for configuration 9x4: 21 ms +Result for configuration 9x5: 21 ms +Result for configuration 9x6: 22 ms +Result for configuration 9x7: 22 ms +Result for configuration 9x8: 21 ms +Result for configuration 9x9: 21 ms +Result for configuration 9x10: 21 ms +Result for configuration 9x11: 21 ms +Result for configuration 9x12: 21 ms +Result for configuration 9x13: 20 ms +Result for configuration 9x14: 20 ms +Result for configuration 9x15: 21 ms +Result for configuration 9x16: 20 ms +Result for configuration 9x17: 21 ms +Result for configuration 9x18: 20 ms +Result for configuration 9x19: 21 ms +Result for configuration 9x20: 21 ms +Result for configuration 9x21: 20 ms +Result for configuration 9x22: 21 ms +Result for configuration 9x23: 21 ms +Result for configuration 9x24: 21 ms +Result for configuration 9x25: 21 ms +Result for configuration 9x26: 20 ms +Result for configuration 9x27: 21 ms +Result for configuration 9x28: 21 ms +Result for configuration 9x29: 21 ms +Result for configuration 9x30: 20 ms +Result for configuration 9x31: 20 ms +Result for configuration 9x32: 21 ms +Result for configuration 9x33: 21 ms +Result for configuration 9x34: 20 ms + +Applying rank selection to top 10% from prev. generation... + Result: 9_19 copied to 10_19 + Result: 9_26 copied to 10_26 + Result: 9_13 copied to 10_13 + Result: 9_14 copied to 10_14 + + +Mutating 9_4->10_4: + Mutating: 0 + Result: 0/14 + Mutating: 0/14 + Result: 0/14 + Mutating: 0/14 + Result: 0/nthMostRecentlyUsed(0) +9_4->10_4 mutation finish. + +Mutating 9_12->10_12: + Mutating: 0 + Result: 0 +9_12->10_12 mutation finish. + +Mutating 9_31->10_31: + Mutating: 3/nthMostRecentlyUsed(0) + Result: nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostFrequentlyUsed(0)/nthMostRecentlyUsed(0) +9_31->10_31 mutation finish. + +Mutating 9_34->10_34: + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) +9_34->10_34 mutation finish. + + +Result for configuration 10x0: 21 ms +Result for configuration 10x1: 21 ms +Result for configuration 10x2: 21 ms +Result for configuration 10x3: 21 ms +Result for configuration 10x4: 21 ms +Result for configuration 10x5: 21 ms +Result for configuration 10x6: 21 ms +Result for configuration 10x7: 21 ms +Result for configuration 10x8: 21 ms +Result for configuration 10x9: 21 ms +Result for configuration 10x10: 20 ms +Result for configuration 10x11: 21 ms +Result for configuration 10x12: 21 ms +Result for configuration 10x13: 21 ms +Result for configuration 10x14: 21 ms +Result for configuration 10x15: 20 ms +Result for configuration 10x16: 21 ms +Result for configuration 10x17: 21 ms +Result for configuration 10x18: 21 ms +Result for configuration 10x19: 21 ms +Result for configuration 10x20: 20 ms +Result for configuration 10x21: 21 ms +Result for configuration 10x22: 21 ms +Result for configuration 10x23: 21 ms +Result for configuration 10x24: 21 ms +Result for configuration 10x25: 20 ms +Result for configuration 10x26: 20 ms +Result for configuration 10x27: 21 ms +Result for configuration 10x28: 21 ms +Result for configuration 10x29: 21 ms +Result for configuration 10x30: 21 ms +Result for configuration 10x31: 21 ms +Result for configuration 10x32: 21 ms +Result for configuration 10x33: 20 ms +Result for configuration 10x34: 21 ms + +Applying rank selection to top 10% from prev. generation... + Result: 10_11 copied to 11_11 + Result: 10_19 copied to 11_19 + Result: 10_24 copied to 11_24 + Result: 10_25 copied to 11_25 + + +Mutating 10_8->11_8: + Mutating: 0/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) +10_8->11_8 mutation finish. + +Mutating 10_20->11_20: + Mutating: 0/6 + Result: nthMostRecentlyUsed(0)/6 + Mutating: nthMostRecentlyUsed(0)/6 + Result: nthMostRecentlyUsed(0)+6 + Mutating: nthMostRecentlyUsed(0)+6 + Result: nthMostRecentlyUsed(0)+nthMostFrequentlyUsed(0) +10_20->11_20 mutation finish. + +Mutating 10_26->11_26: + Mutating: nthMostFrequentlyUsed(0)+2 + Result: nthMostFrequentlyUsed(0)+2 + Mutating: nthMostFrequentlyUsed(0)+2 + Result: nthMostFrequentlyUsed(0)+2 + Mutating: nthMostFrequentlyUsed(0)+2 + Result: nthMostFrequentlyUsed(0)+2 + Mutating: nthMostFrequentlyUsed(0)+2 + Result: nthMostFrequentlyUsed(0)+17 +10_26->11_26 mutation finish. + +Mutating 10_28->11_28: + Mutating: 9/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Mutating: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) + Result: nthMostRecentlyUsed(0)/nthMostRecentlyUsed(0) +10_28->11_28 mutation finish. + +Mutating 10_33->11_33: + Mutating: 0 + Result: 0-18 + Mutating: 0-18 + Result: 0-18 + Mutating: 0-18 + Result: 0-nthMostRecentlyUsed(0) +10_33->11_33 mutation finish. + + +Result for configuration 11x0: 22 ms +Result for configuration 11x1: 21 ms +Result for configuration 11x2: 21 ms +Result for configuration 11x3: 21 ms +Result for configuration 11x4: 21 ms +Result for configuration 11x5: 21 ms +Result for configuration 11x6: 21 ms +Result for configuration 11x7: 21 ms +Result for configuration 11x8: 21 ms +Result for configuration 11x9: 21 ms +Result for configuration 11x10: 21 ms +Result for configuration 11x11: 21 ms +Result for configuration 11x12: 21 ms +Result for configuration 11x13: 21 ms +Result for configuration 11x14: 21 ms +Result for configuration 11x15: 21 ms +Result for configuration 11x16: 20 ms +Result for configuration 11x17: 20 ms +Result for configuration 11x18: 21 ms +Result for configuration 11x19: 20 ms +Result for configuration 11x20: 20 ms +Result for configuration 11x21: 21 ms +Result for configuration 11x22: 21 ms +Result for configuration 11x23: 21 ms +Result for configuration 11x24: 21 ms +Result for configuration 11x25: 20 ms +Result for configuration 11x26: 21 ms +Result for configuration 11x27: 21 ms +Result for configuration 11x28: 21 ms +Result for configuration 11x29: 21 ms +Result for configuration 11x30: 21 ms +Result for configuration 11x31: 20 ms +Result for configuration 11x32: 20 ms +Result for configuration 11x33: 20 ms +Result for configuration 11x34: 21 ms diff --git a/dat/results/results_difffile-large.ods b/dat/results/results_difffile-large.ods new file mode 100644 index 0000000000000000000000000000000000000000..513f2c869ee9f5f502ca7ca1fd58a179273b71cd GIT binary patch literal 36022 zcmbSy1CS?A)8^Q=ZQHhI$NG(J+qP}b?AW%w!yRkKJGOE2e=ol8E-v1CBknSyx~nVt z$%@L(%F3s!`-dzj7#a`|6cCVByuD1Q4R;g+5D?Hm<+};U*3#D0#nZvm(80mR(%8_& z(%z2I&CZ0u-q6|7nZe${)Xv1-*wxn5&V|9*!O7In#M#2s)aA#&bV5Nv{Y&S!n*SE$ z@0y~Km8r1{5i{erYC{GOTbtMvN^-{mAzoGZROC~3OGAm_x=IWT?y62 z)7Ajlvf*G-H&>m2UBT03SC#=$=OSws5`|&q#ro8+GN?fy&Mz6`!Vs6u_{FNr zQ(CD5dT#^QQ+RFUxUjl4i+@X$^Tiq>!6ZWV>{nlf&a6EBhBX{*v&1-GfV$neCw+w{ z5D!E~44a%F(EZo%sMc4oylS`dbDQfea6uGJB}}#6g?gDLvP23Mxef(;F%=NKWj9OG zpc-R(O-mO{NaJu;jHdrX782^FwcCUZ7zoG=1PJK=ZgSNB-Q>#SyO25yzeSN5W_8ZsnVY5irHQO>;2iq z(!-@phLyV2u~lY20)|AE;?(y2_(k#-N$^5|f3ngj1f!I!JPan;;%>4cE`ZKu9=GjA zI#R@F#)a5H)YVXmScgVJ`A;$IapjInTNyplX{X)q8V%*&R2w!N<64vhCW9@MBlwkM z5l&XQmMJwXY(^s$+&@~l_-wAjCr_Mv+AEJ=Wjqcde($~VIA|8Rc65uKu_P#>Sz~rx z&I{QBvZpSW?Ccln?fN$^Kab7TbKs- zdfjrCSkR_shNw<43YbvluRmJg`1RPuFbJup3@lh&u%B7y~}X5{JMZ z6`)2@iha6SRiv86q%zrf3_;eFTSLbXF6)-9Sv9(kcgELIc#{oJ;rzPGsp8%DyA}mG zyCky}Eg%6b2}m8O=&iB-2;OgeTcXk2vJ);-H`XX5Me}^!JWPbt>Wc(uSP;nROfQ$p zPw*5L#}hv~7jjNl zW;wmPy7Pap4HYv2z2j_!Yon8!kx3V`j%W4BaiO3=oZibTNdXd2$ z)K%Sxmc(8;#BNPivItE~sxc$_WOiCdr7P`?b?b|%YADaL;x=nj@3vt|Znvg|i*s@N zeg5xj_sMz3bF)&|g7pn|oAaaOf?sjKr=F2yf5jb(N}eBCwq&(x`L8_qI>+Wr`R;7?d(681kB)ZKt z3Zx$+;*Y}AFA3~3;sm#uTAq%iF6(k8CcVK6KRrHL4nbzeUX?rXf1)T%&RgQxdJ7s? zL#x>`fmaUYzW5zvUZp+Wl)WaRMs}3uZK^6F$>R)b34r08fD>47J?qXl6Ze9M0M?l9 zV%n83{;Dm0d3`((P7oabRHNvtJ5LaiQf(f0aD~!f&Gp7hkC}qV*m@3wE@!tk+L+4G zV{|94QDe<33$8>`I1&CU`iJ`pjL`q|erUrdg1=^ox*?kvWM@&vZRNcOUZ(s82+UH4 zZ#GNEVhjPi1c*}uoKPS&1C?Av)n3P)ZZ)U;9F(Fed#Z8H@)&HfQ=g3*KFe@=0(=f~ zG9=a7+WpCG_r)@YTMdV9>w*4pU5rGGDtz_&fm3k;&y`!`t&UGibik&wh7!mn0nQ6o z8gHv%#Ld{t_xJ70>9C74`q|X|)n{`#TSf0-$sDnHJtH}G;*Y6;r474o;Ovc9X0N|Q zYmkdphT%>kvsThKHQPy!s+YujDD?vX6grA1eS@ebdxHW4@MSxC#J0^DyRO9@8}lP0 zrEzX@R52@6a>3no1aoEQU&7*LqsaQ=#$u;(Haffz$1tE7L|@<|M0BR8ay{olqQWEW zg`HH?0&07_jR=B@%L6slkfFBA1HM|4gp*ll(EKH0 zw)p9rqvw+)6K7AxPi5^CcO~oja+0z?n|^nCsdGaSJ=PiP@A8Fo{2r?$nK$)XOQ1DQ z3i~Lf{7`+=^+_{PE=qLnHa`v7=4G{tEc2G6sCf|h_3~M7wG-xH$+PY3{1I#!a?=vK_L>TF7C^@b6DN}%?gZeOnyqGA* zl0}{Ul2djPz6m5tlt&n+UQ7249bt>8qsQ5EPS?%mBlIlX)C+sQ;o04BF{dy%k;0m= z92W*8%}73j&&s9M6S*nVVgG}m1)&+oU8RD&G(tE6ym(rf0lv@&X;9eb@#JD3xXnCw zGM=d>R^b~tAYM89C0WUrGHjI8fN9OxzH8 z%&Naw9foL6)ZFgrz3W=SFta6RACL~wV5c7r{ktSkuJf5|wU@r4<2vhFgmxf4_~2e&a881WUhUZ0 zgaPdhg`)|vrm%bIPt&>YVd4`oft32hl@qfsLWk~1GhEV;@O56ftdd`b?=V;(&ep9b z8IjhkR}lpD4gx*~gjCN{dHRsmI>HlD#M$P>D0yIxFyd{ENovvqJh#t&vU*Uzh?)n=vdWbXUUg+#{_5)VuqVMx^EVTP`y zc*}-V#8Gx4EO))7)pnhicHSLp{8^8x59glKdtgbVS?baCDB!o3h&wx&ia3k%y2$g9 z_fI?M>8+t$#@oCT^6*j9P)OW&TlIQ|IwI(R%u>F)(1}zYM35^}o8n$q#+(^WO{ZKv zxgsd>bxpzhm}6nB_w%`482-eaL49y1{^(PGJ)T{h??0E9XS+&wg-^nz;!W(>84{dAQ zO%1;4eEHAVe?k6}O^|Vjr^0=+95=@Q$|nAc2K_f*`L5u67g2jVGfQ(umGfp%mD=SPx;5Bsur%cMs|jlHqMML|5ashurrVRp&$tlg9Gz@ z3%s(FP_vRT z@X|3b)3I=|)049^(+e<@^RUwL@bHi@3Q=>4aqx+8i^%dxtMe+EigVJ4^RX%M@`!MW z%82r)N^pyQi-e4Xw7iVCh?In!g0zUNjI5NLs*JL>nw+Gvypp!EjE1_Vh@ye4rl~r> zMAOJd$K2IKPTWL8#uT7osB36#sOe~^;9{n2Vr*h)YGrO=YGP?^ZE9#^X=-g_ZEWLi z=U`{$=;>x{;$iFH>1gHZ>gwd`>FVj@FVX>rEMRq>kw#U8(`rUYU`Ki>=WkT zpJ*SL>=GF36Bz0p673fe?-7>f6;tS!SQcmx2y)a5bF&O^^9uHI3iS1i_Hl~#^GNiy zO7M3L@e2$Ha1Raii3xCx4)KYP@JS7_O$u^J4)IKh@W~8w$_V$)ige3~_Q_4~D~$Cn zO7sf}2?-313XX`43JZ#f2#$)54vtO^ip`FQONmd64^K!9Nz9E&OpQ&+PL2sqjE%~P z4NQtnNllE&O$^CNiOJ1~PfkusO3g~n$jwSk%E?I1%E}5$D~r#sPtGn*%&pAIEzHTQ zh%0E!Dz3~ZZ^^IkEsPH=NeeH|Nh!+9s?1Gl$crw@FRCkuuPDlFDvWFUnbBLHS5i_^ zSXxo`v#g}DrmD2CrlPp2s;a1}si?NIvb?^kw!W^uuDHItroO4FsjI%EpsA{;v9_wS zrm(T5sjac9@mpFunmf8XTN~S(I=b7Ny1Kfus{8XA1}oY}s(R;|yNA05dg}UTY6ccM z1}8ekmip%R`fIa?8*@h5evWiE5A_XC4t6XKR4dYc2RL>I)kNoNF%`y{0uph= zC_m0|WDW!945yML8_8u^Zt=dHXA_TnsAAgxO0MscRI2XpOlRKx%H+Pf>h62WiOi0D z@ofIX@OnS{YjlL;5c*E{9@w4jaKm{lW$cndrR>Tl82f6=z&~uZd@!eDAjY6}(}1Fw zNz#tVV@A}u98#1sgW~Aej%6f3PAe1tY-r22X2Bp2mT-}cqqI0;F{@WI+|ymBDCw^lDLq(IAz=A61kns2seXjRw z9Y%@Dl=9yGzV^h?z}x;+`EO=AKMUbg?t9si}ka6KpOtZz+DQFw31&y;1i5mp=A zzsFa$rv|Wom(rcq55Zf}6}g@5%j=Lsl-#}6N?{FNg^8+$8v+)Stvs6G4Qg=uwCr`B z6w)6BW{wgU-IL-~m#Ylb)b;oF)ka=V!LXlY+3PPZhegT@aAoL-{LG5cobtST1X;5f zB|1VEY;OFGy8@kS4?@cCd@i{DRve6zOtihGfE%<9ZO2@RJHLpqVf7b@$_@ro!y{j4 z=*lce?~^!YIm656Cj!Gu6zA}x9!XV`x5Lm`!CO_xZ8i%yU;PcLZF>oqid00FQnLjK zX6!aP8@=wR?Kamb6#}+`zHIq=wN{_p)~LToHs}^IZPIKb?WTIa)~|d%4&VH;8Y>=! zO`MO)G{byyx=y5D?{P4E`8m`1p2||fod{P0tPLtcECCy_x`ZRPOzCKM;QW(hNuWd`jy0dm9S#HCpe z3saN}w%FsO9kaKQ7U)I=uY=x@=EX$g-HF8*cIcAByIn$>)LAmJa}+}FRTrqU$dvc4 zM5)Ex3Z-d!j}mG(;j-~qH_A^eJ4Pq0zcH~%$26ZH`9XU-Zz?|kKhSzYzr>^HpGnHe z1$iz{E(m{bisygwW}zTn7R}nosch@oW{{TIXgTP&rBJ_h^cWDX(A&Mhs-foF+E zgH9zT_N@T4XDekMUZ`*fs&RNR2k&-DK>bS_tlTZII(lsJrk7D(zwWjD2-I%JU4CRc%K24%E#OR0bAwS5abF2-Mtvzy^gtlQAuPz&n}_Up zmdQXe{jL}6no~Kj@TfWr!3JfMRCW;0;YU&pi}IctLd|jS7j`fDZfHr1t9g7NP|d}% zI!1Htop>;D!8LP1y)kPCiFGY7#FE;8^%qEm$SWDrLIzJR4Rp|M>_Wz@jJy+IeS1Sb z@G0Q-bUOgR7u$lz)Pg?eD`~AG7*Tm+ebfkx_O1bzv`%vUz~O`u8V&9$Id2=HGs1`% z_){G_P=nRfiH!89DJeZAsaa>Q;ftvc7jKquNC&S?c6Q*H`cqQ%X(GltU>Qn|(I*Vuw z()TZi^0U1!%4l{Z2ZV^-q@D~>(yG&AS4+KZ}V%H9YAPaA+ zel{GS*gj?tIxz%Fl<6|MY%Nms*I)`iFI6v zxZ;B*5~^^Zed{f0CnoVJH33%OgSPACSY_-Cnt@t5bdZZu;TW~HP)`JK^8jB^J8vi^ z17BFARswQ~9A_m-`C}Lt%%;v*Mi=@GpV)$U-kyZ>& z3d)JRvr=na!2ttlCJR$KY&Zy$JWHW|9cp9F8}bRKhTXW;ZnDoXF7H^R&K--v;P&$XSM>4nJ=ZlO*GX96Frc$UJ!twARPHOn%lC7WBG zTxCP3n}xVv3GGyjS>qXP(3)S^!S!#1AhhzLyIL@5t;%~WU?|vo zPFPEMr3KrZorcfPuzT!S_+ZqJ!g2sJ(lNb-mf`D1s?FLM9rA61`S=iAr-^AKd?HcB z9M0hYIWmv~EzN6HZoDFmh64RdbbPF{f>ZPJCKQf-?bhesTBhSKy+ zfmR8)qai%tZnH@JQRq&>peTqY82|8CWDiYtTU$UmLcV-bOtW2layT+|oPOhDK=wOW zYX;~_EpMctB_v!dY^>lG?n<9~G@R;N8K!4Y!nwnX29HNW=YynY-PeI&^sYtLlyQ2O zhcatb)RTv6Hia=VW>X=PhIMC;T3ME#SHQ~qeYw$x9OR=#{1vx@8kqZ+OZ;Jfp7CDq z7$Tc4-@=lMl1&4scNXJ79aNsh`W>uhn#bXVHv-$)6C3u(MwR6(u%<#X)FV5)E8>+M z3MuD)*N*L};M|g!UCbYT`I+>rM?ib9J~Q@lOmsIc2}9F->$`u?$GPqfjdNIg#tb|9 z=yRP_i$A9d!Y_a2s9^kK?EzxEK5>?rRVIxX-?f{f<;?W^#u6vjtBzn}EF<;LnUv&q z^+M$1uQL=0BBezogkb_!g}a3VKxP)=QZ&lOn4ZQ$Qtt;i!1}kkjEq1!Vl)n)!I@$O zIzb%(fuEN(M7shjQqaqZM2?oo^{Q;qrA1;|HWlMG+qX+;8#<;O)e!Qe;t`2a_qW6} z=r8?J(sUIT_*jM(1|LKj!~@tKOH!T>=GCfbCA$+CN?8%j3m3}sXEY-QbSj+~<9nEw zDeVKB^8-j|5;tes8B);7Ar>VE&dN%2#KuBjS=Pg|HFsqIHNb!d*aH6dvJ~3?N#pY{ zdYGRaWiTKU&2CoZlXKg1MMoFicaex_BAP~?Pga^T1bfhwwqR|kkqA*Gh)RwwT<|DE zq!i-sgK?>#xg24o{rudQ)S^m*(nwLVVFJ@IO;rJfk;B4`qeH`ztv?a*{j7>`RL3(_ z@%$j-oi`c0=Wzu{(9sEYBXCqzVoFHR)1p+xQ@1-oU?E_+U4m~^oKY4gXeitNHvh1cU;$cE98N@<&t9q#ZBwnKS zv8nsP4`md!rN}t*>JE)?v;&KV*}^t<*d(M3YOy0HJcGV)Y!AEj(+bLPj)#ixY#H@s zZ^ohmD#-ptYWNWTBrp!i{ENW_r|e@DKD@N(5-BxGfw;m#U)H99m(}m3TfM>@ytLsb z>#7Ch&t8cE%YbA%A+iu<-_XRURR=gQa}zj6;ZsmzhDK=$W-xB4EG(3?C<(1^<8S)0 zxn&dyZ``%SqLjrH2|+z9cE%D5Z;b}|lDGZD84fB}U96@?x}Smu=0S|Fq8Mf6l04@;0;Nn?Ddom3&b!g~0VFg&k?85yB?qeFA?V6xdgUU*d zj)%Q_d&TYHR1(|_;6{stG#(8tbp=vBbB5R>M|+r4SQS6p8>@a6yydm^nNOzMPUYC6 zi|Q?0&Su}DM|4hq5|mM4meHl4kXuDf3hNfGPRzy~AL-qjCnB`f)^Fx#Z_pE%?tRX? z>ZS4$$CWS5S_jsqK-4(vZg5vafG^Q}FD(pitdMtVg^8)e5;Q@(NQqI~nM%&|!_7jM zuN<^|9Aq1Xn#*aN=NOThrdErXZ3=R78ikmPk{@Kr;mN9=Ih># zd}~G_?g`-8H^KElZ$h@71j6qv4s@qV!ohiY-)*Z_1?!=d1ys_vSt+lL!~gsWNR2`h zaN70{PASYgkSl&q`<|EhI=HNRMtUjpu3u)6V**eq;#a}1v>sFW!(eI>3;Z!SWCyv1 zr6j&uR5Fr0s4&X8RXu1>zqL84hmg|Oiv#8pe;gcj(@0g_8)`uf7V`4Z-YCBqaB_OE zFqU;O!&iUy=i&VH7mO$+Nq_RH7>h>l)U*G=eS$oYO-^t%Z9xNyP<}H>TcT+nyBtiL z&vFFs#VQDESTWA3wJ{of7*lqq=P|(-qk3?o-geWQQI?^ny+QXITL+iEzZbVj`p-Cl zzP@qs^QIy@2ZtLQ$K{CO%IN5}XlyKrIIf+|ChPX9M@A6ld2G8964V!oQw|WFIUE6X zo;V^fRMfeJkGb*w;pphrVgNzclaz5W@-PCy46@RoNs3cqlY1fc=tj@S7M;vA{$5gM zLPEjEtz6~@sd!qiP+miWL@G6V6xb=rZ+ch53e8^@3U*K7l~M-&9B`e^PLA6)`gV^Q zyx_blU+WL_#oT8)Bf1YrczSW+Eh-%yHGbeXv=1*;<>BdnYCX9)-*6zz1M6Gs@lKSn zK^nb$s|2eq5I8d|wK|nZl6K%zFr@T`ub*Bb1LQ#MA~wn9pi|bFQ5?B}tJV5mnIjJn zp;?ln>v7=0W`<$c!-X0T$q4RX#)upXcgK3?lMMMI+u?%HuIjLq_Kp$~*s8lkooXH5 zd~=heRV@Jg3NMg!qCXNWKxG0f%@;JoG%KLM&DSSfa1E!Ba8-ppY1n@5#Uo+*z_;ba zPC8P*)Hl0 zsV9-5ZCEOU6O2e`TfVNGyj3U3K|1qgCmf+dJNRdE^cel}L^;uJ@>3bqzab zeog~adrq*=9h7VpK9RMfUH%q&l976|)tn1lJOl_A3Vl>t?o`8len`%!E*M%{1j2kL zaXx9==$S*o_C(C9D6(+Uljpo-)zepq?5U>WP1NKAT$p(2mZ+}~iTybXHY4;f_AG^- zqma;`BUGICdpF^JFn3IQ*coX0%?~z;bV@diXLQD({bA@D-C|^J1)#M3ppmGwOg2ge zkso}KI>qx|yV6kQVc_`$%Q@|@=@?}hxx8i5BfInGx|WlPhl(jO_XhqT7k|3oR+JIY#z1cx#uY1Y5B$#`yjq!TfV5! z-3Lk^6R>VS)DjjCGWDUu=U-#S>dteLIvl)pGoc){lC6c4*ek#Y;AhHWg0D*Fg+JG1OW|4Y1w&kXSaeO!|D8 zhOMDY7DsQ%kQC6XbrxHU3Sg*dx&f40%tY(A!EG}Ly?W$M%ZX%n;CTGH`Ht$cvJJ_qmIo771)7Jrrlfy9&d{3MQ^`oBjl~UzrvU7@qw_mUqOJlL((! zl@%%;^7%!yoW_~qH9&4tX29li8h9YxylD5n#IkLSbR{s$UA$(^hAsO1i|~qBA4|a8 zWjHI!xSO8a{gJ^fanu{{yf!83GU;Gb^d>&lmz`^sFl&FI$)ZBpNeK&m}vod5%*dN*!lcV6{ z@-bj|;Uy!A<)1~xc*C%9iU9|(g-UV&hM@IlHMGn-!r0{7$9`>+en#|r0U+S4254Xjco85_0vki&6u_WE@`ogG>i4<^AP9ns zbkc-v7an5vo!dIA%AmR6s>Ib4M0RdH4Gj8{&tUd$JDnmrHe4!b>ZhlStjJGkh|Yg* z(xuaUbLL<+k%6n+y-wgbm?bbG0uz8 zB!*|>VktRh`iy?|qwbWc*5ac7RVGONYKeZt`B3@MMN|F!0%-`1u++`POM!u%#bD=F zeZJ5?rS`(7wsDAJnO|??PsCRp0`jKvw&QQTWQM%qtkwDX^d-kEruF2%+Mp&m4f*KC zi-yG^)T|s`BgSnX65U1wT_c7~T71u1*sa$bxN(Tw=O5iecF0<>J4Wsvwivj;^xeff zVdd&;uS(oTtI|T0*sXBU1EFmdexS%b=)c{gynYj=&6uN}BSC7MnLypc2JJ)fzSP)+#UQDeJu8y+jgpU%} zOOqB`uRK30wM}&tGp{_4-8?KMS8;-{Sg2G*r?4{i0g$25zA&alu#L~+V(a!o!84)Z z#kyS-w@6SesY0Q8?qEN%J9JH^P1+yCuCZ7-6(fVaGw70;xs)b^LZdha=V+nR%&eShq8e@I^A z0|ze$+j5zx0xH;R=1v>k0F(Kh{#Gj0S?{p6tNt}{BORv2PYuu63nvFo7 zl@=X;8G)0q1IHVY0g-SNNZqwV@Q#kc+?)}EN+Rgfd%_K(axj{=agqk!y{Ci zUtUjb=xBc*96u|J?EhL#$>txI5f3d5w0V$ldMImje(GfPXP6k^Nr*mQC2rWHBV&+| z0(e0?GRs4l;H3Qd|;k_y*%CxfXGWo$|>J0dGc%8D-*pZ!!l z=!HOh1x6=3c2g!HYpcqz zDi@)tafaG$a1;}C2lZV%h^V$$FYU8CRMj;8wztqzWssYL78ObFm z^I<$)+*bF+d3P&|(8zSp*(-LhGOpixz0}cVuKN)LW4^tpDE_g2%Xuua2J}eB7y@Qb zzGf!i)2UbO72D^oNDJgUFw;rNGTtaJCd_>ky9!?~WD!1pD-+0ye|(fRPknq-dfnFc zGg(h+m2G;4?Pa*HJJO2_{*1mw0|y*9&AkR(IJ4vdqESr{Q*j-Sk`tqsjIGgJxVF z`X|7FuI;3TKYveGubSDFMU?Q(g~EQ}^O&mp7kpY~0K~9tYTIEuoc~js2uC_bPzWe5 z(93!nKF!*XgIB1icNa$W;2&|((~XK?1Lsn|)}7jU2^h|t4udCssv%-0^BD=rt&qlP z6JDrR({s0G>b`jnpvO?AR((E#k509X=d9YKDx{~UBkZ7kSHfjk9~J;6vpA|lro0C` z{u2kS{d?vY;$ez@$C`X1ZgMjN`aYmxaO=T>rn=Bmsg_{0ZakbVCWQr|kA!Bf@Qh6~ zRSQI{L~Z5+!0^V(G-J;N#M=$Jn09R)O&YR$pDPg9$t2;U>v`oTlz~vndt-4b_}IkY zIF-{7*>PN%B5Of{d#wB~@qx@or!s9p%TUhY1l206L~3?ew=IFF>OP2dHDYV-pC9zS z=)XWXYtAXb&tuH})tgnpI&2@_=q$7)>!g-&oQKYW`b%!brNxI8wkXEcw#}^6-<&nq z6YiUCr8Y&u5qF+Wiu3bJ>}J}z>!+j}SH zq)Urp5R8v_A)-|?M1mqz5G?N-(VyLIMGXDJl+9B4Sl! z#R)mAr-YVp!>mHq1w|4lMoLnRVAc4wn1xZUE=zt4(THP0poOoX)=*Z(xsqlY$r>I~ z9o9U>Ev`wvrkB9qo*F=UyQeHDAF!sE$p6zDM3##5wrBxa27qQi4!9Oe=Hg0TY1MC0 zhdWf9I9-rj)GMM5iy5~b9FsvwuWu7fd3S~WEn5#%IwVZOu>YOfj>njTWl>6}^bl_T zJf$q~7D@2jDuIAHn7GCdkOJfgMW(~R$EG}j;>F#>17lwqkucav0iHFB#GZRX z*>^k_sD20M28lnWHVz;O>b}ASGA6I}`n`Y|^y5ovsqfEb83fa8v=pi^CN!-r3fEJh z7Y}q3pWI4o9*aszyH zMZ<-yCYKhFvJ;y?n5A!%YT`ekU+?`%cJ+te-ZyMczzA?j_maAa?1U|k-XT9FNC<7% z{x~d_mdb~Z@VuXOQd~skYU*R_Ivre3S;}jQXf>RT|32i6kJz19GOO|aLV=^;(=E?0|ncx*Cfbze!O9y?TL<;x<6iFSs^YnBtQZI7=6%z5`EXG1nrR^Up zH7M{2PyTgz4SE*Z{gX?u9Xo)niLjYUIUBWe=rW)pEtkN8b5(=o6dyc8kHGO(nt6M3 z3trE9`T9$_B2*syzT|d^w?E&6|BC4Z{caIt(XjCkg&lc6D9B)t$Et=$hLZ@9R1cib z0l0aB!0G|nb$}R2+BMnO_O`3qnNPhTy(q*Cf^W2;OOqWSh$*OgD3@6I2;(_q zvEYFi`Ukq=>>Ci>oxsoDs@2_uEI4iP-Q(lHb~cYln2|z^xwiX2Eh`3Edm)aLS!!Yt zvi;zBJ%^?!q8|A~&H>rDZsRR(XKHIy>`q7;2d@Eibb;IDQ(@1GBPQ3Q&~%DIZAqpf?DUheO`Q{&3Qu z+binx*8>15#SmKwBO?#8z;-W;%Y$b9$eu$o>w{z!z$rJ(4i2nH2Ex^Xo$7JWNUV^E z87>Zm+vxAtfiP&44#G@63MS@lIuUr>R0XJCR_h|7v-=A7F{A9U$+j`Ecjo&09>Dwt z6kWZB{+Ob}KhK09sh0P4@QUO>yecnvyQA%b2fIq!UsfpkqEbRJ)>$wSJlnm1LEyS& zqe*+*B#+_X&^1D2LJ4Rr6wIiyM-;eP4&lCM$8#p(?zb$3@zcr>(}~~m^6(78BrL%n z-MxtfP5||i2>UagJk9LhESeBuWuSTI{a`xDr4XfPKQl=P0wM_I7=fATHyZ4UZtX{f z3Pf5%Hv-m2LTnBK-hEg!1qQdD!-RS*{~{TCd~yQxYL`uaW(L#v2T)Vyg)y*jGbkAC zUC=>2z5&5EgAgE8kAo;1K!Dg~(c2Rm3;PSgL@6hPccH59H-r}ClYP*Ffq9{ngL=tB z(nDT)1y-QZEHQ3jo14xqW~q~5m*^=SrMuR+P`Hvu`OZu%1efO1VPX1Bn0w4+ zuXL8i1}(?z|6O5?Ge=@l>{>{mdu)TkQy6Ws4KatGsI6Y)8twJfm^oV4WiJB7mw)p} z<-aiQ{L$;Wb>ng-C>3`hFQE%4cf1K|r}VZ{ghS>N`g4ikhCq#a<=OfvU}^l}Qc z)*d0r21XF9JEh%&cpS8w#SaK1c}e^=P`MA;OVe>>&VpJ|qv0VSrJqcctAH`#g^X1@ zHZf)y)cgKPLz@5bZ04r59?@P?ksTT1$tfekG;M20#)Vw==^$ znvz>N9^RUw{-(*@x{ zp9ygX1pH!yRJR>^+|+5g$fMQ|qSmGMFJ?bW=kHV~f(+h|H+YT?G+3g?ig|@yu*YJL z0RGdqNAr>g^!JZ#K-s_T|;GoT8Y#Y4PB zUIz5TlEDEDtka_5A;hM&H|&AEi+=O|Q6x-{^Cm-bX>FQ?EW)s9&4rW|B1TWwh}UU& zI!9q6v|LI!z3}uGwY`k;g;nWcAaPxQ-)djdZOlFLv|6AsIdkRSi1Xz`R{i_ zd(9{5bbE9?{X9bY&v=n3bI{6!>S18)nV-RCe5_YW)t3n0xdf98p)d9iSNCUeNiMgL z?P5(Fqd^`yE;Gmy-iI1FCk7r4Yr0ld)jorPm9EmX?9iuW_@t-zI`S;LDiQV&*Ag>% zU!F|c(esuiBVaKtHe~JhN*{Hux_rMP}@E- z#kTsP8n&YLU;&|K>Xu~XdpRC;(u;;moYoIECyYIS87auct2dKIcRM?l^6(9VSQ~dp%h{g9Ms$H zz_IW#8!XG2XK`pR^~r;n8>aOxNcA{c1?W{G1p~_o$-~TVM46g>5?&(bDFm{})*St| znoXI==y#!oiWr_8&MwzvqaQt}XHulx_O|t9D~9RKEy~OZEtG4LE+t9$rk)-JHLIk~ zrWb|EO55`qlegPrpdaqv+ei~~_GwERM=gO^!y^_PbTp|_aL74A%n};(j&C5A1dUAD zyFimw0>I8NB@k;7_IDm&*ou+Spz_=#n_$x795MjB0=GF~q2qfCY6x>B-0`B4qVWc1 zy+*8GthIhWyrRrK&{LgGFYD@uOY7jE*vYH{od9JPaZ}5!^#HMcX@|^(u$uWx0w)+1 z=&HSEYTLOUcr(py6ajSsWZp4T$4V2#vJLS5zKhr>w>j<~*JQ#t1UR#KaD9w8k}_VT zeBnWqQ{WUadu6G%jIhEeVzF)w2J|lX=XgfKeCjNFEP{5umB-e&@+gg`7Vo&RzOrr{ zQRvn3_I%6fNel{w*t)k8#_~8?l>Xvc#g3lh#Zp`@jk(_X@}y@6bw4fmZn(5y^wXEx zImz>@lfQ<4jZR(D2F+IBbg@EvoL1zT#@R9PR9>DquT+X?@=6Z$`yvyDv?v}DRY-E1G3$lHM^W)D zS1~_fA6@EUZ|CIDxgfIt6bp5R3elhk8r~=8gu2fqhiK>o@0TF;Jd7BZIsqCR_jzKY zmGu+lex}pgj|T{O>v(X($5Nw(!1rnF0&^^b~sre<`cqt@Wy6Q^JcT5({hWa#-w8 z(&E!D77y4Q-0o~%qfIGXZry0t~$~|(3=2BI94^-*j zU7Ey(mIKWvGbztYNu;QjbdT05U_wlQ@UTLa2&X1z_rKs>ZmfLo-(w$fXYA*gLMKS& z8Ic`-(kDgTUdDSXvy7D%L@;^nO<;Vc?8ai z@o12!zP2Z{>)6L`1@RCc!C$I>*VL8it6|~*Yi)2qLRBfBGf7Cr%!@fpVlmZD;eiSE%C|4-&gjO zvMrlbe`QBVQl()Y)(#JFq<{8yWDUI$G|mrna^``1cU9QtmV>E}#`+ z9^miDIjJZpOq20^p}tiK(f&YCK(=dy+@y2um5{>*nP7n75Kf@HQtE!uNjT^F0s+^@ zFPS?1wDDpal2)N#7dir)4WX6*2vNYwn-2Q~qiMg3okGAam0n>1368c%DkXi9DWTOD zhaOTq-dkShyC`)$1kV%60+7a$FwqtYiL{4fgGA(Y?m=8g0i|%C-5586Y`aer4?&-{rMRErQ#du(n0UIX zD)V3vz+AUGN(|6GSzAq(nEkxZ{Yyl6@B*vF-6m?BL&~YS4SJWK;#JzHvk$V5Ge{!0{x=ih76cg#u#DpG zP=q<{0vIucBfJZg)#kH94?5Mu|HYZe%|g#28FkXFce!j^eMwQkgB)X1Pr2YKK2=juR-KlijG+MmI@M-uj2Pr_*1yO%*Rn~Wk*1h~dFgpagghdWC$3^Orl)D^^x6?kjv zX{aQTw5;JyKGP(2zE-vfM9ow2VEOE#s_;hok_WRbK*?DlN(jC1{j|e<#p0XiY}KTo z)lsOP8b99fx8*V#>nqlX9x!I3PmcO^!hHsx4hpmPz;U@jE4%)Rm2vi~@_;M#Pb=!1 zI{5Cpgk(<}vHwJVX11@jk4_+(&lLr6N&X-0y=7RO%hE0k!6A5X4Z+>rT@u_SNN^b3 zH9&9+?(XjH!QI{6-GYBZ_Fj8s?X%YV{X2io+rV|rGfY=MUENi6&rJ1QrOr^F5;7!O zBOHmp&Xwq~(x{i~2n-(YbADLeyl6s!3+e(LJUh??XrFLen~{bq0A$GS>Kd2K;UMfy zAkfOPZ81Nt!!{kp3R$51SUX>0aU#`z)0+^xgAsJCR0yk4rRd9!s}L=lE<;I9n)^f? zT68ohIX&VLVSjOI2>iZ3nX0SXNk;pwFwrL4q!bCG+a1wOYCvQGhlYRb`w4#=*&biI zfdJcQHIyO#ub>YOu3tTFiNQEmh*mNzG@0_wu;HeWefhM^IOkbwlGjs z^dEBJQxI@|RzoA~X1g8ifw*z}VSMunk8gQ*4*{L~^I!PFoc8An>@0&yzK1wp;_^8Q zFx-5xmi72@=_LOEw<)0q|L#i}Akvvh#NPwY`=IEUy+mb4Ni)WkUX^LC^}P8F*U&i1 z3lp2va&&!l8&j$sZxcyv-D!cdK3dYIcU#@prQX&AE9NhddjWB&{TB?u-e03mWjg7$ zEd}=AviM1?6Fi&)cJyKS_cPN$inl+;Z^RNNA&40G{j?QiXyG{sS=IP(&B=!}qMEZE zGDs%C)z5=AWkfG0V0atz4bw`Jw`a$Z(CSdmv>&tF5GezaMoL4dJqamYHzKm!PVYPF55`X$+@~0`sdVQv(;0J~%;iQ)lsE z@QUJhvAGB|E%*saK_{K}q$&R~F5PR+A&xna>9#l}3qx#WU``L#+A?2^JSKz&&x`g`_=zB*L--}jzQzC)- zfM|xT;zkr2JVXgwwi)?ZaXzPSyr;EeWcl*OQ(0lmGn;Q@zUdH^jmwDFwlDexO7-oo zi*EY{;Prfqgow0osi2PcKQnOrMtZ{dzoaMsw@FVJ>He4WOz-ZYj(KS8EVAxV%Zwh2| zyi##*Z&?tDW2y(oJM(kNZ`sX{<-)a1n%^0>v1l$42VdOo^3do!ou3C$SIvzjXRu@( zAt=nKwhiDt>2w?^W<#$!ZO8^#dLswy1L25f?HhN{D4Mj)6kJQ(S*R*`E9Vz$DjS+e z{asEBbGYV$wRc=+26j$9u01UcOJeY|)LH&q8iwjGhKHI8hMl#0*X=caap=EYTUu1J zd35XQdb+5&g&-N(H9o<+Ry|wf;B8VuZ4donAi?f?XtH!2AxkPw+60RbrDHc7a#cnL z3on<_UE-)=mzf7>qFr#exrOoe`uY9*`lO>9xU^i5Q4Gl zmeP1N8Ibqn^V}LoXuV48yvXFs)74?yBn`!xM1qILd}dCuwX>jTzEFL<$sV-4wcKsH z`3~DhcABzqfCk2qO#_ulUScqHlA^Db8x-K!RK9}4dWbvK&@pjO);tj ztxFA@Xz5c>XdBaWqEpKZ_|=&2Zm z6SjHVmJM`GYdE8Bd};zugO`t`r4?{De2}@nLpg&uIC^4}U2V*VRz3B8x127Eqa-7C ze8SnohSVJRO3_igY>jGj4A%Peqx{%+tBo`b?bGN)r64#&rjlEN=Wrikp3&Y$Hxnoi=hk_1n#8Qp0i-ZA8vsPpcn^8;PB%+m8G&DD6R35t$5_N{Fvz#T`L|q?dRB z5!q6)C-_)rE+EvgO#);-!Q!aiz^S}hm6_R7pNaaRFtb-%?89d8X)yYjQ4e4e8!;gX z^QHY5-Vmj-?M=vgQ+bv+GXX0=L}p=liiqeLRfUbFJ*W51Vk0PX)tOh{Ocy+s|0Gsj z@cqEpOLfRaE3BxfLHF6X-cR3hUCEGL%v@i9z$7xacmA_bIvsQ*D^iUO&yP-7sbUO} zEwi?jt4(#>_uR=sGF~Q&3$pJIBY@N=8lphzlUCGyXbZRW33fuC6x3JhlUgA438p`g z`UFG!X=ta~HFPrS2WsB(B0FA7lB9GgF%QL|t+a)dv;Apw)NP!t+hvJUOtVLv-L9P#bNr>0?JALNB)8lVJm z;sXL3!!vBAy`M=9ThPEiKbki^ERCtl+YjMYDEQ@=GtH`KkvFfH6Qdry4{NpGm(Zry^sbI+H>GXFvztAH!|Fwb^J_-QU8!`aMC?~|c%@ha z9X#15D!;Jj+nLEzl-j*)6E9mLoQ$V&?NRy5rEcn$QKn<}n=;ifJ4ag-e;q&b zE}~G2Ddi&x(fW28dz5cwWmbC^ZLL;#=!e8HNPxvn{P+_}R&vc2N{LX|%U-e{>1~<*H(xbN6!hs&a*N{aU9-+FJrUMIEd9r>> zc7~c#tnN78z)-%XhUTXS@zTEsq7dx{6Q!Qkm3Z>Evtz^ciY(uhb)4iXT2N`k@)plO%=yOn7qlG z4dXFX$Vh)L9p=Ns<+~>AFS9SxwsV-D`aAjQ@29SNuCzX$ZLkaLu8ERkd((gCeha>Z zZJXiBM~exC|F%I#5+BNk13!zavP0)N0N!uQnjZ6=$ZaCddo{juSpigso5$dRF$#BX_?uKfS?Z`pUtW-h`v`&yu>V3?4v9l(80Soj2? zpf~3(h3H_Ag8W-LqPYtfnY4I6jzHr5cs(b^bmGqWmH`V9JAD`4&#;K~J@fZejrPMK!((j(c4L-xA$+4&Ov5t2}S^A_?dK1Bslwvp;FvZ$`7sz?bC z^XoKm(&kZ^j+k`M0$4d3Evk?cH{sEvHiy10X4oWuM2y+Y=3whJW!hN1JcEZGE@LaZ zwI;bJFf%a^E>s<}xnQMfRdhk@TB2Sq$qKwFkbiYz2j%3egDND|$7m zl})mL#OPQ^Nv7~uVCrTNfC)^{)Se64^*6dv!*RxH&XwgI-Z3Ju0u_KY=ohdZaER+r z(6qVB^r`acD9%yeloN%WV<8S-lBduJh%Ce$7^Fd;>JoLDt7fb3qsJ-lgF~QhjSAWd zS5N8jmP#$0*ZxV8k=12qr4Zm;4ImKj=|7q*lFPzfOH#c=wsZ=EGC%k3EyWKLap1Ag z5H>Opl-I0iw6;q$i~1-h$e>GYb%p|$45Miw3zH!6EprT@j+`z4M<*wk^TXGIdp9_1 zl6zGl6Sb0W9FsFrheDeHdJWcyki-`&AOoBN^ycZ#Y)r{3{bDn7+YZc1GWqecN5T{! zeYUvRD!uGPZ!>!xF}uHwvoL)iQnrG<`u00-H>#fvwkzAzC=KoV^lX$z(Zx=7J7<|N znbfq6D4pC7+yhYdbXy<%fvR-!>V?x|YEoA6V(DL=x6(8RrgduslgB zc3F9jj)SVDNs~*y(W_)vMSE0_^k6knE9@`m4)9jMTtr2H4Iy}e6WnecBcA6yDpAg`SY%&rJ7i8ALM#<28Ut3{`a+Vj=f3% zS-vALA$MPJl%coEHt#dGT}?uQq$+)EJt>TN#K%eK)+_ZI=}@f?ZI#ZCx_32KTlH7_ za>P@qD0T5lTl1qp?6fffg-?Ml82j0aZDw zZ1u1c@xuVAG1c%8q)vwDr~|+d$&?tvU&}mRW^C8Q;GJ*l?#X#NIzW>#4|x*zJ+MD6 zvdRgG3!pcg^v#0zn5nAmO3M5CaQ&r+!DB)duGd(Zu%9ZUsXlszWBbhlRdN3}bp`TS zWjqUbuZxz6K|<2|4L%RRo*mQZp@kv24gT&>;`p5px&2AJV8PnWF}e59%nn^vYlQCZ zvohbo+K8@A$N~n}@*R<%W3&8mkxRm;52);Fz604XxcsbZnz@eS18ojVtW7CbPi^Pb zc~wD*m7#^N;k)3s;33)cxHV9|5RRf{4f6N!nQdx*n>SN_Znik<3uA2MfRA&Vp5CkI zd?BmVYl*?ao|qNvoNBSIojnqoum zePf(}i&$Z8yT!cc?Qi5u?Hq?yg0rD+fo(WtA5NdK%O^88Z0Fal+9{(Of(kZxQn7%p z*t?#do)($ID;66-fWfOXBWwJSC}~{n*djDyv#H{lcPr0lTm@ijPHnoz{=$QrT!_98 z^$FUQdqwQ{;a(^jY>3unsBw~avNx7>53WCzr;1$!%}ns$30k(QSO3=ea$o+8@fv{{;>8{%p+G=5 z-~Yi-_IDBZEieKDbS+E_4Q%abZS)O?qlPVf=#jpia{C&L%<*DqWSLSypGJl~U84x$F*{9-cqHV}oxy%JWpR=&l*mN3GLKNRNUz&AS|+(v1sZl>5vIgXBu zRaOp2p~bS50I1VpFf`c#dG~1D(c~| zB>H#0x9+f84sboB;Cjf0vr0wEriE%@A?{I)_D6lJLiaZ;o+h~inMdrqP05?VNqL8A zWMym3m4@Nsv030DHghko7SdcT$&g~d{iqf2IX zd%Et&vv_^*vZJ{(PpQx&cM`K>8so0r2?gBYOZe1PmHVyisc;0O`8U0O+-Fxx9cTC? zgXgE{(sE4}j>Y4w^5yKHG{X`xJ0g+;UPZgo}#N#Q*X)~t{^ zJ`Z-!rxCsxffMwyQnz#>8Pq&$-0H4<2QeQMOZ#%MG`52 z*gW|ib}r9a-%rZ^oaStgQ*m`Y;C2Kgr^2H6}>pEUy**-)9*YU&uxQ?%8 zU~6D!XJTRWi{biM6JWW)j`Zx&mbq~lw4Kw`f?iXcj6}$jJ`6XHUSh`>2&0UO(=DxV ze>e&wTN7oo;?nDTmxm!E{^*?C(Io+*u9aOlksn0^`E;wYlvqIhRA*NkIsCE1 zUG-Jg-7H7S$MRroeEUr#c_C3VEeq1dew&50!LpWXUN75XT7d~{SCxvYg|Pm!SGsUa6UF)AV_nFgMN zhCZPG<6!!rZeXL?u3GUT!Q>!kX8@t7*D{q3f*QeKNG^V1$Jm)e={S>EnDvA~GPPKF zLGjc84~mH!0Vx2fdcU~3v45Az8Wr`ksq!dQnZ%07k`U_Wx0fpNCdvM`SnaEGnu~FZNG|h2=b>Czg~q#w#2YF&yvkYL*)|Xl;1|Q;j1H(M ze7)RUtS6GIU}BYMB?%aYH(NaB!rB#-(YDwYM5UH^#-AC($>9M4wz6^35_p(hhs6oG zH3y}lNCMQMb!`TG^ASsl6WOTi*Rs61%>3V@6S;%N4R_!%(u}@0FRJCQ)>;}!5RwgU z2|u*>MBt1QVs?_Vjn7KArHSV)&hE>D24S8pX^D~J(Qk3AfkRUFg4H222_g?)8J*sq z0e(V7V~Dh9)VT$77$}+WXR#c7%}ps(=Hn=xb-X^sI9C6v)c74{dh>fc^FGmDAk4@2 zg2fbqnq8@H=IkBNY#H{2X1H-Dzp5GYz!3GK3W}5f=1dQ{E=Pd1f2id1YYMd=TnbFd+U`l_stoPVZ#AIfLql? zQ{#v?KDUnHa3EJGc}Mu&XP2{%J{!O01`r{)hd9DuIBW1pNRQFQ?|Pk|Iw%VFjwlt@ z4rwnDgP?UVBM;;2x&3fRYy4pjJqhKm=^JoHxclUu4}CXZ&Q%3=coQCYxo=xYV7ihE z>8&>Tud3ec8CB`<>XVxaARx+k(ilGc_y}elc}cW3TSnDXl%Ra4{$$Ycy}OG~-gS0+ z)8)EP5P9V~rCq)f+U@+FtAs&+Z!5_gCS)fkm)Fw0U95sO8v#@-G{Y?{$O&#tZd_!cegDo*7=jp)*sQfR znR)2**;I+4*vj1ik`o&fgUC2RrhAMS2VIl47a9d64Z4Y|WFz~F8)5+O42v*ze(cOhdY0HVUA_u$+@sPON4y?0Qo4@3iDgml z%&*f!k;BY9 zJ<%8Ws}C**QIFsF7IRJiV7OR_K3lTqd7#EiLq#AcF7}T%uAG;9S@EFJtBozcFb&R; zT-i|=egUEgC}bOwP zC$?3-mA#GW$ko?=2!9Mct}O~xGB$-Krt>#<^Iyk~rFMyKfh84JME549afMR7=2Yj8 zY&+ae*vDRmA)j-IS^jA{DZtx$+gZ{WrWMB}0_gAh@O`nycOX9*5{g7 ovNd$0?c z$^(7q)c#_PJD;)|q^k>sBF*1&EV{%OLf*~%)(g@bHIU*7*Cjo}=R1P-t@tEvBr96q@!Kx^9 z#o`CML=|blQy!^+f|qmKOcSk>`mzJ8rw}E&K@Ryja**+#O2a9AqK|idwS2GICj&g< zaRIRa7!Vf!Gp2(BYX7${!H%^6;hUm1&#BrB@n8s!1YO8U+2o-uyhqz^bp3NMZmrFP z&~L)J66B}@gR^Uj~B6Iy9Er!D9|DK}lUv6&oB z-*~(n`!CK8AMgg&ULHSDs`o5DEMM`e^%iALyWj0U9BDns)Hcz3xdj7e-zFfvCwb!&&C03Ydv13*q|ByF$97W8*9|M1r!sA2b zC-h?Rayv0;X++?;IOKSqd-e0`Xmiq-fybCzEmdCqKG`*nmmz>pB970Fs34#u)2n{b z)7{C5OX2y-^YQF#c3-MFWQ8DA+rx=o8{jy8pv8n^0-lrIu}u1zENNMQLFQ~NNnHxJ zyyYks&VKLvDtb7trD0W6c&=4*6LUy*iqn}1e%sRld2Q;gf4|m^EJtc8U=87Pi^-oh zA@PCdr)4VQ=A^9pcgsgm&C(BTWFquuN*vZ}lTI%Uo$yQXW0JoAT38OMtzFI?71 zulJq`6k14it7r`!yy)hq2n5_Y96#155_^2qxV6mN9vlcZ5eZh0UTCd7>)qq?z(jLb zlG;Rzs`GNZ>YeO3wB7Ek9uAFD%-agM>t4=ocJ}hNFMW2MVkn8=F&69Y99*xuTw0TI zL9Z366O2|I9q|_s#}7Evllkp_ZVU~!nLD0e6xNOACFv(|A6q;#-P>}jQ089X3NxsD zc`$oS?qc(N2u4vn=O;7v2>XnJ<1ZYl9KvD8xe8eC)4q5pQUok@!T)g0)0)Be`9F@FrQ#2JcCQk-e}; zP|I`js*+Y+#i1v4oFK1PS5Uh21`F|)hq2n^5-ab~ow zESpDlyE$AI>E4V2_8UYVqYGVQiZ?Ful3LJcSyo66n~!zfV)j2n$gyq#c0I$lzgDg+ zhCanp8;Wh_xjB8mh%i=Srf_etRC04~EXiIE{#n&{z3x@a^TVa^yaeyCWsxND z`Jy?3TM)8R|8o6CC0y`XqnUZqwK|@!403VH{zKkW>P}j)rNRJ)n14atRgrN;Xq$tN z)Xm6p<^c`a65+JKRde7B9opTBuB1UJqj#!Da|r9`rIME(f${MfnUZ|wXxf5pQ0t<6 zOm_|TywSe)W{~b&{Vh^Ppn6q++|? zK!Xxs80tsXa}~?}kQbwSQnUiLbJF>_C=U~}{a}nS4s_5dbS#{s3WDY)w=7Du+@sN; zExvgW`gT87cE&o5R34+8b0JqpvVwuIMmF$Jkf{jJ_ceN9MH<|~ACt0160d^1HiW6Xgx(}JPl>nOGk)a)*Ca#@BP~B!Mk*v|rs4kB* zKZP}&aj^S7bJ0aK*jZc(L0?khE7_A-4(Rek7%3&E{e-zx$UKb^C&rM`Jl{ZS0fOMC zNYZf{6T#4DQSv?}qr_G;cTJvq*Ia5r=4r2m9UPDbvvgKR&J?Lt6}op*m5oP*w2M1k z8Ai080{5K85jESbt29_eOsQ-Y-uT4`w*8?V*W8w^1AxlF%eyN=r{~+sDH}7Z`!7jb zarGcc?pMs()M32ewP=(8%uW)lmu+M=W#;zJPd^)EF5o9`^I|XO&E%PdsP zoHHv0z+qfzw?$sc5{r{8TM{cvsG}4~2d-0vI1Xrq++l?G9}PY@tlAgG&)<-QIj*`l ztr~w|Q)r{D9B%LdG)Fy{1@W+-w%swy@Bol`dV&FRz}y25!UrbHh*N{0x`H~(7o((S zniw|xp}29|=9Xas%GU`^(U-)JVD;iV#t%+c|Re>!X|Ws2q+gB>irEz=-rx|@s> zD6E;ire5gw*)k~)R4z#F=2iE_zR~6+XmK6;qUQwWasst>`b1c{Zng@8|H5|tlyp=b z@eudv@oIgh;UVtHzu@8~?X=*JcUuU6vfpYmXq zJQq1loAgRS9(U-osOL0`jH#!_OJtxAx-WYPb49|FW}c&XL>{v5`0Dvy$UN=1=2R9o z=lvI9wqigxVph6U{64i!oPLIEFfGh+OuZBEs^Hm!g4lpUB=StO+zr3%cDohvXjT8sx?0W_P*ie}=d`V9`Tbl1S0aT-s%4OcfY zf4p#BJU0?)nZie2=%`hST##=Rd+#QpznM%?3W0CSA;Ioih1<2UGwB6Ss7?RrgnthI2e z<`~O84xquunSbeH@udkW`1o^O#j;PgL)qfoNrzt3>^b#YE9~5VUjWQ+bt;z42x|w& z=Gwb zT9=H=se!;qm%LdZsMjTg7w9mJ^4Fy0ypc&;W*~o8d=e@7u9(%iBLO>qer1-@iss2( zzrN>TcD2Co8o`+qRyj#Hs+hMQvJiIP8s3Y9ZqP+b7`R9C9uNs$jvvx^pZ6bDALA}v zPgm}K%B*<4pexi`xiKIJvb~_HcClMbMMHbueUS*TwD5THEbBi>(x!7*b?SJ2X=^AT z$v#VtzzKV_!VKws(>Grfik0TqX#aNNAmyz^2`$<*L$IpP^cw&i&`yo%%u ze%y7lAn2=R&J@@P7$T-}-@18j`z>(!Li?Z90bv~uFN9yMwd*Qam9A7H>H8@lvQBK@4LS$z? zvO502(rn7yNCsGtD-a-kQ)|`F^4>$zT(*5UHrHgztk$v8t>d_@sd2JT)eR%Q!+wvo zgVeHBx{$BtmjIWcAMf#J8pPSDuE0BlIgZ6IHn<$e?|h&c(EtxdThD)&&vZHtGGNIu1pRNJr>*A zRwEG(yUe`K;BBobK3|4QI}UCMh*ri&Ge#};>8{`flf)Le=aogMdLykv4r zW2l@uF&tmTRz9+qd26?Z3`e>xr?8sKrV7&S1Q)wQxktQt|7@KzVzxYAuI6AN5$cI7 z=^E|L6~|*g+O+8KM2HWjWTt?mEHgwzq!BK08THTlVfQF(BRfSL`yT=}90b5$D;r5s z)j}^2FvA>VP?R?xB8F3M2hD0i@bj*B8IJfw9}t_Vi#FTQhP)D5vKtJ=Fa#l_Xh<+< zRZ${VCO8V=aL0%9QE%q>&Tu_xdfffs(5ZaiiUzI&fVh(>Bghd{1Q*;UwKFijRMRyjg$tr1K0%M1B} z@C6OhqLdt|?)EwsT$Ter+Fg~BZ5!UTt>_(cG_G}4YPL-NI4|@gjflaYUHKgy zA&w2gRr8v9ev!l$x;n?77G0(veiUri9DzzsRtrUQ50S`0hRB71yRwk-T7fumwW`1& zIKtlx$tzGq@%k(&lcK+$SK#n~h_33ZLNCZS zfQ7=B#NLiijJ4)?u8hsXEhHb1k@~*igRx|o&$+6TSNzXXIPU4jiTot2$j22)y0U(# zdcb@q=d2w9PFpT2y-=jKal+u;*Jvh|P&Q->dhBrFy-p+Xfl%_H?;w_fdZkQYwyFs`y*ws5Pivpk*ZzZXKOK?d`XOw>pD!ZJ)1a00bZ z;No$e5{JP8HdU(D@TRtBJ=bH_C}~HYcT1jkExUSK^ZlNEbRWdB=r;zR$&Y)7?rZou zX>+7&&)M@WOC!P}choJS`-=_hr-J%pe2X$&+$Z4m;=prCdypsJOmF6x1oIAW7#lz9 z)MthK%m^dA7VH(%j@1H8(Rb2x$uccrdmB<&O1=DuJB)ok_FLbnJ9BoHqihG*U8h)G zcwj)4<0xX=cUoVX{RD3H?>4!1_RNXkUVYEthLtg*@7QUrI_xzZk#8Bp7HHgkBxLEX z!SJ~j8xG=zg*5pvKn_-~4Qf50Bj}~z0Bf^gac=K1oD%@}hh)wnj;nCgoI`yiH?k^c z2R-Uk*rVm!Z%PwslE{%#(RS<9T%4cS_yIF94|3zPJjyusok5p})V8nYHqe>6j1uL) zaF&k@q5QU5N6J-PXwJ|JsX?th07wV(K93azaj1Q?OGwPV)BF-i64$lCqTT6|xi85T zH!a5biCxOaI#0$WEVzxNc_M$^tqn;i<#ZN#%3d<5bj^8FF3ZA+-y;lsXtY1_nTG?b@=o3Z8xz2hiPI*52`uQHwRZQsK zWVb#J?mi-TArzW_K-e*I+jFk-G-Pp4F(56oZxOV1!Df>`8#s4kEZs+l(RoUO6xG!Dfnl$lXRte$Qg@3~r8;tQR`UiGDb zyQVBB#lYM??Ut2>gT5Mf@LN{5MiSz95s(}kX#VPH{VcR~OXT9*LB|icW!m=WI@@>@ zqumvv-361DKDhmmDvzy~12I+#PfQdrjplL#@#$Sw@U!i5sqb_lZ`qi#zX?5LY^+bQ zQbQ=kD_+W~lu%&yfS{(C^rPg}58{2;?SMC48q4VL;qadQ`2#iUS^~%u`}SRxU?!L9 zgdIjeMbf#*l3Zje6RlFKS46`^zOJ5TKn7_~G&s*>%5`x8cq4TIi%jAs!Ov^@{T2^N z%R5s(DLNVund@p>OB0{_3cDJHh`mf2vN{bu;cWkv1;s;PB@rj6-msG|{?CzMhyGtZ zqV2TxsWBZ3cls#C)r@6}nN8zQF!b{Gc}WC9vmV+%cs}$uxb(Bru_r#;N*>)HY+~ij z->)<6g@)1I?|z^KnbIC*0eY6=@xe%nqXJv}=lE#JEWfHA!MFA^;u5l(m7=QdAv1TH ziADzn;;Vy1KLdUBYeh zgap0JIqAkw>~fbsRK8rv@!k8&Y*IubzmxAD^A4F>3nM`b3t#=DY%)dfO4TJ>#U|;E z-Fu|dy%tMLd}!OY)x36ZjVS*3pw3cr)ylnzih6daJ876%;><+jOY!t9)Wvnr@e{eC zB{hSf!cVKtvAQbf<&6QBK?3&yv4ExOralk|`cX)|_e-ptLQ?!WQeR&=g6Q8ak{l!2 zl1|;O5z>IIKdK+|Too`p6aK7@c#Ch_;xo2Ftd;joemp!UCmPP#AU;Rq{Q>cbb!cgux-UjJ+hqtmA3IOmUhY=gUY>hbp>J{C%Sv~U z;|R^qdx*o?Nq~{S2Qx`7%G#XjMw4dhw^hTFXe8U4WYS{g0LV?Q@Uh9~H)=EVgP8_) zWR+@-5mJ@ej;Z$am4-e7kyUe>e66qumj!&_1i@Xq5m8fB(_||6 z0P1K+XX||j_h))Z(f)b#_tDJM(qJSSORWEX@M|cO^lV*gQIjNXM#&o~RD0k({p$rI z(}xpKH~C2dA8l^EXxC2;5R%Bc9pmpuH~KX{X05ofSyx{3$Peyeq5XJ1_Wh03T5*6( z^R}(=!Obmc@&d(+GrvldHTVb;#7DGqAhwC+M$jXd!nX%UD+S|@;c_o0$bpYXYzGq0Xvh}P*`#t`pJCENqTLJ$|$=Kx1gJL+>h-_4F^?mnH9%RBba-G-V zKr?vC@=LEQmTT?C)`X*AI}p}UfS}{MpmH*_>i2LWf`&;~_@Bz`>!pbm6bCFQ@k|Dr-Cx!2e zc@QZEFF><&0m@7|;l>ke6EblXZ z^n%U<_x^D)5ZvZZStB$A9^I2*5B{c6DDxma&+oO zhg7b%`2TwxziyyJlEX;312KtCx?j8PmnP*ZwG;D!N}b=(#4yRCMbY2(22sOENUxJq z{B4+l2N48Pf{u`o<~#iRd!*d^GncXrOhBJgFFD{+3b^3F9S|K7>56z5Y2Oc&^{TuU z;Et2%e0{j!2b=|9N<>txK}Y!M;0n0fTG_zW?m`af{Q=k2<+#jHPx~)zmH+gm{)maJ z@-dtsT8}vkC{&(L5<4Q`4{ePAcUmRw_2D1tdz}{WRZn5UA(2m!@>~f+28;+2PVfQ`p7GZdc`!(+AWZIH%bzhPj>jqVjm35N5v8ElR*=A#a9G!% zG2OAd?OoGH5&WIsQX@hR9%7=K+cd7&RcEwL8|D$>;9Y;qh*-xy)%MIwbim|XaH2oG zY)sH&6G_ttQ}T@`qIAdm5t-Z69!G{1noM}dcsA5@)#2xC4XQF6Yz9s2W~8WB-|nPo zqR&hRY4(PcvqK4Imni!@;`=~l5-U>z>D&BJfuv=KD_2!p5RHSZ9wTRmL;rxQl93GZ z7BB|T6`9kuy&v}tpZO?Zw-HG;&-~}?+x8?iYvih?4ha1s)u)jazuC_``F)#t@^(kv zNzBeiL;IXbQY8Ae>1hg4N=Bz|s&k%ffudr0WF9wdis^lN+kw$Hk7$a5Bm+}g2Q*wx z1t7j>CjsKhylfVrUttnFZ75?=DJ8ahA9=DP?a-AXNNJ7KVX3&&wVpANL{8uMBAgb%t$~o0gN;J#5 z3bTP9g*O^YSg43vdM);^$7&excE7>%WX@OkkD2@AY$wB+0KOZzf=1YuAXrWBo56d1 zJN!5nyjmFQ64Cl2wo^{C)cigM@G0xnZKKKoy{c$GIhH}2+(ZD-?>$Wj|MKRjKvRCT zZeUQFc(r6^*~)IJSyyl}x?+0SUQu!xwI@u2Zf|4K?PsdyddYu9r7gBsIY6sDVw1#nPnKKQiEG3_6a@75Y=w1@2WDok z|9K08J9hmL;jFOuy2?<{6%dG5JcQGt@EF{{cS8{2!1bJk>3U#jTZ5Ac!@ka3TmNyh z(D3ed-zJ3hKaLchBy>gSS1i@~&m7d^NDqEFCD(8O&{q{p%^0-VOEl4DIv0e-HukYo zVT453N0g7m1nLH>kOJR-9=^s}5`?SJ+iB6K{NQ$dM+$shBbUeYcUiCVa6HWb`tgx} zDR6HyWP-I#Kf3mgBnyZmZt;PdeOPwI1jgcK?d;ITK4L12kL7hM9l8CJP&lQY@2sY; z!?EA=%ZsKQ3V5$*A#S{ZUzEqNf;d~jvVN*z>gnMChP^%m<8=MtMZbTC3!~`TjO=mO z*XOEeKTQEg8vd6{2M+d0xZfQZA6Kv@1R;nq2fPL7g-_m|kKvFOh9;JT04+gT^Z=SN z7`MZTy7>uNwS2L&2pB!EKv%$gnvuE#>IFaCC*W^m0%d}dgz~-umE?a#K1Luyn%Luc zogOeO{VQ%6MIXf#12+$skX;hc>snXYcm)>+N1uRWfni*#VE-1UECs~06XXHFh!}v# zR4LP9hKb3CnbYu!QeO2Gy3$ELPp2051cVU!ZLix>be=4FsTVN$YjRjX_5F%ZM3pvP z?K2_=M;HzF-l0tPuRHEFmS|#d#B+be;xH~S8^b)sBnge^Vg;^vKYHD#f5+6<`1B#d zkA|hFUy5QR!HKN3IwLmmClo`~o&W^LbT^ zej5-kyhc5snO-d7}HfdAavINLal)?y^=2bYf-7^6jJ`nu3pN4z=x1- zuN#YWZPx{^BMH?nOj(4GvAzrP4)oT8_vWlR2_>V-cwP@p6bnR$Y1g`UdeA>&c#V=p z8#c>p$xVaJ)dgzVZe=#Bfdy?bVFqnwM&87bv5U^TwL>?Zq4E&O0;bNo#NPY4YydHx z4Lq4sg%JiS?zT)2K}>Bb{Kn|vr{?96sA=Weq3yX`0@12tDcsW)VBV~u_R0&ZRBqXz zQ;n2BvBSP++k@w8>PJ9&o%;`9CbR(^I571C^vyevcOZXMUiLNT2%-fheZ2m?CiMQb z0Zae}cFtA?fAsnzi~78_S)Uo0Ok(&3Sn&5RT@-;=GJ2*4U+f4O{=?bu-`(}>dcZ1x zU1?xIKv4hEy%#9-Ki&U49rfP=ey>0coXc;m0sJ=szh$!gA>ogC|JLPKrRqPgq2T}L zy48Qx-=F>dRrdJLYremc^Jg9Ff0puE$@rC_ z*CNn=w(Y->@_XIuf0pytyTL>FKeha49qfOW@>lIB{Ed{q*2Vs3Nd$jR3iv4WZzTO6 zb+Z3i*k6@2@HfJKubcf>IsaWb`_KD&gZR&NwEx)9|NkZ_A@U!S_>)HEzq|jlNj8iA z*8QJN^7liJe>KTciQfeLjYUccut{&l=^&A(>S|98*dbMRjC9RF;*U;ZKM@xMjTvw=RlXaCZx?!QGkQ?(XjH?hxGFWpHP32@)i@1|QrB8vOD*RrkJIug*Jv zysqk*-cz$ycdxyA_4>ZvTUibo1{(qb0RjS$;3OMi&lk%A0Ri!!`uP)tgN=iQyN|Pl ziLHXnTLagqdSY6v#W)Pxtq0xg}d^9=|n(4 z_%EHGYW`2b_-rYe+FF>ole4jYsy1QqcCe365mNg34L#B;5MZvI8<$_9P)D_ym832D z<5yb)kfQ19n8Wk!I6M%k8oe}N<|JVH$lkBMW+%LUX?Z_95(9Box~7%h?dJIgBt6~^ znmi9|pmw!5X!^c~$K{K0S66YMMo%kc1;VLw?8M+|-;i@8;&l7cU-5*`xtYi4AnfLP z-M0&2uo7WFtg8jJY0v#l(@K5(%L=gpm#Qq3CNEX1s00#+0RFp{t#LzoZChp$WMSDD zFD^hXYnsD=zr0!x`pzD?xA@xBWqx&YhUA7k?}H=!`!{i_e}RoPIBcp@FZjc8_KU1@ zMOa&1V3{jo;Y0{3iZ7{2!aXN}hxGv>l{Gun?_0btA@dU0YLV)V?)1wHF=f(N7!8;N z3+eiCn~pP-P3k`^t{Iua$QYc@O0kWU<=_$iw)dEGLP9`TLP0?Mf14cZ|2DasyN|tv z+kcFnuc?r@PLAIDsHJVFVT*>^-jdF}OydXqQ&4lkM~N?B&8961KJUK@7Qyw*U#xce zcE#o-jQ{%2-NxI!LY9NR-KAZ2FB*wbj^@^tU^OvxJ9XAfA==4QB8EJ3v(Zzm#cRx16M=4?Ck0Sg3l zM4|PYL~Dz%KHnRjGHb^4>~Qr-R$+76!aonzgn_*dbspi%)l62!SzIQU)&S?w zZ8QD%vE-jH4~ht*n5F(b9BR@nW7652{3cL;RNEuQP%j&n?Krf0j<$dO!4ya}IYkca zsiaHv+Us5r;pvvjRkDWHXHP=!Ovh=D4?^{O5!{rB@tN`JVps7Sc z;E(=uxE>1bQG4!D3=9jCA2~WsKez1Nof8I!gu(PSkwVn*b`&+P*yZslteo^ssAU0B zT+DTi0q>0>W^FS(e%(EVOKU$%Ss`8tH=}fMs4b~vN;!Vz^vm<&wDE;jXyhoV*3qLS zKjG}_6}@pwMs9f!;9NVBZ-+0zVc;o8S!WEV?@l&wF!KV!=X(djHtZ0>}LYP1s*jd0{n*WTSHj`vaA#I)ZzQS^iO2Yse6Q!14ff`Z<(wYCkrc}32uL*ieBBP`)T@h4~5a$@Z!(vAEJxNS_Gep(hfTd zzm8#AKF^kUhYLW%p3vvD*U+5Hxn=p6qCe|i_UDJGMbin8r#c~2Cz38DR38tVn{qn# zf>+*xU1PHrg7=~Kz85w&B+mM0IPi*XnwWlBrU&xgAw=Hkj*--aM1}Kh5))`^jEAMg zVweVb)!uSa9AM^ND1{y=e@>oO*B9@f=C6MvV|sZcT!RkeHMhPX+>cGppx}9PFK5m> zh~c=Y{!m=7UVkAl^Qf{7qgN)moO=8^EbQ;euXAcA|j(k62ydRT< zS)2bN5i7ZB%+@D=7_xd%*Qu)&Q1w=$D;|rTNbK@C!H@-6-~Tibt`(|VWM~>B3AwVN z?zVfMgDY3_g9znhE~va`ZZ(S{Rt?Ur2}dhLnu@`ssP1sk#kHSSdq7P+_-&zM-R2f* zv&4Fu=KK5Gp*hqsw8c&PSe3MO{ zc0Ty7JVc(A{cF=xBPB_0NHo!lRkDEt=_J!-hk0Q)>hWLuVn?GFvsc?ak*9IszKI3G zkB~E&lgPK7i%N(+aTRyb(F>=8iJDPGl$HmTmwSh3&UV^sOT8=)h{f@*-}uak$mczRDWzWrk0eZS&_?I=dIylp@35k&3sDhUR@rsh#@a9b|m4yQcy6sp+gcjeP z->(U)3+M74qIfqM?RhV@M^8p7f&2HO^S#adNB0i&tXKIr&$kCXT~C_C=6|(2&aO5^ zhWY#~7L$)kx@x3wZ+?XerAP|ZJk|Hdw%Cv%bQ^Hq4%QVAdWO%}?_=Tm>;&1JNqCogP&*Iu#y_hHJ~2z8$esUY+{uAsOnp*7qN06?8;KKC4Nou+wX+ z3;r?lAd@(#hJB;4Y&pUwebw)HcC==W=0A*GWdn$(WuMj5W3EP&j&3o)$drj=3PP#j zI`TGrT{_wId1LkIthULYEA3@lpyZ!+R)!r-8<2zitk^x=2$bJlWe3CK3SJ6lpbkpfc- zT^;m&cJ4#h_qi^$6{E{&=r>(kwg^G_Bm4Z;yVK1 z&u@*+g`HyB9Zj)`$wc4JSZI$f=d}dnq<4$mu{cJtQohEJB&dNl8CW^Ia3h#mO+e?q zh?{GI$G$NeOZtBYY7`aYHSUcOlo}5SZq>^j5*mY}^k7mqfQ2Hrt~w*NW1MP|)t(pb znCa2MQ97uddy3*6jWNQC- zNTxj)5e2Hn3m{Q%H{fVzoOym3tIVzyk<-j2NfRsPJ6tlBn_M$XGrr6krT)X-QboMk zZkCp9xHQjgHI@LO$^U)#nz73;i@SMR_U%-@snTBdTlPSh_0O07lOh@;L#7HN-3J!R zGw3Rw7&e=GSR{2(*FPy$D=r>8Vpxr&HLCdIMf+Gx;G?VcVPno3WT)PV6@lHW8CzHd zI|9j;^rzO8b7|q6Ta*A}`{m5Ve}Q8T3Sli`fq^j3vxymT#ty=IvmI1C%VUqwgE@*n zUqY1CkcHRDS5u-w(7D(EkI*Iu4M!Ze1Z`rC)M(HqTf?0FWC)twI<5b8Js4}l8=V;Z zt$!l?snR%<3&ir_1$M*Ed z7{#w9Vw-5qJice#Xy*=M5P|wR#PH^6XD>qvAI8NA_n1pq3b?get4Gwk;l)3<^yu$w z`W*~k&_(j=jb`|m;i+^+EYMC8`I6@=OAY~@eaBG7zRS1Ourrd%;p}_;*#b<5|EMNf zcsrD|gS%e;)=HHaRt%VX`3-+|=rLF;M7Ele*ki@fuy9`foNoQZIB@zHncr~O5wX;9 z8I&9J&ibFE0mo8H?iL;b!i)8PCk_7_?R@45|ECaswj`V!Ep4nkT>lH_xUsW3J2`te ze}Ws2Pd)!PO8P%SpAF*wPR`ZI%GJWn&D6y8e~`rgZzTWI+5ar{-;LAF-NfDF|3`1` zPEPj!b8r9M7%lCcOx!L0re&!v6myr`R4x*vbh3@t^viNvd0WIG8$`*x0+Vy8rJci?gFujIyE> z3KAjG=U-4{q$O29zb8KH2LklxXB2X0I0OVVgtELk01g%o79JBB0}mY*8XX0h7#R)| z4FeY)84nld3+`7OVk#m^24XsH8hj)wVjOx30&Y5@uT)fDX&5N!S?H)KSQx08nVBi+ zIjC3!=$YA=Ie9smXt>yzh1sb2*%|rx`6*dN>3Jl%gd};zWd)@*BzYJBf}E0q;fiZ{l?05Hg(V~;!~xRZrRC%#C1e4z3ew{8a`IC0YI3SN>he-53Mx9Pa$1^N;!4Ic zT9z7m7Mh068YZ^7Ha_NBvSxZ3u119lT;fBVB7;4`g8kz|+~dOh5~BlCLYz`V-BKcaGh#f`V*GO= zJo2JFbL0H-lLCu>_?9LGghzyjM8<{2#K%U2#K(lk#l?lirG_PB$0VdgC8dWY=l@7f zk4?=@ii%A85tb4kn-d?J8lRSy{393UHzPkkD>Wx4Cn~ct zF25-)uOy|QDkr@-H@~EyC^x>SIkyy;3G6CL2(HYGD#=JK%}XuGj*Y0QtWC@cb& zWH%KhbW~=Rm6es2SC>`SRhO64R5sKC%W7+D%WGRp>pN>Io2%;^D;qn?ntJLQTWVUm z>p}g^<;ATvrA_rUowX&M4fTz6Z5>V3&7Y;Uvjx=K)7IS6+1B0NlUqMn(DbtsG}hKL zTtD!;VPL*G`$!@zvFp-y5e(n|m8OTkGJXgO#zpjV16l_!PXh2L|sR zo*x|_?Vp^V9D>hI4lXV(-rwIdr3o(~AlRH_B*oOd|6BxoamUu^aul_UsVXht+nXZK zp^nBHFLzA~JwDn{sP0?WMne&~b#wo><59 zrB9>JDcz}8!caqW;xMf6Loe6f(?Og-GfCQWI9Tc6ITljs z0MeMKd_6Cgi7*;Z$yifM`K7W70)F`8377SH-~6EO9`8C2%@TJN@6W;&h+DPEeN$3X z8!x#$YGU)KvldxWtJrRbaouuVj zPuFaEE1EU&7aa7Lx(K76QP2%=N>NzA1O@ewMfq zZt$3~w?}N^x*a(H7aemQ8@@U$-uwinKJIDgITk+B39kJb>a{`rskFv-JLgzqvGZG| zQkS}1<5I>o?WCeyDIt+Z$SW#f`fE-`V=Mj5mTd)1>e(f)OUY>z&4#&N1#{<1@}VZI znVkc(h<1pU!w(?GmY9&%30epLHFI0wpT4NW)Y7z(vrGI<6h9|IyPip50mQmB1U=ZC z`C36n&#_T@ARpRBn}ut+j49E@1xZ{!+pTQ{GrShvZk`M>TV{_E_Z z9vvG?)$0S0_0L+4DI6N3bXQe|#TY4YN&Maj_w{f062<(G?1E@v`!;`qnjE&uMo)RcyWY{c*Xo=?Bs` z850K#xg)`w&c+JG5hUo^S64}qPpw2227}K56#94PQqHqFnG@IjMaqT zqj2kZLPEJ7Rtim|Z10o~-lU>W0gBdP%2X$1TxA{X$b051En<63S?@}WI4zFRwP&03 zWXXsP&iS(7@c-WM!wL<+e9Y4S21L=>K*UhMpe|JeX9^GQNKvCm&>R0OpQC=aMw&%? zz%F?!L;Ht#{HHquO6naAn&m@t9(IoYuL4l?$W5p;AZ#2}y<7uoh6Nci8IfWEX`n*? z5L5hqkkoRG12j%Jpa})1Du!lOF)$lSNh3Y*J@s7>Djqr*%HV9EDFVhEVn(n#i=WzB zwu7wye=zN*!ADbQ zr4vxfv=T!~6?dRcbSeB#aDh;`0l}ceHST~Aa-BJYUpS}@3hpLjAHL>BagPI>siS$T zLgYrU71p>T0yI7!7tDo6DdpOO4#RYa_RX76UC*=h&A$~Bl$nJ- z_V)}<)Zreh#HezR%r!VtZb4 zbH_qlAFj|29f8M3%h$n~qbnz*Z1?xoGZq4!@YzzSoj@ADz8lIG&#^Dc9Zd|;Y(`-n ziQ*$@VODJv`H}Q=5((objp0;K>kDTAjzDhypm~)b}*mQV}I+G z-a}WFe)9ZliSYueYtW#>2VGiky^vwdYy8sr(`ZviA>A;wpo=^K*@JbC>C#M1>sX-1 z{I$nmP#OKhnn*qeP-g^NOI(`$s7^diZw0D`daN|hUkhr-ZOZx=)u~cgJ2egGh8=qd z1r!{)c7`1i#;nCeUzvVbA8i==6iPgctn=4QdiW89KPh4Z@^onD%U>vbbiL_ox$gLt zjr^l>=skb2(t(F?MHBA{VnM4}J7mI;*7nEW^kWe9}`NTi9Jr z0A?>7U*KMKc){}l_RPO+?J?NPz7&t*{ZTUqo6eK^5>!q(Y0$EO%___pz&EDL4T3QH zK^D=JEQ6ESE(FjOdWR|)nR|#acrkG>zT)~t9Ubg3*e-~#6R&4g(Q;;^shON7`^_D> zj_Y;HVJBfpm9>>Ia@P!hABunDm4e1QsXzQ+DOflW__QI-+4tS=!u$z$jfLV6y)7KD z@pp}%=};>k?<;IDGuOOE73;NJl0&EW7Id2DV~e4rdgo`E~zZB(^?A zvQ>;rXk}J?v*0#=SoOLB%llx&f(9e3Gm-**6fd0BRM+C!=3uxa4`u{d-_09p_=pYEJR1e= zMO(*1ZN8vGVpcOGZtz~WM}H^RNG~W@!8oq3ZjFQA*1Q}U=;L9KuwrPy05>}s)p-{Q zSFI7W>`kvjE1+7E;Z=n97j&Q{W`6IyKQ{kI#8YlwzSl3I-$$*B^)4Xq<2LcLmEIb! zhZ@HArcvGf^_w#*;|+byH4QI2rR^*(t+Sq|@x-kY`fz9>vhMApu`|l?q(rjyju9cu zvfz}0t#FapqbzxE#v|GO;;QUy2l9|^#VV=)jY)T`5noX%eYoM8lM#x0^3P11e#(ml z*bWcb=-k!=E{N~`S4pnE@Tx@%U#PIq1C1Kc@peTSz99!Dlv8esk^>+iLAvdV8L`+O zEaR$k{7LxYD_+OJ=Y}FH3830SCx7j)U`qCexnYZ2Ss`W|>de}r`}A3jSdcx4YQ&6T zmaim;OP7J&9n(pqcDsOBorUb~0bMY0>>=1{ViX-O^}Q#9{z}P$wAU?47p(%#kQo~p zI!)dEcUMBV*;eftt*T0;`EPDKRbr;wlQA2hG~GKRWF~(MA$D>sH$Ngg2mhEXK;=1h zH$|>RLl^UCOT;JLx5mF63ZE52&3%wDqE($UMbsL%3el8?+5+OyMn2F2HA8lhoDcQ8 z9H6g{lU|qMw7jfjR3e2%_J01!SB+Dq?`M-2TMecQ{qJ!S`)1Bksc)=S9qX#$s>-1+W$%J>$)Qd*wBpV*SYw(BGq1L=;I-Yv8l{^Z`?ah zF9LE>VsGSYUiKZ@?$b4+gglAkqx#)2GGokS|6O%X4s|5ZTgY2RzMZvAd`LnZGJZ3A z$t(OeZfo|^_XC|yB99We8?e({i;SVnsV6MioBtHL@lqswR;sZB2X*jm0-&7VPk7Pp zfV0nw%Y-A=pkg+-lL1E{nK0aoFHMa*9~P3RDY3dgclv{*#fmM+T*J5VkMub-Kz~D1 zhe6yn3AyhMakh9NtWwmS>iy09dfq1(%edVWwY<1UHY>B7a{DNnmUw9aBeR}RTHl{H z_&VsTnI9z%O1^Z&D?&kp;l0^F(D%6^A z$D(a4QxqM?A}t3fhNYRZt*qc8D&GbPt$n75GyoY&Cm1{LjI9PFc`?HW6*Su(Kg zN1z=?$CW)c%_MzwJnIo_BIJ7viv_t`9G1_jVic8A5}J$d&`)9s``7%!z)P%9H}{%) zSJ~L-ZzGkza>J4R;(Se~@JApzksd2k(S^lgLVw%JJwXn8HJ8${NZ#fS9r%lPHkWv~ z$d0*+qDY?h%v+WrMbCZbmQx{RJLPxJh4NPxpQo_pSF~>~?iAj;Af~YcSVG*acYo?6Yhrvz27)`MmSM}hRadW+cW^FHZDwzA&(t+6gSjyVDLRAhlJ92C+-&chaG z{66Rr{G%*1`!j5N$cR5}W-TWOl(`+)AwSgQ(0QQ-*(a+AIgvaM_Vv{=o-xCUm_+a* zN`8A3*~y^BVzvNX>!&DOZ51M#r`%DjE6B?ZmTKB2UgXg|Z`0Hzfnqyvbl`czEzuL{ z*KBok6miF90_vj#Spc2(wrNs~ToY7R;`lIZ*aup|1)2#E0kge*?iHUI&!*q+Phu$` z=G&Z>ru2!m{YS?^3X6L-B};%Cipntc86p}%=Yl;6TY9B(AW zSo8Bdol}1ndSbRHG_H|V|`OF8Q-;EF&@ zO8!LQrb2-ALpL>yPZke|nOPkhJNSTvO?XmMRkgPb5)E5kX(DWO8`Cjy>NUMr28`%^ zU0#7j*39#~5|tn#4dtnR_zJA5C>h$T7cJ^80heiez{mhJa5M(nk`y^Z8VRUG)M)|FhNjQPGGMn{OWeP+$)K8!t+ z>n0nF)4z3yWm7K4KUXC_dv$S7GKf*Kz{Puxo?WyB7X3bcGI0}eg~lq@6D+|>d5jr7 zve9x@GYtpCw#cVp5_6x9sb$X3CyABm#a2wh6@l@@so*rTWl)u4HAT%Ik>^IYMbVWa zID*&cJS=p=WV8|iin;FI481&`MB>P(pFYyJtEEeo_jb(BJ^8LTQS>g7@U_Ng^P~@E zx+s{3P=WL(JtI`-Sm$2ECV$x_pxxkl*N>4Cx~|>ANkE-lm-vS$})G<`$B@|MYYiBz8$Mdk+o1vw49tn@2pXrC2gnOHlKiL zTj~BrY1{ozgR7+P7`BNM>!@K@)pUP_;9rDM9~81($sNB_ylhjlY$yB;l1i97k3wNX zVW{xOCQ89Qptv{C?}t*)O*7;`uH_I@TE-ldb!N({V_r)}rSPpfaba>E|dlnB^rs&u#v6vmcQUN-0Dt=A|c z0R_bMrH28>GRd?gHsAG$59vkxS1Ste*@>-2a}x6Ma*35_k49O^hs)J`+3t_9U3_*8 zKHM2Lx$>P;rCl$vI9+5CKcmBukQi2GVIl>~6}4co3~h0XQ|AT2y$&EVD2`Q|iVtt6 z22m{9xJ@k~2D?zb_u7fjYt$wbc6)2PonFgKpLslh3AOQfeQ$*alMc0#mm0@NC6=X+y-KsmD) zz3ug=v6#sZmR4DX^EbvZdDV|)N|{}!;J@LV3Qd~=lm7rttS_+y#Sp1h;s#wVd~_|x z7%nzB7_L_4UqgCn>#=%_#oyZ1^I&{aGD*MJ($uT5@3TtU&PG!4quiCk!v#~|h4?@7 z&!&}1sU;X@!A54yMay}s%Y?48EE>(bCqFW^kDhC?l@}r!2vhm(sc_G$K}4%l-JgY7 zq8-w_Vc_`y#w+kolwgTOMpQ9iit#pLL+{^!?j(4qUB7U4ypZS`&&3J^`6g;q~)ZPmM zpBsfDE&H=KQcp7+e%@GWbVq+rXkz@$gD--eFr(A{l}3IUi=>6OH#8s4++ga#YOrw={5b_*;M^h5Vm6o(Hdah-A7oBtO z__%iRK6Y?XC)h_)at*{E5*(1L%4)x9p&mUH&DEYg=?y&t3G-f|^PmvKX}usb7Sf?! z>Fw#|9u@BBU+C#>l)CZn-PH>u@kVU9z3G^^7=LpQ=x8BQE?QuYR&=+a_$5OO$JepI z$S<)N2oVKCH-6$N3nit<)Vy~oRwP4vv2E3wpr$rD_KD~RH4#7Z?P{`JEA}&gCp_Nw zZ~P3jOI`f=QKZSXAp+b=4%7m-rkeSE`?tcyN~MyT%p(F_n_*x6o{5&U9n_-fUT;%GOme)eNc zxAXj@*JjLYkzMx#GdcFh1bKZ!0H4Mfz*W*!KMC)gFg-Rc?0H@7Gkw866nUg!#u+c# ziV9^2j$d>cRGlka9=BLSniCt9)TdmpJ_HRIf@mtX0=xEWSnS9ZWdw_t;=UK$W@YyNDKS-?Jc+ zLSA=#vSZtCI7zO7)_PoOhArAmPWkkc4w`$$%WrLAmtUjf??`GLaMAwE-P+V`@_1W{ zWW=J9y2GJ@PiEmCSHifVmM`5NdI1A}e4Bs-*=w$i%L^T7UQlgqWN--ufRekxx3=O3 zUDI*pi@{&*)peLa1v@e)3+}}NoMp#C^5K#90N2Y8gv6(mq^<07j$9I}W~*xTX_TPb z#S@}ZF58N-u~AVlrhrTxJW+b=)UP?2L-ASb3F6_>U&=;@n4DuenqjusKsw~Iy3dUz z4oU>#u!l)fzr8G&y9BPON!Yl3zvS|_GeRr#lw=Do;ZX?0XIf@8S*2cPIf1y=khjWR z;aabnTcXFRM9FRnq+=K>{~8N&Zg5u}rrt@Y-W%%O5VgdC?El<7l!r$gk^qS6!Sx^i z_y>@`I`4~@C45QW3pJ-o(rU3!;9GbxfLYK}`7VGG64SU*b`gD+3S~ z<};TB$JwDsKY~i4KL-$A2_{}hiB-l4h|k{KQF`)a7>k(nE6CAMmzM#!Cdfr+#Ky8l zL?OV2y&Y|^rr_;VIYFa4fuD;71F{&7^^tf41VjvKn=FU>@ z2F}r&7f3uNUAsa)iuXQoV%CseS?isXr@H|>4bAnq`c>17?#|bpun&%EMh5M<^^#gj z->#Y4TTF>)Fsu|;{V!7y_I2$yoWGQih2Z9rxUY+2)2%+wy*b)7$uWUxir&HgS}sCNXN(QThcEJ@V96UBopkyiJ8pIGUa%! zT{Fb;>p!u}!tCSHqZT6lq+eQoRP(VYG^@8FKOxP5h|_YN-eVxMVa=yC+FR>cJ*Sui>I=gP%3)zTFHf^1O)CfQZV2GWl?8;-2E{KmjL zp)086CO^CrlV!m4J+O~u?58MtT4+*DhKdaULWG$NaB(SrB2r8)>Eu{+7Yvq$IH*#j z+41#?4Jt5YuBu??Y_Vb6?|e@)R0Fo~Dlymm*PoIMDPLxN2!YX)WOR*9CUk>Rasap^ z3w9FUV7N~*916)i_}}e0+j!^g9*ZqzCV0Gi5q|g?-FjV71`y0TVvGI_raVWsdS3*l z26!^7`n!M*7+ob6!nDIGq%Depr-i}7!-$o6WJeFanSWyAV|i94*SXipCUmp96iU5% z`HL4OWpW~~-#f5avaW5N=k>=QMoL7N%)yaEC{dhg<5~QY9vQB-<-C66;FBNFUj41j z5el=>3=b453Q)`+$P+dGa05=)bz{)A4fC|<&?0bTba3_Ezv|+sy}LG+l$7+@S^*;d zw9IeLQ6Q0c^N^6_Er!U1znpiHWBC6|Kuuf}iq)Dp{l)uZf}|X75}L+MdR)Z3#ZCZ>cBa_Y3$i6TT4G3tINAu$exuDf$>; z4{%AY`iyXvxu$|xRRLVlcs38S3WM$(*N0O>(0DN-$6qNsW8$uUG=dpv%Q8*2L`ZLA^!cC<` zUBK)D>~T-8iibWqsLm~GP*IA8MGFVaK9q==i4I4>BgV(VUWK+x&k#CD8#b|O_|HCH z(0i;!18d(42cw_zCK>Ee4Q(o|pL3Cr0pPbL6_e;N~~JA zrl7Hs%(vPf{w*IyC3VpPe4{#bH}Z*jx|l6VHRdmxvIx{&FAuT=PNKiS(4%?^9u}s= z(2oVhx#xTnJ+Pl&e4Q{;GpoR@Q0jc6wcUERwlB|J8!NK0J7~#?Pq!>P(Kchu#qAGq zOlA3LdK5`={3iY0%W-B9=fW?aNpX?ahm`Ce^n0ocFBX>~#WsHZU{0%?zGywq`QZ^C zd2w{PtGSw8x|kefc3U&jui>Zp9uVYkfjB16R*hBWed#N`|7~{%25raL%Qe4Sn8};U zUF{ZqS9wFSD{vDU2GYxrSVa2at4kil^WQ+2%Puc}249u&_}X0$0)YL@FklHC$e)D0+7O6q$EAEY(MY&XGN?-8J-dvI)jd_fi$LvU*;J`yNR z@JcmBFBUteP=y5JLtD&tO>xy%5A}U35DX28S&}Y>Ef-|`i@W)^xg^Nj!R9tdY$dqmDW7dZRWXEs(;3D>hul^bxaM)x+x6+^MdQyb}Y#O}2 zj6()RxV6Rh@_?@aru>ePxpO?cjsufMi&{)b9G{=E<%NtA@|LUv_!Sg8MhJymf6srO zD5mM&?D zB@T0yo|3`{U*9Xa(4Nn&_^3?YjSCiv>~rOu}k{Ecjb=vBXuiAc&;{OO0u{CSa8t}W<_^W-dSHX~|gvqWXq z5@quQGzmJPhSI0p)319O5!u2}&GIx|{tk)Md4JN(lz;I#74&t*jY|slF|!rxIEiJO zvuo!^9IW-CW#@g7XH0fZdzapvFh!X*3w^;3hSfw-`VC4Wj>e5Dsln~YbTm>~3An@Us5OOPiSO5jYs5vzo4 z5U8jo7b94xPPi(SjtARK{l-rcv%r*)WboxD8o8gege(~Mi_AjlsN)7I{cYtEcM3w| z=#Z{c{`8@G{N_)90xR{IHyvYro;y6h8hz5Gu*$pmeJX)k7_!spKiSj?1=a1zzGTIcNW-9+qW@jo=zuv78`QqZ}gK(r$fx0XaismE^>=*2CjwyI3KqKI(f7|h&9-*2JC;0uxJX`KG6w{47U;{* zxzRpRox<*rSzcmO!Q7$Ldse2q)V}&As1^aHd2N?c#O+U5Bqyk4(5La&>&6@efM}GlGv)BlzL!s>h<D|J4h(cQDg#QkDDrgv(fHL&f+%q3u
      OZhf%-&)yWSF%O@`tNOBsg@9g~<68&1b1-IcJ- zDfk)@7Cn@umSUm-q^ltHG(K%m-=dKNfcozzRp(Ime4x5;FC~TUHKg^Y1e{lW%`lzI z(`$dKVi2!uQQ}dFT}M!IYVmI%#KiTntGSRgtE(H9NdruP=D5cSfqhA!^l}+vyX5Cu zNHT#+G+3lMkr<9VL5<9S5Yc$8I^NLdr#}$0HFrzYD z?xG=pRv4t9zo5{{PKRj)e`+AasZ1azxMqcmAeL;2it^TgVCqTcA<_XNX>W`MwFH4zN z_1K&`+&b90H&|rrpLcIxpn-}v{m-YfxX+Yye(;$<% z){Dq8oT4VTr0hFrlv8$ZeFLrqI;nQrX2;hx4N{E8&Wj!p1BBP_ zCBu*nDPN&NXVAfz#)>?z z0CY%L9+mMx-OE?nDyP695y2K$os%w`8pQ`9)QFXG>0%r!QK({=rz+eG>!s~MeIJ*K zg?gqmd&&GnLe+CfXvesEI- zqF3N|EaTDld*euQ=OF1L5Q0_0f~rbX>LE>90?bSX9FYLzm?;+mCSGxGZxRhlfl2;b=>&(9jO>Z?%ol}{Q|8Tj=$$+H}DF1TdLA!CC{Tw#ChZ0BK^7JM)GoinnJD2 zSmN5>G?k!MTUz4CzWhthvgdodyHPei+I^+E*RLO6gQ7k<2Am%KC^SMv@{VzOLyr$6 zQQwCqeR|&v2Wf-ueSJXwVULI<2$?Sy^6zbQ{~Yx*@%Al@U=nJ74|?o$5E(j|8-R}Q zW1LkCqifOm$OV&lnhW3OjD~{v8sIMhhYrbDNsmlJy+dRc64PH4Ol%L702dE`F4pZH zmxe?d`ZT+t-%B2Z>$m4-9t4QRA3f?z3%w9f>!IHj-`h$H-4OIeyl~&IT<*MX-}HH$ zqH3HI-UEFieu?wwA1AFG!hlRVuJPdEgPwOM-j4P+`F6hRKYIMTmk$!4btZPoGy(Mo zdW%jEuJ0bc5pR&8twac9dZB%gZMLlcd{{q7O+j0IGmu^}aljf$3qwl+)2fh3>q>_} z?exP95G25Dl3_-&AynD^f#i!n=>N7Vf&imBDH>jrtO2=C%_FT~Ps*O-i7b0f9^hGR zl;pK>xyTJDtTVJMrQ#l@ZTYqGAP#Qc*^h)nhD*c)d%up&LY^w&GVXmB*{9*eUpcWN zj?Vp6^z@6SweThi4vIgD5+|f)iXQ=&vFL7*$(gH;IWDOaAY;6j3|73z%uuiCkPV^& zH%oWs=~ImzOdvt2rn_~TxgY3@Nhg$rP&TSeSBSFeU{kilzCYN(Bq&CGhdtImqe3X* zXL(DG{zAbLnwLj(%KZ6k)z%_t&>ZaQ&JECyb<2)ROGwiM9D(d7mW-$rv*8lCVBDQ% zitp0FTzb~vlA2rz>Lc7MhT>>BB~>-|VL&98f{l-fszJ?nlFZ9Xdoqd$CDt8f7NC%(BkQizEgH(1SgkNqBy5CY z3{%j_K9;=-Sactc9`t-;J*&+|K-M;O^P#B>p=4>Y%VFn$ce)8J)a(uz`f;%qBM`+a z_^v?k*kHh4EDY^LoYU+wkrt&v=7;-S8>WqVBQW@D4$Y>qm((luQcToP1r7?2{GS!! zzRbP!UnU4mTM-HbQ{lxUNK8oTZv8gbBqW}^i0kpB!}aAm#u|-E38z@Jn{i?Wn-SIs zGryxNW%-w&5%|P9lKd{ntBFJ`B0A-bEEsZ-cBj?4J4y%)>c}Xx5_QNuSz75^&(kd= zf%@x&h7j?3P$Npnq0de=Fn2H~i|lgMyUV5SyVca6wPijp8>+}_9byTjT-onO?Ql@_ zADq>Vz&RboC7u|#gXl?G2&DoGaS7n?dZM{=99(qVj|7lDGu261a_u&FK_RNubQD!@ zBk{B?TJEq9*%ay9)xclICzKyR0UNNYyr_43{o)EK4Zo_W7GG5J?PDi3r_0=xgbbl; zmg(7qU=GM!ojKv=fweZUTJcuL$6oh9?7}@C++QsRh$O$lM&Pk2+J+~;{gMDBP>wqI zN)Oq2R&Ryi;-Z$_-KYUN(|S+OQYC$>FPVEJw#lA<-dO}LcuFZH#rDiKa&CdgzdMP- zJKnN-t?cg?X;Ej4X7jVV)E#Hs{ZLz~u)m9Rx!tRIVgF{mL|e$7>t%BD*IPxd0#Ru4 zKq-s2Wuy$f*Hc3L?Qg`F^gl8o7JobaD=fGG`j&Mz6DoxvQMQGRSW-q!L4|YAz4Sqq zkVb=PVK05>a9_61@phfS=Y7iwjt}!Gh1Gq~GlWnE0xthbub|K$3nXh`w?h7r5+~R^ zLbx2soR9DDoau?VhoZY{6=`8WZJ~azelRm~;e>f^-vg64(k4}(vMGgZuOh{Q1{?sO zxyYet*7)zd3LPeFlt;Z8p4eCC=RN{!8dEM!jw2qzkve-Bp>mgJrEy~ z(X1_=DxQXkYr-E~lo}r4CC6d{*SHab1JV9I(>Y6Sn-o=m?ST!#@;yQu=a1?xJ|q+@ zs{00j6X8GWPSx9f_}0D9GcL|^`yE`-|Es;XjLRwu`$kbgM7lv5K|s1&K)Sn2knZk~ z?vUA;F2xUT+M`DAk`;_N zLE<_~%2)!qQLDJl@_UFd>}6-a0J6J@r*Vl56Zl>SNQ`+0vRtU4S4k56;y&mpPF)$) zs|bBRBqm-BuJIl*)XLwY^94$DxAXJ9jR?`wblyxYAI-`bu6+|WRUQ$glwYxq;zMI# zsZaRonFW&5D_C@}W^Ig_TBPl2=Aux|ZE%X8g>dnziw&KRRFGox!8yYNo~=dS8j*%ieR5 zkIN<`rY?itxB?UAm*6XY|H1RWu^@hf-=OKRs;Wy~0{}+Daf8jU&{{+85NBuv+ zZ|JC6IXTh32v@UPFO3JQh4>49!_Lh$Fbg+|!g+1qa+W*i$v~WZVP|JaAn_T;ofXCA zE-HY(ab<{GbMNBY6Q!Hg%hmUAv{xd*@vwFUFKJRwOg67WF^66gCDAPc84tp?3Py_hEm0SK;A`Tw3(1q@sIl)SaDHCSFVw$VQwv43j|?*{ zR*V&#Cm9t{oY8c2#~(grK72LzRFr}7UAD2G+J1O4F2^e?bE z+_p8)3t=25bHne{o8cu76SS)TQ>Pk6;9($u!t0Cp|q+NMhY>&Dy z)>xAMRNh-}WGAU>DTjXY7Qa-dyF)fSBuVl!k=^akZxA6Az7jO zlgn3Kr`L4=07pCsfJ5@6EDH*n8I6twrok1hJ`t089C zvHX#;iD2h&MF&T%$4PEd7iTuc_B5wZIDXjGHyNjkPK}K$2c@QwUyl1+@lzS!8+m7C ztKclJAd!?;K`5DuyQ_IdHY{EC!(a)loBsT!%f7*}E0_~O*WH5;HigGcF9ihn_=mdE zHz7vcM55MS8*}q(bO0T-}|Z#s+jGZYEeb-|jvl zaE$rouda#=XO=T-Okq%CB+eW_u(_-{f#eS3u%|YP#)P(`cP6gD~Ch2o7u~o zb7eCT|01F>_x{(%RQ=VJi$1!!=Ru)cS6zcr?%SkBZy*YM1=$PtKjx`brY*Fa*kQMM zrS32-z!pJBcg`ZPXAAkWS-XxgKCQPHot*K;50De`6#UTL4I66;PQt%C$j6|^8*+Xv zP?Q2e@kC*g0HV9h;duLuWWZ|J0p%t(Wh5Jmnzx6HgP|}sHpw@6Bo!VvF&&8}*MwRR zJBTxSSyI0r%RS^FkS@;p0~m%am~5h>a_%~jA8(j1T@PI;TbHe%nANn4OCEOkBRn6HEXT6$6>Ub7i=JJxZRT1IO2%^IK@8bvX2ULbi?^N; zBTV4^fF8!RaFE-0AoFz|L~D>+rbx0(e%~M%BMY6 zGiFPd43TI0eMVos=tvnl8?bf_S=oc>dT~Z-_%!vgxf*M3crrG;g5>VfBc*mwaxZK~_0X;;YE(F%9zCc-?tw*eycgvZsc*9TEt z07at%We(nZQZfem1oP}C2FFxKMFZZ8KIOKJFYum}ju%xqXk+a)Y6XrqbfB}xiToQStj-XbDmls_v_UUWus=|ziTwC?`qs_)Wn4s@ zW;8E%x%ZjzrmN@iZ9!Nag->W}7Q8XklMpiDX$hX&NnIo&*5Ba0bEY{3AUImg#4Zw% ziZH)v!cBevus(PXs+v|hCL1Y~V5kH{k5j5m)^!saN1G6e+@DR}PFoy~-IkYLG2LpO z3_LvIcn!3%Q$qsyf_8sFa{L=uAP98fSH?W2vST*GgmT}UOCy)I`H41SFDqcK{YjOU zu}2lD(^Xk&FkcrRsWg5*%ht}W__+={5xT3Ofv11LBjeM?_6)6B}2p}ruI7~4968B<0`U}p+szlBC>jQ`KYNb@k<40 z_myQ?sV^q|s0^HFAo5A9Fw2Gb!);AS6`z1e;v5FC0Q(SZEQ{q=-4|`b> zV+xDuq?F_QNONLdGC|q_(L#gHKvjXDouCf|aw>*fAl_ z#9C)oj+n4Qi59ui`)MY@`A$U+53~7z8zP!0GDl*S2G!J(JGP} z#DmQGHmlTaY=KJaQ!)aI|c9JTUyEG34 zgP#)4b{4%IQH+8mpQPDqn((iOc||GmYmf9t@R*4b=Amin~1mun*?Zs$+X5wfIWuo-f9_X!;WMX5AxEbM6FD&>qh zx`m$9`>uXwf2#{EErZJISli;6F!=&L@%%YDrrt9&#}+6e`kJ{C3)nXp7ebl_RKm+^aW`?c=Px<4V?OX_}p3TO{BNlY?d6vEKOf`DLc~ODCDS`ll!?c_5y<6DE_$e%Bx8u`o(L>3e z^a>$=GssijF47^pI8ph)c%l?7^ggSD%5-&{&|MKE@M`G3DCLG6&456R{R37u{GAaf zeqnAgG{^!^P0`_jHtCGPthFGr}pyoe7O$_CuI6NrlMzui5U8RR?K+)`Q9*DS$g z2x_K;WIjikT~kbAHJ(OXEDa%@ygjL|F3kL><7F{Dh)pj?CuA{+Z8KGcJj#xTfV^j5{mO6~fT6v;?30IT=y z@$N=$yp!e9Gx%8If+>NbZybx{>|YPk7fj0`l4UK@@M?22El{%-QqQ{$LtK_w-M_~=K*6Z86<%wdm7fYA3xUoaw(K9|#lwSBzYVBTtXKS%R z!z!>Bl)UeP*k<1#vsd60Kj8I5Y9Y^#qz_z1(K*#b%l?Kcn=!_!nEiWI+v(BQqGSsr zGao&aAQF@PcW0wlFE+jDhM_;t zGc{jeT)*q8<4S28dMOWWMbY@O_JE}?ZQLf0#6<5Kx7OEn^Zq`_Al*AfGpMr7zO}VA z$4Q(*!EQJxoN8l|y4MLJ1{DWReo1TJOYS8OvfT#tX3QMu?ROZzJH26%ryPb)Ksa}3 z2%Ek*^CN|fQ$LNf&2`NQqcj~vkKlCHvkZJY?mfAY>daT6U<4ZvzFi2{hm5(GnZ|yC zuR}#2t~7Lu!Y|6e1;r$dl8{RJrD*V5A2q$cgkHA5CZX2UW5D);EJ{8q5Xq$OfHFGP}NQV}#iE6MlWoAXF?<)l3{w02Pak;7?Sn ze+$7dKnOO~GBecEwYH(M($VXS>@)MCLGV7{@X_s`>uLyksg&XqT@NCuP6>I-8 zl%Arr%}!dl;{`rv&>UNSTKP+@Dw#&VD*VqL+#yh6-QG4{*mV-39rQ6L(yT4%d&`|4 z8b`b`I6fSbhYn26`@`g{X)HFD?yGq%xI`N`?SFK#9qBk)cpdd2iEdwVyPnE>#?Lr30QSp(Vm-M$v#XBgqUP%Pq7yl;QOmk zPs0Ll=xcPn7e-uOCPW7@?oYto`5*Pt;`*jzbhp|IitW^WkE~BqnX9p0mE%O9 z@IghYq4Zbj+*Nd_;2G~za7{`#Lm)M2$0O#TkILdRD>Y^;_2qVWSGzEP-`+VmHc3} ze=8}47#TsA7GbJrl}VnlS{1QYCqt}W5Mna(?6p-kWLB(AP8 zfnt+AEhTba##3YT5NQQX-Gxwbv*)cDE#^#Ncym@qkRU;ttd!kG0)l+~KME3L2iCea zHil;UkLbyJYNqDPEC}~*%^Ax(fos|Ijh-qB5--AW2iJW}f)v=|+hG-uu{tDVuXhHZ zq$;CK$inyJk54?p+uii&a0e!(cfaDnYgyQY5&Dv`Qjaw$hzk1GjJCCNQHShGTveQA zo=spjHg-@MIgN(!@;Ss4^z$Ry5q&`(SDSrD-GOK*^Ml4134?Ha)hx0fL0R7T9rawV zH)Sygc-(AqY);ZZLbON(k!Ivd3BxgYr9h^1*M4zeUDT|$yQ*~1@BqKGNGf-N}ob@y_EO@-WXyy15CcsE=@r+G3Z1O=RKuXNn>x`89B{9XeQAJYM?NJ^o?wA_I% z4kSGX6oNlO#a3ZOUDpP^B{H&xk^I2h65)CNS;6WCjP=yXl@amLg@Ut{yDjGzHzOfm z@DvMj7pm5%{VWu|xAVgPP>uD8=qrjEL%c`rs~*B2uB*;@v+~)(Lx$Yef4ZJQTzKNN zBE9s7YG6|#5&;@y(p^vc6eXM#rr+Sel7q5r$ZLU2@@^V*&Sj^}D@l9fnb=WgtbD9` z=?epIJhCO4QoSeZ&$iRg(Bg*;;7bG%JI$nbji*Z}Y<_6ms69Nr^yoR_?4A@Cy2U;j zwSTR-<-90VmBDz@+MCkg7qUsN;A17x_6#YE4A!*8N-9i37zd*rczBypxn0bJKuZBz z-K@(s^?5d7I16j(Oz2%Y19y0o3P<3O-a0ILDoJ?5jB?gOm9Z`>K1tUq_)X)-&sanF zaoigz!6`oSmrep&!(rY*)QQ(g^n!gPreR1A-(et?_F~y?0_^(KtGasZAjX8mdoiB-%s&WpNWxR#bB-g zj^G0iMT#M<@LMs@fH;fd*`wwc+3ddcw$~xnpIo}``FI32$A zCLr6tlJ>+qX*^x@`n(42X#K?Z^8A1s4So4V4(x48EJ25FqNl9f(3E`6w+Z!iJQT!l zG(?KDmX0vYy@v3};}6^!+aIl%6CA@cZ>ym@A6CjddtK=+TpjkEMUnhj<+T>Sdu-}M z3=ZhExU@@+`eNgz+>7*{`^5V$6K(K+E76R#lcX;?j=t{kBnS#{&pI#Z?mXN6>_gbF z!|su-gLt`orl^AaW3Y=E0vV%El+tznUM8Qj#;$Kve4}-rUF4>YK1rh3uTpsPTHvf@ zbH?k6TYmTGti!~G6AUjvy0LBUBMI(6bk*Dwm%}^~Cw+_>Ergn`pbV}jgP(L$iu)PC zaul3S+XvG0G}yXeYn}%}SI91c@k36(2zKdsZiE{AY4~|EcrcRg%R2eRHzKe$%^sFd zUD9Ab!J@pTWET2{UGZelBX0tyh!0A+3c8NUh`EXM+u$doJSkU(Q(CZ>V8v1riuBRk zDp+7`U}Ib#TS!Q!N}Bn*Lba9q#mlA}pr@y$-!G3WFK42LhqK@Z!+%a_P+uL%*zj^Q zlBX@SaMgWY_bLvB&>&v2V~_|7O^u@S1rk!~i+c8=<*bh`@c!?{>G|+vpAO!|Sya77 z8qDGD9h4YW?#OTCe~4w%Ixq6ky5SX+AHz3_%n<7rskCOPL2{Mn$s{F&!@ETckOUg$E` zhZi(*k!v+?$$P}_%nEz#(UJbONtS+MYADCyw`7CuvyAfC5;NbE=B0;y*&F(CGQrwf z-PA_>;nwBh?hPA5!iND~zU0;ybsTpH?hA7y*Ws76E{%(BSNt@D>}F%!D{^jd#)?yx z=ua`UgvJ#mDU`|0CltfOgz+Mia_2mGUeBBF9Mn5)i`N&cXk;%@yr;N}xnJB#qjU&M z>Ih|u<%1<9*RE{WE)yZiNDpaM=D{0RHbA|}=hM#5^Mu@-^i&L-Q^eEOovU{{ z{oLv+p=gCG!Hz_wg=YgCF^9eSz&p{-4evHc@*RRVb#uFU?&i&Cw5p;?j+JdP#O4S2 zm&EdUtfN3qL@l(E{Bo2 zh;GTz(Yy(}4cV(I2$451dO<|(XX4_w^eTqJDXQ`18zDI~Pa;ZZNToA274C@UowfL_ zS94ILlXlT_mqsHz@0u>!it0kuW7+vlyV_re&s6$!=OsOdB$n;B6(E1r(~d~)hSqyv zd%Vbz_qGD8y&Z`x)z5q|s>laI#>M2qXaqX~k)!$5+}mag zvIEZXoPhgatiak;f@KCUT-b?=7d<~NOe-Mea-cn_1oulF@mrO~KE)jeDIrl83T2D_a*-jxV`#O#RcL%iRmp4JCFrD z12W?OPUoNj?*H~cYcKiAdPTsl(|tfQJ)%Hu9?xNMIlWBJIO)ucslZaEidisQhRola z=sQshSUAH<^E;MTC_;!j%mFK$r}k>Z%0#a&8!|PUzwoz9dCC)xB4_UH8Ned z?U0*uo@@l2t?ZpGxZhcuTitbrJsdVZ9G1p8GF!W!Hyn>ko3EE-US7!0I^oRgEX-?g zLGEBJz@jhpO{+UDi8It6G0(G^+sblWziCuB7shZ^7h#r!r>Y8Vp#E&KvO1YuwcmIf zJ>nHqwBd2{c7}zONx`V>%8PpDQnY55^RjGQ5sO)6SK39HYP@+)gNuJ?U601W)pf5~ z#g)qe8)Ib4CfuzaBE>Xph6A$aH1En}k+N}Bd+FOIme=iMGpHqOIFN^J?*u7&^lBi z2=5My_8A=oE)|E}8RCXUK;${(YN(%$pOxJNkXwYh?_TA%dCv>l6H|;#io(qi^`dazg06J7JDy z;T@h9rFV-2{fJKR`@K7TjZ<{Dm#%0l)p(k^?j*C-6ZSz4--O1T&w}bhomH^?Pk0rB z)+T0l%;!Sz+$PznZVs=FHb%RS8U@X9$O+-lmv#tY>_aChGL*5UG-p42c3N0unbxq zeEFr8Ir7B^YJW5hhqJ|nS;&+d)r0vUc59c`)!{45j-`?y#|UN&J$DX`BANTA{j^M9 z$*QE?zxeAh`Y>(53mO^Nc^UY=N*F;&&^;3u4KW=>Ni;l94tS|5H7@+@!4{t4K1(Rt zHQMEJl@d2~xom7JapZEk(=nB|WWzk8qg(wvFeGzvO16b+t6BfUjBBUK3wA4bWA+CN z)B(iCv}#MdMvd`h$$77vhTwCZw?87qCpUsDzS=au#I>x_(MFW)bS8JlO*OuAW_ghQ%zjAC={f4I%Mruf77W_oMQ`9jS;OZQK3iJfC8Evs!OS6K2jsF?1(o zqo2~8vHKn>7c3olk`eY5){q^0)0?e%TxqsdpP+?C9quWEM0_r{k(=ykDOe zyYHb+*q&3T!kuUwbcc&jHG&VKzN$Wo8nCXeo?kAR)!l5g_mVwFGb=lwgq+16_qf5R zNzCQEnx{e5Egpe#x;^TK#YNvqB80ARx|CIx8BXCE+dxsT)>TGRG}cM&ba!(0^{^~p zHdDr(4GDFcjIW?Io8rsZN`k?ucA5$8vY(CEy-^aJtE^|LN*Xokkx4YnTq28~U(S9o z!d#y}!`-UADIMAFf_!dhTVX}bOSM9rj>l#XZL}+X5Gi1I$H0Cg-&HSEBl#7%+j=%P zaFkyK$5ygMq(i~OME9+wvXC5YMmhY5a5MSo67+kGIWm(of)a&`v`F)D3$Dhx0G$0? zQMM>$dta&{^U->bDHB3LQ~4N*zo_GJn(U!qN2p0p4D{ z9Zbe`0!CJZ=m;>g>(uDy4D5S(85!0R2}J?4iOKXh(Ca6snuY@u@bBd%5_c> zpdgfO%tj_M!h!_dgSvVB<#6)$uYA2{^`($gP^022`x8acl7&BIT*|=DYv4j`a*W9N zxkb(S92PkvU8g6?MoPiYvEMixZZ3CLs0!Ea9NvitDAZ4Z*9&MWVj5PS-gPd{sS!}} zQR=DE2Q~+>3B^ozl0e@sG^m|z3Bm`hS#5anIhJMCG?H*B-R_eZ4_xdh*LOA&DaJM8 zRI2oD^xT@b?Mie#w11g)_^LGE+mQBfEzxf}L>a@N8mIZjkf+dE#O?qCGP}UD1O4Lu zc4y}JO1v=6@p9F1sPo{fk8#&J_&|?MnKOXhsne*^l(V;&1RqqhKr!cRj=4_U%j4#G znrlEX{@h7x*1qilYNc7*v2k8|?VZz7B}?AqK;)UjRX{6=edH&7r z3O9Qx>$|9`&oevPCNv5wH~MBn8d4qxp=WI=^qZ&}`CzAF?;~MZ^KfhVO_~zc>^)o2R(1 z_GfG;!B$V)U-#Q@%ot}WaybN~HueoC2Z(!oso!4ga}T|Y7z(Er7lhEH^UG{v%svq1 z5>7cF5!R$rJ<5JrT(=_XHAf@w@21^#>2Voj)`G9_LZ3`LrhONCMcH}ibod05*9SS_ z3hL`!MSHpywX;=6;(~^xF4Y#P+Ay1Am*rS&MPe+0~099ExzH7`{XR^NBvkOuT@c&W009&pG5dbYe& zg+LEDlmb0FUaAV9XD3TlmH5X2c4I3d!0Bt*TvX7W-v6sZM9`iBFyOaCo4pp1c^d=P z3}x-48RO4`Ji<)mpi)c7K!GH680zd@VZ{1&{e;JZUr&5to3E_a7Xj8TSuNC0N$Igh z=FO4y&8{_sBQ7SK>Z0@H#8X5h5h6;q{X{(lQfTBpZ)Am#l)7dNQ)2h`DjzJYZ?+cP zZm&i(-EQ}ruep?%?<5~g?k@1;Xl|-lEx-F-l0h}j7k??oSrO45pZtJqqVMXqYY2a*}@NcnD`)GJEIYK}Q*%SjwhotrJ zV+7lDC-?m~iR%HVJM0uQ9^ z4R*)O#W0j$ne=PN=-0<@Emh;{;`UbM8H+yc#H(Vm1)q1qEx$B+h}k@9v5g9* zem!ROQR_LCdfK$%Xz$`%Z*m+p_O~uU?Od+i9p z6fdts05io@Ggb}^sBtISuYOn!o2NHB4?qp%8B>;$MfZB3iMxqjTU#Mw#IY|cVfn@BD|-}rePcJB6TiP^Tr$c^CK`&(Y=VQ@Ceil_eZ3cMrQR1t?(?( zhZS5kdRaI0l1DB%y8?c=wl@mv(o#Be#7n^Hv%OM2hL=IbqW$4&G zUd@(KgqL}jom_#MRmxN!J*uA&eE($!Vk_)kdHc0DxwtFaTbG1uG5+n>W)G8J!fa?A z#|_`g;91`I0qo6s#|Yez^dwrSmmql|{}zpuG<{i8jB5{l)?fz`;vqAjj8-gym)BPO z)m_Gim{;Z<?11)mr=C5R+XK3WD1D!9HKdAE_@n=BBr+WEeponRxmF6pXB%$P74 z4}FG4D9m_jQ}bXnzjYSknjns&!hNCUJ-4_y%g;!%g~28n;I!y1&f zB5F9XzxDvP?5t3wJRW?-z+_UZnG-Y|!CG?oacET(<=%?w0DG)~-@-Yh!}N8_9P{P| z(p^QfSZtNs;UdJ@y)7X-)5xlnt!<%YzwG7rDaobORGf|FX#GxgdF~jTprS1bORO;k z*H5F*;=7%FCGbD+4 zw(1#S#n|g?2Q!we#Way7}m)ha2+;3{JJju9Bv=E_dIu#=v0=? zLwKQFiOX$J`q4B((Ts&v;8W#^xZ6YWvc z5FkpY<7Hrq`mFOv@P4&{yR#UVyou~bX0^Qjg2QWDNgvQxtZTKb)^MCu15DXUyDT%8 zc>e?2mw~D24Gt$Q=7&w6$zjUcf!@BqQ7fsXSx= zCbV%_apr|ddX1iOP&@K)+UM!J9ZE*TG#(Rw4``0$Lp^YvYic`*YCf`YX$_*U$=^G< zveCOxuo&s@(AjgLSr77hriM>7t(1e8J@Js9gdQF$YPn5xJvsJvlS?^neJ+H8I_l=@ zMhGRcKx;sH5cl3K(&TSCG}l5Y4Q(kmk%m&$iYr0_3AjjM&-VL8z@WCR6cWL4WL`yo z`zo4!`fk38>74Tg5DALppE!7hg1OqsrVc7F22?^_6gW}!3Z?4ZM2C4PjUdNQ!s}ft z2*}z#Lq-ZiQO?~!Ry`8gKu$un=&nn>*9*KGrL?pjlh$bdI>+L|5iuKXRU!>x6)M?J z;+-|F^Tz?0?BR2i>X|9r@44;x4?an+oRlr;4a9IU$pC^2=9ptoucN+AKQYZLaA zI}C8|#F@LlE8xG6<+Fhjxg-Yulk!B0a#agGNofG4#r(3N>{ z2qGiZN}b+gwi5wKOi`Rj#RJvsO;ukciW^m0V^+7y)77?|22RZ1%``9YQN=KT=V~sw zs3CYwh>{pRvmvHcSjwsrMODN`HS*p|iH|RqgH+3Mj?_^p36dB-=p@a%g9l3FH09j3 z%L@q&l9*ov*9~+wAs!1NDspP+TSqZ2vs=-gc1?IXq+0eZN^V~xGtii<7GtdvMZz

      |u{68iQd@SV|VcxLHGbKXVAuI|L zx@{F=EdpZ~QW>Qde5~@4gr{pvX0?jB-erXe_YN|Oj}&nNAXGl{bD11Jr%eI($m+EA z$+p-(c}uz!J4o!Pj%G}jS)&a9m&piY+~RsAb?hJalK}u%0deig5+ZHo zhyt@BBo2Gm4_bH#hz+E`RJEfzRJvIxX@liOVP;f#Ze{D*rA*{3e`hP}1Ygt8tL)u1 zaoO$ToP1$YaAHIe++_5+QGkjc6(BU(N4evoZGglCy7D7e(nSFd@#M=9#b;G|1#I8& z=8<>`uw5WEKyk&?+;9qI(}&@K__NQN1t zO(;(66B_M3PB zY8hd?u?)5#9p+c}lwocL2UZ^-l=YbkdJM%l4h6F?eS2mE`bK=JoZmNDU`#=_N;^tH zRtZX^B!RFNb!x4?Fg+DHAU@4o^L^}G&ZE|svXJsj?ajA6subyv^Yp|cNBJ^9Y6ggm zM_EOjc9_sBy{>PJ_2AZG+qt$&A^6w`P=GCY+12>~t%_R-7+|8FlCH9Q~2|t z7f~RFWrl%N-*yCKt=Lg%;JPHWo4sAe4@<-!~#!_O@;>g8G}F`7cuQ>08^ zY7!!Xq&38sh)5fa0#~W@W6c+R4YE`jhQB>pq6n@lc2wQfPtqu4j+cKwdvp%KwKE@C z1(dYht@!bwph+U@P#d937uq@GZE?=3c9fzl3y8(bKf3k}hP@C%(t7%(TbJvApFu!S z+hSzSj-ph+_j3)Z!mng!Fti}!c)TnrKzYd7K??ZeEu^S4lQgmAtg&Z;Wll7l`jp=* zzVnj+rmGuq0v=5P-wtV)iA`85KDEYPs+BZEx&3WDtTAo0k6JZ9A$VB3)xTqAEKE)uP__a<*|HVIKU0LLYrw1wc`^9M|7o>hyw1>v@qfL{#(30 zvgMTe+qN3Lv8D4(!LgAE%u#N5r!S|Qm4l6;bw3^Z;KvHjeVzq*r%TSwCDz%;V32~v zNtgq7n$wZs<`mwf)Si@8*$5Rhak%?ZAIGk6ZdniT@s^R1PgN+**j~Pj7!iVK>CnNM z>`XH^ReI{0ySa3c2Fc0nbgHt6dpZmBfUBJzVh`>J0nwx}H07BSa5})g{z;>p#lSkJ z+LuH$aipT0S-xl&waU68o7}lW0QH6aBtw06ACQv_zafDLpMe;OLYm_cRKQ&cHjCmo zpI!W&&4G2`*=A9joP)$RQ>K7^Lq7HZp9~nM!<2IO`;ZRYH^k4K^OUqpgWorDSGAXp z;*SLs#=9#(lt{^&^+ek4~Cg=#%K0o+pXJCHim0i5Sd1Kd-i;9ph)5~L$YU8DhL z^;3Je0dGn^>fF(uKSFoBY%9o}IZ56;@}4&q<&PWz6k!@_eTKSt)luFu7Ko2_;Z9GX!d}gJblcU;6&zb z%cG;oA}fB-NW0EBrK{mzJk0>^GAPP|{0ra;K>lTRY4^Bq#^DsdUF1On-QX3J{J!_GtvzClKg}bUUr%lGFJ@^Rb9QNsV3o z#U~^;Vd>aEEfSC=l=^#6CgucBs&({w4A?C|hw+8~`Bv-u4*5vz>IS3t()dneh{BH4 z%y?nAPktsw;KT(-H~@8u!rNi2FQVl?tWP#X>WbHxX? zN2-50aLZL4`@sRIpVIr4Dgxmal+8UZe+$S*K^f#<2`Wegf4C1IzLx>z#lO$>;#%UqSu%q~IqD=59e63+MqTS%3=i z0#ZKsW{_8*&!SL}O{(~@n1_ZL{Jw>|?guE(V+0vSLaXrL_b+4z@JWuZ390HuqZ=kt zWc_9`Q$ID;dOWK;DBpJ+X|qmq27TK|%asgsfOm3$W1a(gKtSTODS>?a)&W1@v7bMZ z2&eDV!y=?fp&dFrJug&NrJpQ2^OdS-Zx4$3-J2v*v-Ra@bY@mE?#deFTOuyQj3&o{ zn{ucI8nw$E8bh*G=oR?6$9w8CevdcVHUD_-3sV-lyny$B2YPNTVItz1q=o3&+4W=Cai%}z!PiG4`?Ie-|4j*0Z1h+A z@Gq2p)qwqPDt}*B%)e0iy(a8`)A{>s`u~N_uNtxcPpN>z{h!?VRWtU#sXSsB{KXo! zf1&dC8nXXQ2~JFuKda3Cn$#9R=f7&s{;AOa z_a-^Q`(Ow`u7dM{~Y=I z1|rZVtzRul>p!+^{gcG+z8tjE=vPDf__uvWQlb#RMlmojbl~3>1W=IJ1JwJ!0M9vx Ab^rhX literal 0 HcmV?d00001 diff --git a/dat/runTests.sh b/dat/runTests.sh new file mode 100644 index 0000000..25ed1ab --- /dev/null +++ b/dat/runTests.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Runs Emergen(e)tic with a series of scripts + +GEN="30" +CAN="20" + +dnc "emergenetic.dn" + +for FILE in ./scripts/*; do + FILE=${FILE##*/} + FILE=${FILE%.script} + + dana "emergenetic" $FILE $GEN $CAN + + for DIR in ./cache/*; do + (cd "$DIR" && rm *.o) + done + cd results/ && rm *.txt && cd .. + tar -jcvf ./archives/$FILE.bz2 cache + rm -R cache + cp -a ./cachebackup ./cache +done + +echo 'Complete.' >complete.txt diff --git a/dat/scripts/difffile-html.script b/dat/scripts/difffile-html.script new file mode 100644 index 0000000..5fdc7f7 --- /dev/null +++ b/dat/scripts/difffile-html.script @@ -0,0 +1,44 @@ +./htdocs/index.html +./htdocs/index_big.html +./htdocs/index_huge.html +./htdocs/index_med.html +./htdocs/index_small.html +./htdocs/index_150KB.html +./htdocs/index.html +./htdocs/index_big.html +./htdocs/index_huge.html +./htdocs/index_med.html +./htdocs/index_small.html +./htdocs/index.html +./htdocs/index_big.html +./htdocs/index_huge.html +./htdocs/index_med.html +./htdocs/index_small.html +./htdocs/index_150KB.html +./htdocs/index.html +./htdocs/index_big.html +./htdocs/index_huge.html +./htdocs/index_med.html +./htdocs/index_small.html +./htdocs/index.html +./htdocs/index_big.html +./htdocs/index_huge.html +./htdocs/index_med.html +./htdocs/index_small.html +./htdocs/index_150KB.html +./htdocs/index.html +./htdocs/index_big.html +./htdocs/index_huge.html +./htdocs/index_med.html +./htdocs/index_small.html +./htdocs/index.html +./htdocs/index_big.html +./htdocs/index_huge.html +./htdocs/index_med.html +./htdocs/index_small.html +./htdocs/index_150KB.html +./htdocs/index.html +./htdocs/index_big.html +./htdocs/index_huge.html +./htdocs/index_med.html +./htdocs/index_small.html \ No newline at end of file diff --git a/dat/scripts/difffile-images.script b/dat/scripts/difffile-images.script new file mode 100644 index 0000000..4e79cd2 --- /dev/null +++ b/dat/scripts/difffile-images.script @@ -0,0 +1,48 @@ +./htdocs/image_med.jpg +./htdocs/image_small.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_big.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_small.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_big.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_small.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_big.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_small.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_small.jpg +./htdocs/image_big.jpg +./htdocs/image_big.jpg +./htdocs/image_med.jpg \ No newline at end of file diff --git a/dat/scripts/difffile-large.script b/dat/scripts/difffile-large.script new file mode 100644 index 0000000..a8e66fc --- /dev/null +++ b/dat/scripts/difffile-large.script @@ -0,0 +1,40 @@ +./htdocs/image_big.jpg +./htdocs/index_150KB.html +./htdocs/index_big.html +./htdocs/image_big.jpg +./htdocs/index_huge.html +./htdocs/index_big.html +./htdocs/image_big.jpg +./htdocs/image_big.jpg +./htdocs/index_150KB.html +./htdocs/index_big.html +./htdocs/image_big.jpg +./htdocs/index_huge.html +./htdocs/index_big.html +./htdocs/image_big.jpg +./htdocs/image_big.jpg +./htdocs/index_150KB.html +./htdocs/index_big.html +./htdocs/image_big.jpg +./htdocs/index_big.html +./htdocs/index_big.html +./htdocs/image_big.jpg +./htdocs/index_150KB.html +./htdocs/index_big.html +./htdocs/image_big.jpg +./htdocs/index_huge.html +./htdocs/index_big.html +./htdocs/image_big.jpg +./htdocs/image_big.jpg +./htdocs/index_150KB.html +./htdocs/index_big.html +./htdocs/image_big.jpg +./htdocs/index_huge.html +./htdocs/index_big.html +./htdocs/image_big.jpg +./htdocs/image_big.jpg +./htdocs/index_150KB.html +./htdocs/index_big.html +./htdocs/image_big.jpg +./htdocs/index_big.html +./htdocs/index_big.html \ No newline at end of file diff --git a/dat/scripts/difffile-small.script b/dat/scripts/difffile-small.script new file mode 100644 index 0000000..f4449ce --- /dev/null +++ b/dat/scripts/difffile-small.script @@ -0,0 +1,40 @@ +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html +./htdocs/image_small.jpg +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html +./htdocs/image_small.jpg +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html +./htdocs/image_small.jpg +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html +./htdocs/image_small.jpg +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html +./htdocs/image_small.jpg +./htdocs/index_small.html +./htdocs/index_small.html \ No newline at end of file diff --git a/dat/scripts/difffile.script b/dat/scripts/difffile.script new file mode 100644 index 0000000..ea54679 --- /dev/null +++ b/dat/scripts/difffile.script @@ -0,0 +1,40 @@ +./htdocs/image_med.jpg +./htdocs/index_150KB.html +./htdocs/index_small.html +./htdocs/image_big.jpg +./htdocs/index.html +./htdocs/index_med.html +./htdocs/image_small.jpg +./htdocs/image_med.jpg +./htdocs/index_150KB.html +./htdocs/index_small.html +./htdocs/image_big.jpg +./htdocs/index.html +./htdocs/index_med.html +./htdocs/image_small.jpg +./htdocs/image_med.jpg +./htdocs/index_150KB.html +./htdocs/index_small.html +./htdocs/image_big.jpg +./htdocs/index.html +./htdocs/index_med.html +./htdocs/image_med.jpg +./htdocs/index_150KB.html +./htdocs/index_small.html +./htdocs/image_big.jpg +./htdocs/index.html +./htdocs/index_med.html +./htdocs/image_small.jpg +./htdocs/image_med.jpg +./htdocs/index_150KB.html +./htdocs/index_small.html +./htdocs/image_big.jpg +./htdocs/index.html +./htdocs/index_med.html +./htdocs/image_small.jpg +./htdocs/image_med.jpg +./htdocs/index_150KB.html +./htdocs/index_small.html +./htdocs/image_big.jpg +./htdocs/index.html +./htdocs/index_med.html \ No newline at end of file diff --git a/dat/scripts/samefile-html.script b/dat/scripts/samefile-html.script new file mode 100644 index 0000000..54c36df --- /dev/null +++ b/dat/scripts/samefile-html.script @@ -0,0 +1,40 @@ +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html +./htdocs/index_med.html \ No newline at end of file diff --git a/dat/scripts/samefile-images.script b/dat/scripts/samefile-images.script new file mode 100644 index 0000000..4f6d56a --- /dev/null +++ b/dat/scripts/samefile-images.script @@ -0,0 +1,40 @@ +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg +./htdocs/image_med.jpg \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..0e34078 --- /dev/null +++ b/index.html @@ -0,0 +1,68 @@ +

      SCC.300 Final Year Project

      + +

      Contact

      + +

      Ben Goldsworthy (33576556) - Email

      + +

      Introduction

      + +

      This is the landing page for my final year project: ‘EmerGen(e)tic: Exploring the use of genetic algorithms in distributed emergent systems’.

      + +

      Abstract

      + +

      “Adaptive and emergent systems exist to attempt to answer the deficiencies inherent to distributed systems, and the necessarily finite ability of any programmer to predict all possible eventualities in which his software may one day find itself. This paper argues that these systems fail to go far enough, and then proposes a further development—genetic systems—which utilises evolutionary programming to extend the versatility of a given system massively, if not infinitely. This paper proceeds to detail the EmerGen(e)tic framework for rapidly testing genetic algorithm modules within emergent systems, as well as an example module pertaining to the cache updating behaviour of a web server. This paper concludes by proposing further avenues of potentially-fruitful research based upon these programs and its findings.”

      + +

      Files

      + + \ No newline at end of file diff --git a/report/final-report.aux b/report/final-report.aux new file mode 100644 index 0000000..8617c76 --- /dev/null +++ b/report/final-report.aux @@ -0,0 +1,164 @@ +\relax +\citation{distsys} +\citation{reliable} +\citation{machinecentric} +\citation{antenna} +\citation{genprog} +\citation{ants} +\@writefile{toc}{\contentsline {section}{\numberline {1}Introduction}{4}} +\newlabel{sec:introduction}{{1}{4}} +\@writefile{loa}{\contentsline {algorithm}{\numberline {1}{\ignorespaces Basic genetic algorithm}}{5}} +\newlabel{alg1}{{1}{5}} +\citation{bugcost} +\citation{1000} +\citation{cni} +\citation{unix} +\citation{geometry} +\citation{email} +\citation{rfc} +\citation{distsys} +\@writefile{toc}{\contentsline {section}{\numberline {2}Background}{7}} +\newlabel{sec:background}{{2}{7}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Assumptions}{7}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Distributed and Adaptive Systems}{7}} +\citation{dana} +\citation{dana} +\citation{machinecentric} +\citation{machinecentric} +\citation{losingcontrol} +\citation{rex} +\citation{fusion} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Emergent Systems}{8}} +\citation{floyd} +\citation{genprog} +\citation{security} +\citation{antenna} +\citation{ants} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}`Genetic Systems'}{9}} +\@writefile{toc}{\contentsline {section}{\numberline {3}Design}{10}} +\newlabel{sec:design}{{3}{10}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}EmerGen(e)tic}{10}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}The Web Server}{10}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.1}How a web server works}{10}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.2}Added extras}{11}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.3}A tale of two web servers}{11}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Caching}{12}} +\newlabel{sec:caching}{{3.3}{12}} +\@writefile{toc}{\contentsline {subsection}{\numberline {3.4}The `Cache Policy' Genetic Algorithm}{12}} +\@writefile{toc}{\contentsline {section}{\numberline {4}Implementation: EmerGen(e)tic}{14}} +\newlabel{sec:implementation}{{4}{14}} +\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Folder Structure}{14}} +\@writefile{toc}{\contentsline {subsection}{\numberline {4.2}\lstinline |emergenetic.dn|}{14}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.2.1}\lstinline |App:main()|}{14}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.2.2}\lstinline |runGeneration()|}{14}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.2.3}\lstinline |runCandidate()|}{14}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.2.4}\lstinline |printResults()|}{14}} +\@writefile{toc}{\contentsline {section}{\numberline {5}Implementation: \lstinline |cachingpolicy|}{15}} +\newlabel{sec:cachingpolicyimpl}{{5}{15}} +\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}Folder Structure}{15}} +\@writefile{toc}{\contentsline {subsection}{\numberline {5.2}Genetic Algorithm search space}{15}} +\@writefile{toc}{\contentsline {subsection}{\numberline {5.3}\lstinline |CacheHandlerBase.dn|}{16}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.1}\lstinline |CacheHandler:getGetCachedResponse()|}{16}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.2}\lstinline |CacheHandler:updateCache()|}{16}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.3}\lstinline |CacheHandler:clearCache()|}{16}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.4}\lstinline |nthMostFrequentlyUsed()|, \lstinline |nthMostRecentlyUsed()| \& \lstinline |random()|}{16}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.5}\lstinline |resolve()|}{16}} +\@writefile{toc}{\contentsline {subsection}{\numberline {5.4}\lstinline |emergenetic.dn|}{16}} +\@writefile{toc}{\contentsline {subsection}{\numberline {5.5}\lstinline |cachingpolicy/mutator.py|}{16}} +\newlabel{sec:python}{{5.5}{16}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.1}\lstinline |getSubLists()|}{17}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.2}\lstinline |crossover()|}{17}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.3}\lstinline |mutate()|}{17}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.4}\lstinline |parse()| \& \lstinline |compile()|}{17}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.5}\lstinline |createInitialPop()|}{17}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.6}\lstinline |readChromosomeFromFile()| \& \lstinline |writeChromosomeToFile()|}{17}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.7}\lstinline |hasSubTrees()|}{17}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.8}\lstinline |main()|}{17}} +\@writefile{toc}{\contentsline {subsection}{\numberline {5.6}\lstinline |cachingpolicy/config.conf|}{17}} +\@writefile{toc}{\contentsline {section}{\numberline {6}The System in Operation}{18}} +\@writefile{toc}{\contentsline {subsection}{\numberline {6.1}Creating a Module}{18}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.1}Files}{18}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.2}Implementation}{18}} +\@writefile{toc}{\contentsline {subsection}{\numberline {6.2}Creating Scripts}{18}} +\@writefile{toc}{\contentsline {subsection}{\numberline {6.3}Running EmerGen(e)tic}{18}} +\@writefile{toc}{\contentsline {subsection}{\numberline {6.4}Background Tests}{20}} +\@writefile{toc}{\contentsline {section}{\numberline {7}Testing \& Evaluation}{21}} +\newlabel{sec:testing}{{7}{21}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.1}Testing EmerGen(e)tic}{21}} +\@writefile{lol}{\contentsline {lstlisting}{../dat/helloworld/output50.txt}{21}} +\@writefile{lol}{\contentsline {lstlisting}{../dat/helloworld/output50.txt}{21}} +\@writefile{lol}{\contentsline {lstlisting}{../dat/helloworld/output0.txt}{21}} +\@writefile{lol}{\contentsline {lstlisting}{../dat/helloworld/output0.txt}{22}} +\@writefile{lol}{\contentsline {lstlisting}{../dat/helloworld/output100.txt}{22}} +\@writefile{lol}{\contentsline {lstlisting}{../dat/helloworld/output100.txt}{22}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.2}Testing \lstinline |cachingpolicy|}{23}} +\newlabel{sec:testingcache}{{7.2}{23}} +\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces }}{23}} +\newlabel{fig:difffile-large}{{1}{23}} +\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces }}{23}} +\newlabel{fig:difffile-large-wo}{{2}{23}} +\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces }}{23}} +\newlabel{fig:samefile-images}{{3}{23}} +\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces }}{23}} +\newlabel{fig:samefile-images-wo}{{4}{23}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.3}Evaluation}{24}} +\newlabel{sec:eval}{{7.3}{24}} +\@writefile{toc}{\contentsline {section}{\numberline {8}Conclusion}{25}} +\@writefile{toc}{\contentsline {subsection}{\numberline {8.1}Future Development}{25}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {8.1.1}Completing the original goal of finding the optimal conditions for the genetic algorithm}{25}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {8.1.2}Designing more modules}{25}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {8.1.3}A more `Danatically'-designed EmerGen(e)tic}{25}} +\citation{meta} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {8.1.4}Issues within the present \lstinline |cachingpolicy| module}{26}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {8.1.5}Putting human developers further out of work (through meta-learning)}{26}} +\bibstyle{IEEEtran} +\bibdata{final-report} +\bibcite{distsys}{1} +\bibcite{reliable}{2} +\bibcite{machinecentric}{3} +\bibcite{antenna}{4} +\bibcite{genprog}{5} +\bibcite{ants}{6} +\bibcite{bugcost}{7} +\bibcite{1000}{8} +\bibcite{cni}{9} +\bibcite{unix}{10} +\bibcite{geometry}{11} +\bibcite{email}{12} +\bibcite{rfc}{13} +\bibcite{dana}{14} +\bibcite{losingcontrol}{15} +\bibcite{rex}{16} +\bibcite{fusion}{17} +\bibcite{floyd}{18} +\bibcite{security}{19} +\bibcite{meta}{20} +\@writefile{toc}{\contentsline {section}{References}{27}} +\@writefile{toc}{\contentsline {section}{Appendix\nobreakspace A: \lstinline |emergenetic.dn|}{28}} +\newlabel{appendix:emergen}{{A}{28}} +\@writefile{lol}{\contentsline {lstlisting}{../src/emergenetic/emergenetic.dn}{28}} +\@writefile{toc}{\contentsline {section}{Appendix\nobreakspace B: \lstinline |helloworld/mutator.py|}{32}} +\newlabel{appendix:helloworld}{{B}{32}} +\@writefile{lol}{\contentsline {lstlisting}{../src/helloworld/project/helloworld/mutator.py}{32}} +\@writefile{toc}{\contentsline {section}{Appendix\nobreakspace C: \lstinline |cachingpolicy|}{34}} +\@writefile{toc}{\contentsline {subsection}{\numberline {C.1}\lstinline |CacheHandlerBase.dn|}{34}} +\newlabel{appendix:base}{{C.1}{34}} +\@writefile{lol}{\contentsline {lstlisting}{../src/cachingpolicy/cachebackup/CacheHandlerBase.dn}{34}} +\@writefile{toc}{\contentsline {subsection}{\numberline {C.2}\lstinline |mutator.py|}{39}} +\newlabel{appendix:genetic}{{C.2}{39}} +\@writefile{lol}{\contentsline {lstlisting}{../src/cachingpolicy/project/cachingpolicy/mutator.py}{39}} +\@writefile{toc}{\contentsline {subsection}{\numberline {C.3}\lstinline |emergenetic.dn|'s \lstinline |runCandidates()| method}{44}} +\newlabel{appendix:runcand}{{C.3}{44}} +\@writefile{lol}{\contentsline {lstlisting}{../src/cachingpolicy/emergenetic.dn}{44}} +\@writefile{toc}{\contentsline {subsection}{\numberline {C.4}\lstinline |setup.sh|}{45}} +\newlabel{appendix:setup}{{C.4}{45}} +\@writefile{lol}{\contentsline {lstlisting}{../src/cachingpolicy/project/cachingpolicy/setup.sh}{45}} +\@writefile{toc}{\contentsline {subsection}{\numberline {C.5}\lstinline |config.conf|}{45}} +\newlabel{appendix:settings}{{C.5}{45}} +\@writefile{lol}{\contentsline {lstlisting}{../src/cachingpolicy/project/cachingpolicy/config.conf}{46}} +\@writefile{toc}{\contentsline {subsection}{\numberline {C.6}Gen. 18 chromosomes}{46}} +\newlabel{appendix:chromosomes}{{C.6}{46}} +\@writefile{lol}{\contentsline {lstlisting}{../dat/cache/difffile\textendash large/17/chromosomes.txt}{46}} +\@writefile{toc}{\contentsline {section}{Appendix\nobreakspace D: \lstinline |runTests.sh|}{47}} +\newlabel{appendix:bash}{{D}{47}} +\@writefile{lol}{\contentsline {lstlisting}{../dat/runTests.sh}{47}} diff --git a/report/final-report.bbl b/report/final-report.bbl new file mode 100644 index 0000000..2287e56 --- /dev/null +++ b/report/final-report.bbl @@ -0,0 +1,130 @@ +% Generated by IEEEtran.bst, version: 1.14 (2015/08/26) +\begin{thebibliography}{10} +\providecommand{\url}[1]{#1} +\csname url@samestyle\endcsname +\providecommand{\newblock}{\relax} +\providecommand{\bibinfo}[2]{#2} +\providecommand{\BIBentrySTDinterwordspacing}{\spaceskip=0pt\relax} +\providecommand{\BIBentryALTinterwordstretchfactor}{4} +\providecommand{\BIBentryALTinterwordspacing}{\spaceskip=\fontdimen2\font plus +\BIBentryALTinterwordstretchfactor\fontdimen3\font minus + \fontdimen4\font\relax} +\providecommand{\BIBforeignlanguage}[2]{{% +\expandafter\ifx\csname l@#1\endcsname\relax +\typeout{** WARNING: IEEEtran.bst: No hyphenation pattern has been}% +\typeout{** loaded for the language `#1'. Using the pattern for}% +\typeout{** the default language instead.}% +\else +\language=\csname l@#1\endcsname +\fi +#2}} +\providecommand{\BIBdecl}{\relax} +\BIBdecl + +\bibitem{distsys} +G.~F. Coulouris, J.~Dollimore, T.~Kindberg, and G.~Blair, \emph{Distributed + Systems: Concepts and Design}, 5th~ed.\hskip 1em plus 0.5em minus 0.4em\relax + Addison-Wesley, 2012. + +\bibitem{reliable} +\BIBentryALTinterwordspacing +E.~Redwine and J.~L. Holliday, ``Reliability of distributed systems.'' + [Online]. Available: \url{http://www.cse.scu.edu/~jholliday/REL-EAR.htm} +\BIBentrySTDinterwordspacing + +\bibitem{machinecentric} +R.~Rodrigues~Filho and B.~F. Porter, ``Experiments with a machine-centric + approach to realise distributed emergent software systems,'' 2016. + +\bibitem{antenna} +G.~Hornby, A.~Globus, D.~Linden, and J.~Lohn, ``Automated antenna design with + evolutionary algorithms,'' in \emph{Space 2006}, 2015, p. 7242. + +\bibitem{genprog} +C.~Le~Goues, M.~Dewey-Vogt, S.~Forrest, and W.~Weimer, ``A systematic study of + automated program repair: Fixing 55 out of 105 bugs for \$8 each,'' in + \emph{Software Engineering (ICSE), 2012 34th International Conference + on}.\hskip 1em plus 0.5em minus 0.4em\relax IEEE, 2012, pp. 3--13. + +\bibitem{ants} +B.~Goldsworthy, ```thanks, ants. thants.': Applying genetic algorithms to + simulated ants to produce higher-fitness generations,'' unpublished. + +\bibitem{bugcost} +M.~Dawson, D.~N. Burrell, E.~Rahim, and S.~Brewster, ``Integrating software + assurance into the software development life cycle (sdlc),'' \emph{Journal of + Information Systems Technology and Planning}, vol.~3, no.~6, 2010. + +\bibitem{1000} +S.~McConnell, \emph{Code complete}.\hskip 1em plus 0.5em minus 0.4em\relax + Pearson Education, 2004. + +\bibitem{cni} +B.~Goldsworthy, ``Critical infrastructures protection: the responsibility of + government or of companies?'' unpublished. + +\bibitem{unix} +E.~S. Raymond, \emph{The art of Unix programming}.\hskip 1em plus 0.5em minus + 0.4em\relax Addison-Wesley Professional, 2003. + +\bibitem{geometry} +D.~Muder, \emph{The Unreasonable Influence of Geometry}, 2000. + +\bibitem{email} +\BIBentryALTinterwordspacing +L.~Lamport, ``Distribution,'' May 1987. [Online]. Available: + \url{https://www.microsoft.com/en-us/research/publication/distribution/} +\BIBentrySTDinterwordspacing + +\bibitem{rfc} +\BIBentryALTinterwordspacing +S.~Crocker, ``New host-host protocol,'' Internet Requests for Comments, RFC + Editor, RFC~33, February 1970, \url{http://www.rfc-editor.org/rfc/rfc33.txt}. + [Online]. Available: \url{http://www.rfc-editor.org/rfc/rfc33.txt} +\BIBentrySTDinterwordspacing + +\bibitem{dana} +B.~F. Porter, ``Runtime modularity in complex structures: A component model for + fine grained runtime adaptation,'' in \emph{Proceedings of the 17th + international ACM Sigsoft symposium on Component-based software + engineering}.\hskip 1em plus 0.5em minus 0.4em\relax ACM, 2014, pp. 29--34. + +\bibitem{losingcontrol} +B.~F. Porter and R.~Rodrigues~Filho, ``Losing control: The case for emergent + software systems using autonomous assembly, perception, and learning,'' in + \emph{Self-Adaptive and Self-Organizing Systems (SASO), 2016 IEEE 10th + International Conference on}.\hskip 1em plus 0.5em minus 0.4em\relax IEEE, + 2016, pp. 40--49. + +\bibitem{rex} +B.~Porter, M.~Grieves, R.~Rodrigues~Filho, and D.~Leslie, ``Re$^{\text{x}}$: A + development platform and online learning approach for runtime emergent + software systems,'' in \emph{Proceedings of the 12th USENIX Symposium on + Operating Systems Design and Implementation. USENIX}, 2016. + +\bibitem{fusion} +\BIBentryALTinterwordspacing +A.~Elkhodary, N.~Esfahani, and S.~Malek, ``Fusion: A framework for engineering + self-tuning self-adaptive software systems,'' in \emph{Proceedings of the + Eighteenth ACM SIGSOFT International Symposium on Foundations of Software + Engineering}, ser. FSE '10.\hskip 1em plus 0.5em minus 0.4em\relax New York, + NY, USA: ACM, 2010, pp. 7--16. [Online]. Available: + \url{http://doi.acm.org/10.1145/1882291.1882296} +\BIBentrySTDinterwordspacing + +\bibitem{floyd} +R.~W. Floyd, ``The paradigms of programming,'' \emph{Communications of the + ACM}, vol.~22, no.~8, pp. 455--460, 1979. + +\bibitem{security} +J.~V. Hansen, P.~B. Lowry, R.~D. Meservy, and D.~M. McDonald, ``Genetic + programming for prevention of cyberterrorism through dynamic and evolving + intrusion detection,'' \emph{Decision Support Systems}, vol.~43, no.~4, pp. + 1362--1374, 2007. + +\bibitem{meta} +J.~Schmidhuber, ``Evolutionary principles in self-referential learning,'' + \emph{On learning how to learn: The meta-meta-... hook.) Diploma thesis, + Institut f. Informatik, Tech. Univ. Munich}, 1987. + +\end{thebibliography} diff --git a/report/final-report.bib b/report/final-report.bib new file mode 100644 index 0000000..a43baf5 --- /dev/null +++ b/report/final-report.bib @@ -0,0 +1,193 @@ +@IEEEtranBSTCTL{IEEEexample:BSTcontrol, +CTLdash_repeated_names = "no", +} + +@incollection{antenna, + title={Automated antenna design with evolutionary algorithms}, + author={Hornby, Gregory and Globus, Al and Linden, Derek and Lohn, Jason}, + booktitle={Space 2006}, + pages={7242}, + year={2015} +} + +@inproceedings{genprog, + title={A systematic study of automated program repair: Fixing 55 out of 105 bugs for \$8 each}, + author={Le Goues, Claire and Dewey-Vogt, Michael and Forrest, Stephanie and Weimer, Westley}, + booktitle={Software Engineering (ICSE), 2012 34th International Conference on}, + pages={3--13}, + year={2012}, + organization={IEEE} +} + +@article{ants, + title={`Thanks, ants. Thants.': Applying genetic algorithms to simulated ants to produce higher-fitness generations}, + author={Ben Goldsworthy}, + year={unpublished} +} + +@inproceedings{dana, + title={Runtime modularity in complex structures: A component model for fine grained runtime adaptation}, + author={Porter, Barry Francis}, + booktitle={Proceedings of the 17th international ACM Sigsoft symposium on Component-based software engineering}, + pages={29--34}, + year={2014}, + organization={ACM} +} + +@article{machinecentric, + title={Experiments with a machine-centric approach to realise distributed emergent software systems}, + author={Rodrigues Filho, Roberto and Porter, Barry Francis}, + year={2016}, + publisher={ACM} +} + +@article{meta, + title={Evolutionary principles in self-referential learning}, + author={Schmidhuber, Jurgen}, + journal={On learning how to learn: The meta-meta-... hook.) Diploma thesis, Institut f. Informatik, Tech. Univ. Munich}, + year={1987} +} + +@book{distsys, + author={Coulouris, George F and Dollimore, Jean and Kindberg, Tim and Blair, Gordon}, + title={Distributed Systems: Concepts and Design}, + place={Boston, Mass.}, + edition={5}, + publisher={Addison-Wesley}, + year={2012} +} + +@misc{reliable, + author={Redwine, Erick and Holliday, JoAnne L}, + title={Reliability of Distributed Systems}, + url={http://www.cse.scu.edu/~jholliday/REL-EAR.htm}, + urldate={2017-3-2}, + journal={Cse.scu.edu} +} + +@inproceedings{losingcontrol, + title={Losing Control: The Case for Emergent Software Systems Using Autonomous Assembly, Perception, and Learning}, + author={Porter, Barry Francis and Rodrigues Filho, Roberto}, + booktitle={Self-Adaptive and Self-Organizing Systems (SASO), 2016 IEEE 10th International Conference on}, + pages={40--49}, + year={2016}, + organization={IEEE} +} + +@inproceedings{rex, + title={RE$^{\text{X}}$: A development platform and online learning approach for runtime emergent software systems}, + author={Porter, Barry and Grieves, Matthew and Rodrigues Filho, Roberto and Leslie, David}, + booktitle={Proceedings of the 12th USENIX Symposium on Operating Systems Design and Implementation. USENIX}, + year={2016} +} + +@inproceedings{fusion, + author = {Elkhodary, Ahmed and Esfahani, Naeem and Malek, Sam}, + title = {FUSION: A Framework for Engineering Self-tuning Self-adaptive Software Systems}, + booktitle = {Proceedings of the Eighteenth ACM SIGSOFT International Symposium on Foundations of Software Engineering}, + series = {FSE '10}, + year = {2010}, + isbn = {978-1-60558-791-2}, + location = {Santa Fe, New Mexico, USA}, + pages = {7--16}, + numpages = {10}, + url = {http://doi.acm.org/10.1145/1882291.1882296}, + doi = {10.1145/1882291.1882296}, + acmid = {1882296}, + publisher = {ACM}, + address = {New York, NY, USA}, + keywords = {feature-orientation, learning, qos analysis, self-adaptation}, +} + +@article{bugcost, + title={Integrating Software Assurance into the Software Development Life Cycle (SDLC)}, + author={Dawson, Maurice and Burrell, Darrell N and Rahim, Emad and Brewster, Stephen}, + journal={Journal of Information Systems Technology and Planning}, + volume={3}, + number={6}, + year={2010} +} + +@book{1000, + title={Code complete}, + author={McConnell, Steve}, + year={2004}, + publisher={Pearson Education} +} + +@book{geometry, + title={The Unreasonable Influence of Geometry}, + author={Muder, Doug}, + year={2000} +} + +@techreport{RFC, + author = {S.D. Crocker}, + title = {New Host-Host Protocol}, + howpublished = {Internet Requests for Comments}, + type = {RFC}, + number = {33}, + year = {1970}, + month = {February}, + issn = {2070-1721}, + publisher = {RFC Editor}, + institution = {RFC Editor}, + url = {http://www.rfc-editor.org/rfc/rfc33.txt}, + note = {\url{http://www.rfc-editor.org/rfc/rfc33.txt}}, +} + +@other{email, +author = {Lamport, Leslie}, +title = {Distribution}, +booktitle = {}, +year = {1987}, +month = {May}, +abstract = {This message is the source of the following observation, which has been quoted (and misquoted) rather widely: + +A distributed system is one in which the failure of a computer you didn't even know existed can render your own computer unusable. +}, +publisher = {}, +url = {https://www.microsoft.com/en-us/research/publication/distribution/}, +address = {}, +pages = {}, +journal = {}, +volume = {}, +chapter = {}, +isbn = {}, +} + +@article{floyd, + title={The paradigms of programming}, + author={Floyd, Robert W}, + journal={Communications of the ACM}, + volume={22}, + number={8}, + pages={455--460}, + year={1979}, + publisher={ACM} +} + +@article{cni, + title={Critical infrastructures protection: the responsibility of Government or of companies?}, + author={Goldsworthy, Ben}, + year={unpublished} +} + +@book{unix, + title={The art of Unix programming}, + author={Raymond, Eric S}, + year={2003}, + publisher={Addison-Wesley Professional} +} + +@article{security, + title={Genetic programming for prevention of cyberterrorism through dynamic and evolving intrusion detection}, + author={Hansen, James V and Lowry, Paul Benjamin and Meservy, Rayman D and McDonald, Daniel M}, + journal={Decision Support Systems}, + volume={43}, + number={4}, + pages={1362--1374}, + year={2007}, + publisher={Elsevier} +} + diff --git a/report/final-report.blg b/report/final-report.blg new file mode 100644 index 0000000..fc2a560 --- /dev/null +++ b/report/final-report.blg @@ -0,0 +1,15 @@ +This is BibTeX, Version 0.99dThe top-level auxiliary file: final-report.aux +The style file: IEEEtran.bst +Database file #1: final-report.bib +Warning--entry type for "email" isn't style-file defined +--line 139 of file final-report.bib +-- IEEEtran.bst version 1.14 (2015/08/26) by Michael Shell. +-- http://www.michaelshell.org/tex/ieeetran/bibtex/ +-- See the "IEEEtran_bst_HOWTO.pdf" manual for usage information. +Warning--empty journal in machinecentric +Warning--empty journal in ants +Warning--empty journal in cni +Warning--missing publisher in geometry + +Done. +(There were 5 warnings) diff --git a/report/final-report.log b/report/final-report.log new file mode 100644 index 0000000..a8c5c69 --- /dev/null +++ b/report/final-report.log @@ -0,0 +1,1203 @@ +This is pdfTeX, Version 3.1415926-2.5-1.40.14 (MiKTeX 2.9) (preloaded format=pdflatex 2014.8.24) 22 MAR 2017 11:21 +entering extended mode +**Z:/scc300/report/final-report.tex +(Z:/scc300/report/final-report.tex +LaTeX2e <2011/06/27> +Babel and hyphenation patterns for english, afrikaans, ancientgreek, ar +abic, armenian, assamese, basque, bengali, bokmal, bulgarian, catalan, coptic, +croatian, czech, danish, dutch, esperanto, estonian, farsi, finnish, french, ga +lician, german, german-x-2013-05-26, greek, gujarati, hindi, hungarian, iceland +ic, indonesian, interlingua, irish, italian, kannada, kurmanji, latin, latvian, + lithuanian, malayalam, marathi, mongolian, mongolianlmc, monogreek, ngerman, n +german-x-2013-05-26, nynorsk, oriya, panjabi, pinyin, polish, portuguese, roman +ian, russian, sanskrit, serbian, slovak, slovenian, spanish, swedish, swissgerm +an, tamil, telugu, turkish, turkmen, ukenglish, ukrainian, uppersorbian, usengl +ishmax, welsh, loaded. +("C:\Program Files (x86)\MiKTeX\tex\latex\ieeetran\IEEEtran.cls" +Document Class: IEEEtran 2015/08/26 V1.8b by Michael Shell +-- See the "IEEEtran_HOWTO" manual for usage information. +-- http://www.michaelshell.org/tex/ieeetran/ +\@IEEEtrantmpdimenA=\dimen102 +\@IEEEtrantmpdimenB=\dimen103 +\@IEEEtrantmpdimenC=\dimen104 +\@IEEEtrantmpcountA=\count79 +\@IEEEtrantmpcountB=\count80 +\@IEEEtrantmpcountC=\count81 +\@IEEEtrantmptoksA=\toks14 +LaTeX Font Info: Try loading font information for OT1+ppl on input line 503. + +("C:\Program Files (x86)\MiKTeX\tex\latex\psnfss\ot1ppl.fd" +File: ot1ppl.fd 2001/06/04 font definitions for OT1/ppl. +) +-- Using IEEE Computer Society mode. +-- Using 210mm x 297mm (a4) paper. +-- Using PDF output. +\@IEEEnormalsizeunitybaselineskip=\dimen105 +-- This is a 12 point document. +\CLASSINFOnormalsizebaselineskip=\dimen106 +\CLASSINFOnormalsizeunitybaselineskip=\dimen107 +\IEEEnormaljot=\dimen108 +LaTeX Font Info: Font shape `OT1/ppl/bx/n' in size <6.02249> not available +(Font) Font shape `OT1/ppl/b/n' tried instead on input line 1090. +LaTeX Font Info: Font shape `OT1/ppl/bx/it' in size <6.02249> not available +(Font) Font shape `OT1/ppl/b/it' tried instead on input line 1090. + +LaTeX Font Info: Font shape `OT1/ppl/bx/n' in size <8.03> not available +(Font) Font shape `OT1/ppl/b/n' tried instead on input line 1090. +LaTeX Font Info: Font shape `OT1/ppl/bx/it' in size <8.03> not available +(Font) Font shape `OT1/ppl/b/it' tried instead on input line 1090. + +LaTeX Font Info: Font shape `OT1/ppl/bx/n' in size <9.03374> not available +(Font) Font shape `OT1/ppl/b/n' tried instead on input line 1090. +LaTeX Font Info: Font shape `OT1/ppl/bx/it' in size <9.03374> not available +(Font) Font shape `OT1/ppl/b/it' tried instead on input line 1090. + +LaTeX Font Info: Font shape `OT1/ppl/bx/n' in size <10.03749> not available +(Font) Font shape `OT1/ppl/b/n' tried instead on input line 1090. +LaTeX Font Info: Font shape `OT1/ppl/bx/it' in size <10.03749> not available + +(Font) Font shape `OT1/ppl/b/it' tried instead on input line 1090. + +LaTeX Font Info: Font shape `OT1/ppl/bx/n' in size <12.045> not available +(Font) Font shape `OT1/ppl/b/n' tried instead on input line 1090. +LaTeX Font Info: Font shape `OT1/ppl/bx/it' in size <12.045> not available +(Font) Font shape `OT1/ppl/b/it' tried instead on input line 1090. + +LaTeX Font Info: Font shape `OT1/ppl/bx/n' in size <14.05249> not available +(Font) Font shape `OT1/ppl/b/n' tried instead on input line 1090. +LaTeX Font Info: Font shape `OT1/ppl/bx/it' in size <14.05249> not available + +(Font) Font shape `OT1/ppl/b/it' tried instead on input line 1090. + +LaTeX Font Info: Font shape `OT1/ppl/bx/n' in size <20.075> not available +(Font) Font shape `OT1/ppl/b/n' tried instead on input line 1090. +LaTeX Font Info: Font shape `OT1/ppl/bx/it' in size <20.075> not available +(Font) Font shape `OT1/ppl/b/it' tried instead on input line 1090. + +LaTeX Font Info: Font shape `OT1/ppl/bx/n' in size <22.08249> not available +(Font) Font shape `OT1/ppl/b/n' tried instead on input line 1090. +LaTeX Font Info: Font shape `OT1/ppl/bx/it' in size <22.08249> not available + +(Font) Font shape `OT1/ppl/b/it' tried instead on input line 1090. + +LaTeX Font Info: Font shape `OT1/ppl/bx/n' in size <24.09> not available +(Font) Font shape `OT1/ppl/b/n' tried instead on input line 1090. +LaTeX Font Info: Font shape `OT1/ppl/bx/it' in size <24.09> not available +(Font) Font shape `OT1/ppl/b/it' tried instead on input line 1090. + +\IEEEquantizedlength=\dimen109 +\IEEEquantizedlengthdiff=\dimen110 +\IEEEquantizedtextheightdiff=\dimen111 +\IEEEilabelindentA=\dimen112 +\IEEEilabelindentB=\dimen113 +\IEEEilabelindent=\dimen114 +\IEEEelabelindent=\dimen115 +\IEEEdlabelindent=\dimen116 +\IEEElabelindent=\dimen117 +\IEEEiednormlabelsep=\dimen118 +\IEEEiedmathlabelsep=\dimen119 +\IEEEiedtopsep=\skip41 +\c@section=\count82 +\c@subsection=\count83 +\c@subsubsection=\count84 +\c@paragraph=\count85 +\c@IEEEsubequation=\count86 +\abovecaptionskip=\skip42 +\belowcaptionskip=\skip43 +\c@figure=\count87 +\c@table=\count88 +\@IEEEeqnnumcols=\count89 +\@IEEEeqncolcnt=\count90 +\@IEEEsubeqnnumrollback=\count91 +\@IEEEquantizeheightA=\dimen120 +\@IEEEquantizeheightB=\dimen121 +\@IEEEquantizeheightC=\dimen122 +\@IEEEquantizeprevdepth=\dimen123 +\@IEEEquantizemultiple=\count92 +\@IEEEquantizeboxA=\box26 +\@IEEEtmpitemindent=\dimen124 +\IEEEPARstartletwidth=\dimen125 +\c@IEEEbiography=\count93 +\@IEEEtranrubishbin=\box27 +) ("C:\Program Files (x86)\MiKTeX\tex\latex\blindtext\blindtext.sty" +Package: blindtext 2012/01/06 V2.0 blindtext-Package + +("C:\Program Files (x86)\MiKTeX\tex\latex\tools\xspace.sty" +Package: xspace 2009/10/20 v1.13 Space after command names (DPC,MH) +) +\c@blindtext=\count94 +\c@Blindtext=\count95 +\c@blind@countparstart=\count96 +\blind@countxx=\count97 +\blindtext@numBlindtext=\count98 +\blind@countyy=\count99 +\c@blindlist=\count100 +\c@blindlistlevel=\count101 +\c@blindlist@level=\count102 +\blind@listitem=\count103 +\c@blind@listcount=\count104 +\c@blind@levelcount=\count105 +\blind@mathformula=\count106 +\blind@Mathformula=\count107 +\c@blind@randomcount=\count108 +\c@blind@randommax=\count109 +\c@blind@pangramcount=\count110 +\c@blind@pangrammax=\count111 +) +("C:\Program Files (x86)\MiKTeX\tex\latex\graphics\color.sty" +Package: color 2005/11/14 v1.0j Standard LaTeX Color (DPC) + +("C:\Program Files (x86)\MiKTeX\tex\latex\00miktex\color.cfg" +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package color Info: Driver file: pdftex.def on input line 130. + +("C:\Program Files (x86)\MiKTeX\tex\latex\pdftex-def\pdftex.def" +File: pdftex.def 2011/05/27 v0.06d Graphics/color for pdfTeX + +("C:\Program Files (x86)\MiKTeX\tex\generic\oberdiek\infwarerr.sty" +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) +("C:\Program Files (x86)\MiKTeX\tex\generic\oberdiek\ltxcmds.sty" +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +) +\Gread@gobject=\count112 +)) +("C:\Program Files (x86)\MiKTeX\tex\latex\geometry\geometry.sty" +Package: geometry 2010/09/12 v5.6 Page Geometry + +("C:\Program Files (x86)\MiKTeX\tex\latex\graphics\keyval.sty" +Package: keyval 1999/03/16 v1.13 key=value parser (DPC) +\KV@toks@=\toks15 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\oberdiek\ifpdf.sty" +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is detected. +) +("C:\Program Files (x86)\MiKTeX\tex\generic\oberdiek\ifvtex.sty" +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +) +("C:\Program Files (x86)\MiKTeX\tex\generic\ifxetex\ifxetex.sty" +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) +\Gm@cnth=\count113 +\Gm@cntv=\count114 +\c@Gm@tempcnt=\count115 +\Gm@bindingoffset=\dimen126 +\Gm@wd@mp=\dimen127 +\Gm@odd@mp=\dimen128 +\Gm@even@mp=\dimen129 +\Gm@layoutwidth=\dimen130 +\Gm@layoutheight=\dimen131 +\Gm@layouthoffset=\dimen132 +\Gm@layoutvoffset=\dimen133 +\Gm@dimlist=\toks16 + +("C:\Program Files (x86)\MiKTeX\tex\latex\geometry\geometry.cfg")) +("C:\Program Files (x86)\MiKTeX\tex\latex\graphics\graphicx.sty" +Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR) + +("C:\Program Files (x86)\MiKTeX\tex\latex\graphics\graphics.sty" +Package: graphics 2009/02/05 v1.0o Standard LaTeX Graphics (DPC,SPQR) + +("C:\Program Files (x86)\MiKTeX\tex\latex\graphics\trig.sty" +Package: trig 1999/03/16 v1.09 sin cos tan (DPC) +) +("C:\Program Files (x86)\MiKTeX\tex\latex\00miktex\graphics.cfg" +File: graphics.cfg 2007/01/18 v1.5 graphics configuration of teTeX/TeXLive +) +Package graphics Info: Driver file: pdftex.def on input line 91. +) +\Gin@req@height=\dimen134 +\Gin@req@width=\dimen135 +) +("C:\Program Files (x86)\MiKTeX\tex\latex\listings\listings.sty" +\lst@mode=\count116 +\lst@gtempboxa=\box28 +\lst@token=\toks17 +\lst@length=\count117 +\lst@currlwidth=\dimen136 +\lst@column=\count118 +\lst@pos=\count119 +\lst@lostspace=\dimen137 +\lst@width=\dimen138 +\lst@newlines=\count120 +\lst@lineno=\count121 +\lst@maxwidth=\dimen139 + +("C:\Program Files (x86)\MiKTeX\tex\latex\listings\lstmisc.sty" +File: lstmisc.sty 2014/09/06 1.5e (Carsten Heinz) +\c@lstnumber=\count122 +\lst@skipnumbers=\count123 +\lst@framebox=\box29 +) +("C:\Program Files (x86)\MiKTeX\tex\latex\listings\listings.cfg" +File: listings.cfg 2014/09/06 1.5e listings configuration +)) +Package: listings 2014/09/06 1.5e (Carsten Heinz) + +("C:\Program Files (x86)\MiKTeX\tex\latex\pgf\frontendlayer\tikz.sty" +("C:\Program Files (x86)\MiKTeX\tex\latex\pgf\basiclayer\pgf.sty" +("C:\Program Files (x86)\MiKTeX\tex\latex\pgf\utilities\pgfrcs.sty" +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\utilities\pgfutil-common.tex" +\pgfutil@everybye=\toks18 +\pgfutil@tempdima=\dimen140 +\pgfutil@tempdimb=\dimen141 + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\utilities\pgfutil-common-lists. +tex")) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\utilities\pgfutil-latex.def" +\pgfutil@abb=\box30 + +("C:\Program Files (x86)\MiKTeX\tex\latex\ms\everyshi.sty" +Package: everyshi 2001/05/15 v3.00 EveryShipout Package (MS) +)) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\utilities\pgfrcs.code.tex" +Package: pgfrcs 2013/12/20 v3.0.0 (rcs-revision 1.28) +)) +Package: pgf 2013/12/18 v3.0.0 (rcs-revision 1.14) + +("C:\Program Files (x86)\MiKTeX\tex\latex\pgf\basiclayer\pgfcore.sty" +("C:\Program Files (x86)\MiKTeX\tex\latex\pgf\systemlayer\pgfsys.sty" +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\systemlayer\pgfsys.code.tex" +Package: pgfsys 2013/11/30 v3.0.0 (rcs-revision 1.47) + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\utilities\pgfkeys.code.tex" +\pgfkeys@pathtoks=\toks19 +\pgfkeys@temptoks=\toks20 + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\utilities\pgfkeysfiltered.code. +tex" +\pgfkeys@tmptoks=\toks21 +)) +\pgf@x=\dimen142 +\pgf@y=\dimen143 +\pgf@xa=\dimen144 +\pgf@ya=\dimen145 +\pgf@xb=\dimen146 +\pgf@yb=\dimen147 +\pgf@xc=\dimen148 +\pgf@yc=\dimen149 +\w@pgf@writea=\write3 +\r@pgf@reada=\read1 +\c@pgf@counta=\count124 +\c@pgf@countb=\count125 +\c@pgf@countc=\count126 +\c@pgf@countd=\count127 +\t@pgf@toka=\toks22 +\t@pgf@tokb=\toks23 +\t@pgf@tokc=\toks24 + ("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\systemlayer\pgf.cfg" +File: pgf.cfg 2008/05/14 (rcs-revision 1.7) +) +Driver file for pgf: pgfsys-pdftex.def + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\systemlayer\pgfsys-pdftex.def" +File: pgfsys-pdftex.def 2013/07/18 (rcs-revision 1.33) + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\systemlayer\pgfsys-common-pdf.d +ef" +File: pgfsys-common-pdf.def 2013/10/10 (rcs-revision 1.13) +))) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\systemlayer\pgfsyssoftpath.code +.tex" +File: pgfsyssoftpath.code.tex 2013/09/09 (rcs-revision 1.9) +\pgfsyssoftpath@smallbuffer@items=\count128 +\pgfsyssoftpath@bigbuffer@items=\count129 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\systemlayer\pgfsysprotocol.code +.tex" +File: pgfsysprotocol.code.tex 2006/10/16 (rcs-revision 1.4) +)) ("C:\Program Files (x86)\MiKTeX\tex\latex\xcolor\xcolor.sty" +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) + +("C:\Program Files (x86)\MiKTeX\tex\latex\00miktex\color.cfg" +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: pdftex.def on input line 225. +LaTeX Info: Redefining \color on input line 702. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `hsb' substituted by `rgb' on input line 1341. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcore.code.tex" +Package: pgfcore 2010/04/11 v3.0.0 (rcs-revision 1.7) + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmath.code.tex" +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathcalc.code.tex" +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathutil.code.tex") +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathparser.code.tex" +\pgfmath@dimen=\dimen150 +\pgfmath@count=\count130 +\pgfmath@box=\box31 +\pgfmath@toks=\toks25 +\pgfmath@stack@operand=\toks26 +\pgfmath@stack@operation=\toks27 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathfunctions.code.tex" + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathfunctions.basic.cod +e.tex") +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathfunctions.trigonome +tric.code.tex") +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathfunctions.random.co +de.tex") +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathfunctions.compariso +n.code.tex") +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathfunctions.base.code +.tex") +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathfunctions.round.cod +e.tex") +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathfunctions.misc.code +.tex") +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathfunctions.integerar +ithmetics.code.tex"))) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmathfloat.code.tex" +\c@pgfmathroundto@lastzeros=\count131 +)) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcorepoints.code.t +ex" +File: pgfcorepoints.code.tex 2013/10/07 (rcs-revision 1.27) +\pgf@picminx=\dimen151 +\pgf@picmaxx=\dimen152 +\pgf@picminy=\dimen153 +\pgf@picmaxy=\dimen154 +\pgf@pathminx=\dimen155 +\pgf@pathmaxx=\dimen156 +\pgf@pathminy=\dimen157 +\pgf@pathmaxy=\dimen158 +\pgf@xx=\dimen159 +\pgf@xy=\dimen160 +\pgf@yx=\dimen161 +\pgf@yy=\dimen162 +\pgf@zx=\dimen163 +\pgf@zy=\dimen164 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcorepathconstruct +.code.tex" +File: pgfcorepathconstruct.code.tex 2013/10/07 (rcs-revision 1.29) +\pgf@path@lastx=\dimen165 +\pgf@path@lasty=\dimen166 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcorepathusage.cod +e.tex" +File: pgfcorepathusage.code.tex 2013/12/13 (rcs-revision 1.23) +\pgf@shorten@end@additional=\dimen167 +\pgf@shorten@start@additional=\dimen168 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcorescopes.code.t +ex" +File: pgfcorescopes.code.tex 2013/10/09 (rcs-revision 1.44) +\pgfpic=\box32 +\pgf@hbox=\box33 +\pgf@layerbox@main=\box34 +\pgf@picture@serial@count=\count132 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcoregraphicstate. +code.tex" +File: pgfcoregraphicstate.code.tex 2013/09/19 (rcs-revision 1.11) +\pgflinewidth=\dimen169 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcoretransformatio +ns.code.tex" +File: pgfcoretransformations.code.tex 2013/10/10 (rcs-revision 1.17) +\pgf@pt@x=\dimen170 +\pgf@pt@y=\dimen171 +\pgf@pt@temp=\dimen172 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcorequick.code.te +x" +File: pgfcorequick.code.tex 2008/10/09 (rcs-revision 1.3) +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcoreobjects.code. +tex" +File: pgfcoreobjects.code.tex 2006/10/11 (rcs-revision 1.2) +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcorepathprocessin +g.code.tex" +File: pgfcorepathprocessing.code.tex 2013/09/09 (rcs-revision 1.9) +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcorearrows.code.t +ex" +File: pgfcorearrows.code.tex 2013/11/07 (rcs-revision 1.40) +\pgfarrowsep=\dimen173 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcoreshade.code.te +x" +File: pgfcoreshade.code.tex 2013/07/15 (rcs-revision 1.15) +\pgf@max=\dimen174 +\pgf@sys@shading@range@num=\count133 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcoreimage.code.te +x" +File: pgfcoreimage.code.tex 2013/07/15 (rcs-revision 1.18) + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcoreexternal.code +.tex" +File: pgfcoreexternal.code.tex 2013/07/15 (rcs-revision 1.20) +\pgfexternal@startupbox=\box35 +)) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcorelayers.code.t +ex" +File: pgfcorelayers.code.tex 2013/07/18 (rcs-revision 1.7) +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcoretransparency. +code.tex" +File: pgfcoretransparency.code.tex 2013/09/30 (rcs-revision 1.5) +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\basiclayer\pgfcorepatterns.code +.tex" +File: pgfcorepatterns.code.tex 2013/11/07 (rcs-revision 1.5) +))) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\modules\pgfmoduleshapes.code.te +x" +File: pgfmoduleshapes.code.tex 2013/10/31 (rcs-revision 1.34) +\pgfnodeparttextbox=\box36 +) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\modules\pgfmoduleplot.code.tex" +File: pgfmoduleplot.code.tex 2013/07/31 (rcs-revision 1.12) +) +("C:\Program Files (x86)\MiKTeX\tex\latex\pgf\compatibility\pgfcomp-version-0-6 +5.sty" +Package: pgfcomp-version-0-65 2007/07/03 v3.0.0 (rcs-revision 1.7) +\pgf@nodesepstart=\dimen175 +\pgf@nodesepend=\dimen176 +) +("C:\Program Files (x86)\MiKTeX\tex\latex\pgf\compatibility\pgfcomp-version-1-1 +8.sty" +Package: pgfcomp-version-1-18 2007/07/23 v3.0.0 (rcs-revision 1.1) +)) ("C:\Program Files (x86)\MiKTeX\tex\latex\pgf\utilities\pgffor.sty" +("C:\Program Files (x86)\MiKTeX\tex\latex\pgf\utilities\pgfkeys.sty" +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\utilities\pgfkeys.code.tex")) +("C:\Program Files (x86)\MiKTeX\tex\latex\pgf\math\pgfmath.sty" +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmath.code.tex")) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\utilities\pgffor.code.tex" +Package: pgffor 2013/12/13 v3.0.0 (rcs-revision 1.25) + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\math\pgfmath.code.tex") +\pgffor@iter=\dimen177 +\pgffor@skip=\dimen178 +\pgffor@stack=\toks28 +\pgffor@toks=\toks29 +)) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\frontendlayer\tikz\tikz.code.te +x" +Package: tikz 2013/12/13 v3.0.0 (rcs-revision 1.142) + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\libraries\pgflibraryplothandler +s.code.tex" +File: pgflibraryplothandlers.code.tex 2013/08/31 v3.0.0 (rcs-revision 1.20) +\pgf@plot@mark@count=\count134 +\pgfplotmarksize=\dimen179 +) +\tikz@lastx=\dimen180 +\tikz@lasty=\dimen181 +\tikz@lastxsaved=\dimen182 +\tikz@lastysaved=\dimen183 +\tikzleveldistance=\dimen184 +\tikzsiblingdistance=\dimen185 +\tikz@figbox=\box37 +\tikz@figbox@bg=\box38 +\tikz@tempbox=\box39 +\tikz@tempbox@bg=\box40 +\tikztreelevel=\count135 +\tikznumberofchildren=\count136 +\tikznumberofcurrentchild=\count137 +\tikz@fig@count=\count138 + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\modules\pgfmodulematrix.code.te +x" +File: pgfmodulematrix.code.tex 2013/09/17 (rcs-revision 1.8) +\pgfmatrixcurrentrow=\count139 +\pgfmatrixcurrentcolumn=\count140 +\pgf@matrix@numberofcolumns=\count141 +) +\tikz@expandcount=\count142 + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\frontendlayer\tikz\libraries\ti +kzlibrarytopaths.code.tex" +File: tikzlibrarytopaths.code.tex 2008/06/17 v3.0.0 (rcs-revision 1.2) +))) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\frontendlayer\tikz\libraries\ti +kzlibraryshapes.code.tex" +File: tikzlibraryshapes.code.tex 2008/01/09 v3.0.0 (rcs-revision 1.1) + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\frontendlayer\tikz\libraries\ti +kzlibraryshapes.geometric.code.tex" +File: tikzlibraryshapes.geometric.code.tex 2008/01/09 v3.0.0 (rcs-revision 1.1) + + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\libraries\shapes\pgflibraryshap +es.geometric.code.tex" +File: pgflibraryshapes.geometric.code.tex 2008/06/26 v3.0.0 (rcs-revision 1.1) +)) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\frontendlayer\tikz\libraries\ti +kzlibraryshapes.misc.code.tex" +File: tikzlibraryshapes.misc.code.tex 2008/01/09 v3.0.0 (rcs-revision 1.1) + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\libraries\shapes\pgflibraryshap +es.misc.code.tex" +File: pgflibraryshapes.misc.code.tex 2013/07/18 v3.0.0 (rcs-revision 1.5) +)) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\frontendlayer\tikz\libraries\ti +kzlibraryshapes.symbols.code.tex" +File: tikzlibraryshapes.symbols.code.tex 2008/01/09 v3.0.0 (rcs-revision 1.1) + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\libraries\shapes\pgflibraryshap +es.symbols.code.tex" +File: pgflibraryshapes.symbols.code.tex 2013/09/11 v3.0.0 (rcs-revision 1.6) +)) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\frontendlayer\tikz\libraries\ti +kzlibraryshapes.arrows.code.tex" +File: tikzlibraryshapes.arrows.code.tex 2008/01/09 v3.0.0 (rcs-revision 1.1) + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\libraries\shapes\pgflibraryshap +es.arrows.code.tex" +File: pgflibraryshapes.arrows.code.tex 2008/06/26 v3.0.0 (rcs-revision 1.1) +)) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\frontendlayer\tikz\libraries\ti +kzlibraryshapes.callouts.code.tex" +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\libraries\shapes\pgflibraryshap +es.callouts.code.tex")) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\frontendlayer\tikz\libraries\ti +kzlibraryshapes.multipart.code.tex" +File: tikzlibraryshapes.multipart.code.tex 2008/01/09 v3.0.0 (rcs-revision 1.1) + + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\libraries\shapes\pgflibraryshap +es.multipart.code.tex" +File: pgflibraryshapes.multipart.code.tex 2010/01/07 v3.0.0 (rcs-revision 1.2) +\pgfnodepartlowerbox=\box41 +\pgfnodeparttwobox=\box42 +\pgfnodepartthreebox=\box43 +\pgfnodepartfourbox=\box44 +\pgfnodeparttwentybox=\box45 +\pgfnodepartnineteenbox=\box46 +\pgfnodeparteighteenbox=\box47 +\pgfnodepartseventeenbox=\box48 +\pgfnodepartsixteenbox=\box49 +\pgfnodepartfifteenbox=\box50 +\pgfnodepartfourteenbox=\box51 +\pgfnodepartthirteenbox=\box52 +\pgfnodeparttwelvebox=\box53 +\pgfnodepartelevenbox=\box54 +\pgfnodeparttenbox=\box55 +\pgfnodepartninebox=\box56 +\pgfnodeparteightbox=\box57 +\pgfnodepartsevenbox=\box58 +\pgfnodepartsixbox=\box59 +\pgfnodepartfivebox=\box60 +))) +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\frontendlayer\tikz\libraries\ti +kzlibraryarrows.code.tex" +File: tikzlibraryarrows.code.tex 2008/01/09 v3.0.0 (rcs-revision 1.1) + +("C:\Program Files (x86)\MiKTeX\tex\generic\pgf\libraries\pgflibraryarrows.code +.tex" +File: pgflibraryarrows.code.tex 2013/09/23 v3.0.0 (rcs-revision 1.16) +\arrowsize=\dimen186 +)) ("C:\Program Files (x86)\MiKTeX\tex\latex\wrapfig\wrapfig.sty" +\wrapoverhang=\dimen187 +\WF@size=\dimen188 +\c@WF@wrappedlines=\count143 +\WF@box=\box61 +\WF@everypar=\toks30 +Package: wrapfig 2003/01/31 v 3.6 +) +("C:\Program Files (x86)\MiKTeX\tex\latex\cite\cite.sty" +LaTeX Info: Redefining \cite on input line 302. +LaTeX Info: Redefining \nocite on input line 332. +Package: cite 2015/02/27 v 5.5 +) +("C:\Program Files (x86)\MiKTeX\tex\latex\amsmath\amsmath.sty" +Package: amsmath 2013/01/14 v2.14 AMS math features +\@mathmargin=\skip44 + +For additional information on amsmath, use the `?' option. +("C:\Program Files (x86)\MiKTeX\tex\latex\amsmath\amstext.sty" +Package: amstext 2000/06/29 v2.01 + +("C:\Program Files (x86)\MiKTeX\tex\latex\amsmath\amsgen.sty" +File: amsgen.sty 1999/11/30 v2.0 +\@emptytoks=\toks31 +\ex@=\dimen189 +)) +("C:\Program Files (x86)\MiKTeX\tex\latex\amsmath\amsbsy.sty" +Package: amsbsy 1999/11/29 v1.2d +\pmbraise@=\dimen190 +) +("C:\Program Files (x86)\MiKTeX\tex\latex\amsmath\amsopn.sty" +Package: amsopn 1999/12/14 v2.01 operator names +) +\inf@bad=\count144 +LaTeX Info: Redefining \frac on input line 210. +\uproot@=\count145 +\leftroot@=\count146 +LaTeX Info: Redefining \overline on input line 306. +\classnum@=\count147 +\DOTSCASE@=\count148 +LaTeX Info: Redefining \ldots on input line 378. +LaTeX Info: Redefining \dots on input line 381. +LaTeX Info: Redefining \cdots on input line 466. +\Mathstrutbox@=\box62 +\strutbox@=\box63 +\big@size=\dimen191 +LaTeX Font Info: Redeclaring font encoding OML on input line 566. +LaTeX Font Info: Redeclaring font encoding OMS on input line 567. +\macc@depth=\count149 +\c@MaxMatrixCols=\count150 +\dotsspace@=\muskip10 +\c@parentequation=\count151 +\dspbrk@lvl=\count152 +\tag@help=\toks32 +\row@=\count153 +\column@=\count154 +\maxfields@=\count155 +\andhelp@=\toks33 +\eqnshift@=\dimen192 +\alignsep@=\dimen193 +\tagshift@=\dimen194 +\tagwidth@=\dimen195 +\totwidth@=\dimen196 +\lineht@=\dimen197 +\@envbody=\toks34 +\multlinegap=\skip45 +\multlinetaggap=\skip46 +\mathdisplay@stack=\toks35 +LaTeX Info: Redefining \[ on input line 2665. +LaTeX Info: Redefining \] on input line 2666. +) +("C:\Program Files (x86)\MiKTeX\tex\latex\algorithms\algorithm.sty" +Package: algorithm 2009/08/24 v0.1 Document Style `algorithm' - floating enviro +nment + +("C:\Program Files (x86)\MiKTeX\tex\latex\float\float.sty" +Package: float 2001/11/08 v1.3d Float enhancements (AL) +\c@float@type=\count156 +\float@exts=\toks36 +\float@box=\box64 +\@float@everytoks=\toks37 +\@floatcapt=\box65 +) +("C:\Program Files (x86)\MiKTeX\tex\latex\base\ifthen.sty" +Package: ifthen 2001/05/26 v1.1c Standard LaTeX ifthen package (DPC) +) +\@float@every@algorithm=\toks38 +\c@algorithm=\count157 +) +("C:\Program Files (x86)\MiKTeX\tex\latex\algorithms\algorithmic.sty" +Package: algorithmic 2009/08/24 v0.1 Document Style `algorithmic' +\c@ALC@unique=\count158 +\c@ALC@line=\count159 +\c@ALC@rem=\count160 +\c@ALC@depth=\count161 +\ALC@tlm=\skip47 +\algorithmicindent=\skip48 +) +("C:\Program Files (x86)\MiKTeX\tex\latex\amsfonts\amssymb.sty" +Package: amssymb 2013/01/14 v3.01 AMS font symbols + +("C:\Program Files (x86)\MiKTeX\tex\latex\amsfonts\amsfonts.sty" +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +)) +(Z:\scc300\report\final-report.aux) +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 81. +LaTeX Font Info: ... okay on input line 81. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 81. +LaTeX Font Info: ... okay on input line 81. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 81. +LaTeX Font Info: ... okay on input line 81. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 81. +LaTeX Font Info: ... okay on input line 81. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 81. +LaTeX Font Info: ... okay on input line 81. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 81. +LaTeX Font Info: ... okay on input line 81. + +-- Lines per column: 50 (approximate, difference = 8.53687pt). +("C:\Program Files (x86)\MiKTeX\tex\context\base\supp-pdf.mkii" +[Loading MPS to PDF converter (version 2006.09.02).] +\scratchcounter=\count162 +\scratchdimen=\dimen198 +\scratchbox=\box66 +\nofMPsegments=\count163 +\nofMParguments=\count164 +\everyMPshowfont=\toks39 +\MPscratchCnt=\count165 +\MPscratchDim=\dimen199 +\MPnumerator=\count166 +\makeMPintoPDFobject=\count167 +\everyMPtoPDFconversion=\toks40 +) +*geometry* driver: auto-detecting +*geometry* detected driver: pdftex +*geometry* verbose mode - [ preamble ] result: +* driver: pdftex +* paper: a4paper +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* modes: +* h-part:(L,W,R)=(56.9055pt, 483.69687pt, 56.9055pt) +* v-part:(T,H,B)=(56.9055pt, 731.23584pt, 56.9055pt) +* \paperwidth=597.50787pt +* \paperheight=845.04684pt +* \textwidth=483.69687pt +* \textheight=731.23584pt +* \oddsidemargin=-15.36449pt +* \evensidemargin=-15.36449pt +* \topmargin=-35.81992pt +* \headheight=12.0pt +* \headsep=8.45543pt +* \topskip=14.45398pt +* \footskip=23.45547pt +* \marginparwidth=20.0pt +* \marginparsep=10.0pt +* \columnsep=12.045pt +* \skip\footins=13.00848pt plus 5.7815pt minus 2.89075pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumntrue +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +\c@lstlisting=\count168 +ABD: EveryShipout initializing macros +LaTeX Font Info: Try loading font information for OT1+phv on input line 87. + +("C:\Program Files (x86)\MiKTeX\tex\latex\psnfss\ot1phv.fd" +File: ot1phv.fd 2001/06/04 scalable font definitions for OT1/phv. +) +LaTeX Font Info: Calculating math sizes for size <14.05249> on input line 87 +. +LaTeX Font Info: Try loading font information for U+msa on input line 87. + +("C:\Program Files (x86)\MiKTeX\tex\latex\amsfonts\umsa.fd" +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +LaTeX Font Info: Try loading font information for U+msb on input line 87. + +("C:\Program Files (x86)\MiKTeX\tex\latex\amsfonts\umsb.fd" +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +LaTeX Font Info: Try loading font information for U+pzd on input line 87. + +("C:\Program Files (x86)\MiKTeX\tex\latex\psnfss\upzd.fd" +File: upzd.fd 2001/06/04 font definitions for U/pzd. +) [1{C:/Users/Rumps/AppData/Local/MiKTeX/2.9/pdftex/config/pdftex.map} + + + +] +LaTeX Font Info: Font shape `OT1/phv/bx/n' in size <14.05249> not available +(Font) Font shape `OT1/phv/b/n' tried instead on input line 91. +LaTeX Font Info: Font shape `OT1/phv/bx/sc' in size <14.05249> not available + +(Font) Font shape `OT1/phv/b/sc' tried instead on input line 91. +LaTeX Font Info: Try loading font information for OT1+pcr on input line 95. + +("C:\Program Files (x86)\MiKTeX\tex\latex\psnfss\ot1pcr.fd" +File: ot1pcr.fd 2001/06/04 font definitions for OT1/pcr. +) +Underfull \hbox (badness 10000) in paragraph at lines 93--98 +\OT1/ppl/m/n/12.045 All work-ing doc-u-ments and re-sults can be found at + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 93--98 + + [] + +[2 + +] +LaTeX Font Info: Font shape `OT1/phv/bx/n' in size <9.03374> not available +(Font) Font shape `OT1/phv/b/n' tried instead on input line 102. + [3] +LaTeX Font Info: Calculating math sizes for size <12.045> on input line 140. + + [4] [5] [6] +LaTeX Font Info: Font shape `OT1/phv/bx/n' in size <12.045> not available +(Font) Font shape `OT1/phv/b/n' tried instead on input line 169. + +Underfull \hbox (badness 10000) in paragraph at lines 171--172 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 173--174 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 175--176 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 177--178 + + [] + +[7] +LaTeX Font Info: Try loading font information for OMS+ppl on input line 191. + + ("C:\Program Files (x86)\MiKTeX\tex\latex\psnfss\omsppl.fd" +File: omsppl.fd +) +LaTeX Font Info: Font shape `OMS/ppl/m/n' in size <9.03374> not available +(Font) Font shape `OMS/cmsy/m/n' tried instead on input line 191. + [8] [9] +LaTeX Font Info: Font shape `OMS/ppl/m/n' in size <12.045> not available +(Font) Font shape `OMS/cmsy/m/n' tried instead on input line 206. + +Underfull \hbox (badness 10000) in paragraph at lines 210--213 + + [] + + +Overfull \hbox (16.83781pt too wide) in paragraph at lines 216--216 + [][][][]\OT1/ppl/m/n/12.045 EmerGen(e)tic + [] + +LaTeX Font Info: Font shape `OT1/phv/m/it' in size <12.045> not available +(Font) Font shape `OT1/phv/m/sl' tried instead on input line 230. + +Underfull \hbox (badness 10000) in paragraph at lines 232--233 + + [] + +[10] [11] ("C:\Program Files (x86)\MiKTeX\tex\latex\listings\lstlang1.sty" +File: lstlang1.sty 2014/09/06 1.5e listings language file +) +Underfull \hbox (badness 10000) in paragraph at lines 285--287 + + [] + +[12] +Underfull \hbox (badness 10000) in paragraph at lines 288--289 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 297--298 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 299--300 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 309--311 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 312--313 + + [] + +[13] +LaTeX Font Info: Font shape `OT1/phv/bx/n' in size <10.03749> not available +(Font) Font shape `OT1/phv/b/n' tried instead on input line 334. +LaTeX Font Info: Font shape `OT1/pcr/bx/n' in size <10.03749> not available +(Font) Font shape `OT1/pcr/b/n' tried instead on input line 334. +LaTeX Font Info: Font shape `OT1/phv/m/it' in size <10.03749> not available +(Font) Font shape `OT1/phv/m/sl' tried instead on input line 338. +LaTeX Font Info: Font shape `OT1/pcr/m/it' in size <10.03749> not available +(Font) Font shape `OT1/pcr/m/sl' tried instead on input line 338. + [14] +LaTeX Font Info: Font shape `OT1/phv/bx/sc' in size <10.03749> not available + +(Font) Font shape `OT1/phv/b/sc' tried instead on input line 357. +LaTeX Font Info: Font shape `OT1/pcr/bx/sc' in size <10.03749> not available + +(Font) Font shape `OT1/pcr/b/sc' tried instead on input line 357. + [15] +Underfull \hbox (badness 10000) in paragraph at lines 420--421 +\OT1/ppl/m/n/12.045 Within the [][][][] method,[] the [][][] com-po-nent within + + [] + +[16] ("C:\Program Files (x86)\MiKTeX\tex\latex\listings\lstlang1.sty" +File: lstlang1.sty 2014/09/06 1.5e listings language file +) +Underfull \hbox (badness 2435) in paragraph at lines 445--446 +\OT1/ppl/m/n/12.045 If the python script is called with a gen-er-a-tion ar-gu-m +ent of `0' it calls the + [] + +[17] ("C:\Program Files (x86)\MiKTeX\tex\latex\listings\lstlang1.sty" +File: lstlang1.sty 2014/09/06 1.5e listings language file +) +("C:\Program Files (x86)\MiKTeX\tex\latex\listings\lstlang1.sty" +File: lstlang1.sty 2014/09/06 1.5e listings language file +) [18] +Underfull \vbox (badness 10000) has occurred while \output is active [] + + [19] +[20] (Z:\scc300\dat\helloworld\output50.txt) +(Z:\scc300\dat\helloworld\output50.txt) (Z:\scc300\dat\helloworld\output0.txt +[21]) (Z:\scc300\dat\helloworld\output0.txt) +(Z:\scc300\dat\helloworld\output100.txt) +(Z:\scc300\dat\helloworld\output100.txt) +Underfull \hbox (badness 10000) in paragraph at lines 614--616 + + [] + +<./img/difffile-large.PNG, id=91, 455.45157pt x 255.95625pt> +File: ./img/difffile-large.PNG Graphic file (type png) + + +Package pdftex.def Info: ./img/difffile-large.PNG used on input line 623. +(pdftex.def) Requested size: 212.82779pt x 119.60815pt. + +<./img/difffile-large-wo.PNG, id=92, 455.45157pt x 255.95625pt> +File: ./img/difffile-large-wo.PNG Graphic file (type png) + + +Package pdftex.def Info: ./img/difffile-large-wo.PNG used on input line 627. +(pdftex.def) Requested size: 212.82779pt x 119.60815pt. + +<./img/samefile-images.PNG, id=93, 455.45157pt x 255.95625pt> +File: ./img/samefile-images.PNG Graphic file (type png) + + +Package pdftex.def Info: ./img/samefile-images.PNG used on input line 631. +(pdftex.def) Requested size: 212.82779pt x 119.60815pt. + +<./img/samefile-images-wo.PNG, id=94, 455.45157pt x 255.95625pt> +File: ./img/samefile-images-wo.PNG Graphic file (type png) + + +Package pdftex.def Info: ./img/samefile-images-wo.PNG used on input line 635. +(pdftex.def) Requested size: 212.82779pt x 119.60815pt. + [22] + +Package wrapfig Warning: wrapfigure used inside a conflicting environment on in +put line 643. + + +Package wrapfig Warning: wrapfigure used inside a conflicting environment on in +put line 644. + + +Package wrapfig Warning: wrapfigure used inside a conflicting environment on in +put line 646. + + +Package wrapfig Warning: wrapfigure used inside a conflicting environment on in +put line 646. + + +Package wrapfig Warning: wrapfigure used inside a conflicting environment on in +put line 646. + + +Package wrapfig Warning: wrapfigure used inside a conflicting environment on in +put line 646. + + +Package wrapfig Warning: wrapfigure used inside a conflicting environment on in +put line 647. + + +Underfull \hbox (badness 4254) in paragraph at lines 642--649 +\OT1/ppl/m/n/12.045 Tests were then run on the test suite + [] + +[23 ] [24] +Underfull \hbox (badness 10000) in paragraph at lines 664--665 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 666--667 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 668--669 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 670--671 + + [] + +[25] [26] (Z:\scc300\report\final-report.bbl +LaTeX Font Info: Calculating math sizes for size <9.03374> on input line 100 +. +) [27] +(Z:\scc300\src\emergenetic\emergenetic.dn +Missing character: There is no  in font pcrr7t! +Missing character: There is no © in font pcrr7t! + [28] +Underfull \vbox (badness 10000) has occurred while \output is active [] + + [29] +Overfull \hbox (9.06848pt too wide) in paragraph at lines 157--158 +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][][][][][][][][][][][][][][][][][][][][][][] + [] + + +Overfull \hbox (181.78821pt too wide) in paragraph at lines 159--160 +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] +[][][][][][][][][][][][][][][][][][][][][][][][][][][][] + [] + + +Underfull \vbox (badness 10000) has occurred while \output is active [] + + [30]) +[31] (Z:\scc300\src\helloworld\project\helloworld\mutator.py +Overfull \hbox (61.7654pt too wide) in paragraph at lines 47--48 +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] +[][][] + [] + + +Overfull \hbox (61.7654pt too wide) in paragraph at lines 52--53 +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] +[][][] + [] + +[32]) [33] (Z:\scc300\src\cachingpolicy\cachebackup\CacheHandlerBase.dn +Missing character: There is no  in font pcrr7t! +Missing character: There is no © in font pcrr7t! + +[34] +Underfull \vbox (badness 10000) has occurred while \output is active [] + + [35] +Underfull \vbox (badness 10000) has occurred while \output is active [] + + [36] +Underfull \vbox (badness 10000) has occurred while \output is active [] + + [37]) +[38] (Z:\scc300\src\cachingpolicy\project\cachingpolicy\mutator.py [39] +Underfull \vbox (badness 10000) has occurred while \output is active [] + + [40] +Underfull \vbox (badness 10000) has occurred while \output is active [] + + [41] +Overfull \hbox (37.67543pt too wide) in paragraph at lines 218--219 +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] +[][][] + [] + + +Overfull \hbox (31.65294pt too wide) in paragraph at lines 225--226 +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] +[][][][] + [] + + +Overfull \hbox (67.78789pt too wide) in paragraph at lines 226--227 +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] +[][][][][][][][][] + [] + + +Overfull \hbox (51.22592pt too wide) in paragraph at lines 227--228 +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] +[][][] + [] + + +Underfull \vbox (badness 10000) has occurred while \output is active [] + + [42] +Overfull \hbox (71.87785pt too wide) in paragraph at lines 233--235 +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] +[][][][][][][][][][] + [] + + +Underfull \vbox (badness 10000) has occurred while \output is active [] + + [43] +Overfull \hbox (58.75392pt too wide) in paragraph at lines 325--326 +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] + [] + +) (Z:\scc300\src\cachingpolicy\emergenetic.dn [44] +Overfull \hbox (466.77783pt too wide) in paragraph at lines 148--149 +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] +[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ +][][][][][][][] + [] + +) (Z:\scc300\src\cachingpolicy\project\cachingpolicy\setup.sh) +(Z:\scc300\src\cachingpolicy\project\cachingpolicy\config.conf [45]) +(Z:\scc300\dat\cache\difffile-large\17\chromosomes.txt) [46] +(Z:\scc300\dat\runTests.sh) [47] (Z:\scc300\report\final-report.aux) + +LaTeX Font Warning: Size substitutions with differences +(Font) up to 1.98875pt have occurred. + + ) +Here is how much of TeX's memory you used: + 18404 strings out of 493921 + 369080 string characters out of 3146480 + 519461 words of memory out of 3000000 + 21258 multiletter control sequences out of 15000+200000 + 58638 words of font info for 147 fonts, out of 3000000 for 9000 + 844 hyphenation exceptions out of 8191 + 55i,18n,67p,1330b,1578s stack positions out of 5000i,500n,10000p,200000b,50000s +{C:/Program Files (x86)/MiKTeX/fonts/enc/dvips/fontname/8r.enc} +Output written on final-report.pdf (47 pages, 383434 bytes). +PDF statistics: + 242 PDF objects out of 1000 (max. 8388607) + 0 named destinations out of 1000 (max. 500000) + 33 words of extra memory for PDF output out of 10000 (max. 10000000) + diff --git a/report/final-report.pdf b/report/final-report.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1cdfe5f628aa90c488068ab4020deff6599e45b4 GIT binary patch literal 383434 zcmc$_bCf0fwl0{q?ObWwHY;u0R;6v*HYzJKE3Hb~wr#soul7FY^xL=ZdHwdgeMk5D zYpodZi--|1<69r*BvTL-r(>dLgCU!qA6SNA2QUKcjjRB?yf6$hrgr8o7629wCcr;F zFbv|BHZG=400wazLl;v~Q)7D*Qy6}J7-ttJQ$t%A_thLFS@}LjxQ-|F=VfWu#Kd5BOaIzV7Y3{OBr&tFaZR zm&|`sH=7f4FmM|u*sZYpWmwv2f-)CJG>^KawWI4;@^s`2rRa4EGC*%Z#)`bJ2Xmwv zOy8Sr^_6$tr^R> z_*<(;)K@mXxjLCm)Ll#?Z9z4di7BcTtsOQM+d2>7@|Rm+1&ga~=fEbx;^19kWP~4b z1bZ522v8v$lX2kE1TY_h)B=NrC9hkW=$-`=U3DLLbzO`0NG7ENFs61U|GfLZzx{r4 zFl>K$f+`*krT_*7LvvFY1`&HZ7gIYIXTTqiSP6zf$<*2YtCO**Gl2CU8)QvQEDeS2 z-2vK+zc;XPvC%Vgumd<*ndmvWbYXrU#p(BQ0N0;8^Ya7#dAdIq|Fd8Kzt3S~@1*Qt zXlx2#`D4F7&h7HMVC(?Q|M)59?joV=^1F5bOn+|pT~WU;>vy&NE-4O10LMS}5@+WG zaQ^xAcWp5!IN2L3o4NqBe;-X$9KfJr>h1#2{atqdx&)>_4*q{DS`H4*zg@InRlhi| zG9q=}(Rf#8Ko2r>@256dQsl_-BsrYj158%Ru_9{sTi#wTtuV= zW*&Gb9gy`1kYp=pCX NusVYaJ$};Hy`8u0NbMdAlPre_JK=nx6~WRGH{35%G-Gj z3Q|+V5S|3MHkBJxB?h8`cG8Y&e6z%O(&M0*eV2Q#FIJ%34Z8leRJaGf=w1->O==-j z(6_gW zVvsT4f|#%7sbh!aj5)-b!aD|1jPr#EV|AB@MGNNG;rN4M3z%Ldq~yc9Q9VVMY6rMz z*wA`nS4VeH*onrAti-}qtmpJFM^8pIzQ%_u;m{EcKwpTRhh7MI$tey_eRI=s9%0L4 z0Mgpbzlpbpx)a3U6b*|84+-~Z^{f0L4Rb(;Z|kG`;5Be)Du-48xKN}?&2k`_hE1Dm zbubVTKzN@CJPB2?HQ@kD4V0!p=uKMJT=Q`#hNn-DTJC+YkmPkOTqs<+bkMb`;+@B# z9IIq?rGRuBOekEDj9L6ffo|EOdYQalPlblsw>T*_a)W{k+G5^7^`usL(Zr_V6L)@ zkxI#nv$rzvM08RY`Y9Ba={e^@AJx(EBP@s~I|nZhAMDyN$dv$phShm9Hs@@huDPq{78hy-d3H5((1C9cGl(N zRR4B2&&hY$*?rV9z)K~- z-vgRIK+LYB4&&jHb9$*R$a9qPV z+Yg^3F?LJmVbAm@?>mi@9F~+0ejk2bpXb$bn>2hmOQzsmwws4EU;fblEaPt)F;t$pSjVV&o6rE06iDqE(W*VwNX1 zD!92SW+uFEr&niupk0*vbscZx2bFUg{TsgAcT?U_lq5?8^Y1o;0%mx%!jWidtrvLr zp>$zFEkxq<#_faa*`Y%At<))&&}*dXxQ=%t@3+(qb`3N5VSd!&V0B zI_R`Uwt`w?c?Zv=NLhf{9&Uqqn!INS_u4Yc;OAxyuJolH6pyy;vE9t>rbEn8+M3N^ z#N#tgoFxb<1!`$Gr#wrbcQ4YG9-8*tBjS=<26xgjLLKMoCcwW-SHsL~Mpn4xdB-H~ z4Y?xi?070mi(5~Rr+Sm8`j-9KRfC%brA-cVrm&;^(6QMOMNhv5v-HPzy~VfEcpz&? z$m?6DT>?7#oYWn~1r|IMmN^Xe_BRV+T~9z7m3!%;@!XqR0EzR9C#%bB`Zf=wm_k}q z*e6{VUhW6T?l$tszX7H{n8Lr_#D5P=e-enl(j2CL5}*GfF#UxY|MwA{{|QWg3xJsa zipT$==ggcef0v%8XlXmsG{gG}boI*f-9|UAR2KX2N+q%SNOI%5{n~aXZxH>GeJ-YZ zsU`9LFaYV_UioG9BnlHu5D833hjIw88u6aI;DtXtTF7C^yedc%n?!UH>jo1ZYU+& z@)2Gg#8l%?cY97L^tmVYbm7R4%5u7{;ZtsojJ;(Zr_v9^=Mn^%-Q)b){rEW~doJw`v+HSml&{kuw{c z`^D@v)M8a(9C~KRVxW5vlwM_D@jS8LyHeD@uRJw%YSoPw6-xHv?S(uvr%^`gt^G)} z2J_)=xe)5M)h3MCyw}tC=4$-|MT(;6d!2=DD&iPv+96?NRyNfPNz#smF;nkXAxLe25kS)WKZ9W`SS< zn?dDVdv(yN-o5_z9iANW+Aj1P<`0T5NnBq^;m!tX$)1Qx_+fvM`KWSd#rr3nA>L8p zGUFiNA`wE15`JGwiL;dtbuCpwsLQ~ckC}9vB-a}wz9~+Nc2K;j(glqIF}X6$zmPrn zRUfTEHXHzK53cJD6LZ1~Y;$?NMft`bJO=DXDO&kmBW9;ap$aIvOv)ug1$RkDMu!2S zW<6GpYx-2mI9jtW<9MO)Vm((_jO=(D9l!V6Qaa4zqbnrj9WZtlI#*-}Le>LFS;?jc z#;Rf{Pc!<~`uBd^Zri5flO}u|vIyTZZ)E7byB?1K9cKr7r?2cn9>U6K#SVK9{r)`> z0j4}Ibq>x)2zu+OE**-mzbK;nt^EfUP$d}|+4h}^fjqfIu=f;(4dI9IQ|FICtkhdd z0Zmm`eaw(`n-^rf8mmg9BmN7bc=iWTQ4uvO8ODU+-VJc$jl$ybs4EDKR|T1I)ylgA zz50N8pKF9!gN#b=mK9Nzr05riI-$rPDb@8MgquGvz(ZJoFGtUl97=m*0#rUBBaOs} zo$7C3{0B~w`6^a)XxHE#vMxxwz9rUI)e>uh9GtpxsI+)ueSv~xT|nS@0`q!($wlF`-90T3lr*d8=Z{^IEgoN^U&+*HCAbo`>r zNKhr#;Hb`QVorpB04o?R9E}wC&~5#8mEf5sGz)%ip3sAIPkzIq&idnHJ>4GDhjN>RCy6~uvNjZcgc^1 zgsFBvlC!|asi4ZAR?CFz_-9!+;wEBTJU%$H6Lw_&X;27txO*w8K{nwGc`1r>8kLI8 z$!+^m8oCUeTVEFGh1))tw#{BZ%xB?9x5d|5<7yM?RH_Y9Cv~E0QNoouFY+k`z|x+C zJuw{{<4q;DSsKwHj@}tz?uByeE^I}-s!SNWJ~^zcX`ioZPhPdEcQ>UE6yJorsnr#= zQaNs*Q59gSg|)1xcvf?yttt!5Ily$S@{Op)%iY}?&tBFgzmV%y)@KsqFtAnOjxLl~ zv2V4AkA9y&SFJuGP@fDA>|g239t~zL?n_X7@wBgW>j^72d|wFWIP(%xqzcNaCG2Op z!VD2pjHkt;06^>bM|nmkYRxBf(2lPIgVoZFGvj6R z?2osBMKbyQoVVTu;kg(&{RY9;5NGTVslY1Q&}+#*tpvSIi*2hXGp9dk3|gS&)PF6f zBuZf9$li8|#CTs5V-rxLdBg?Rt`ecTJ8BdsC@FU$u=-G2A#h+uSis2uvQQuNN1b zitP*)Lvu0AMwB{HdXe3<4Wb%FmjMZYc#zhf4V_^*Yj7lILJ_g?>Rn1?w=%y}4!Ec( zV=ajrf)x@cfu+^bfTw{1IC@l7ezY}pchDLQe(eejS;lXUa+4BKJEV?!u9|;f2VR$i z@)lIAF>sqkV#`h0gN7YkGpd)?qHn{Qn!qXLaF#bV(%n16IXpDuU0N3Li9PM4YFX4Y z8+TOB zGR&9SI?WVYvApH@n)6F?2CwFwv+>BtL@1bwl@>*VnzIfgQYI>_&qBGoZ|Vo?PbJc1 zca>78B1Us&VmWlisH=uR z$_l#41gyXelh+6@77Z)cYms;Ru+eF2nn%QPO?$4|;=LR0!xV;3aMyEr80sh3Imb8z zY@WmF>L{0E?qri~2g7RIOh=ArP0`FTyW|}C9KPZfk`nlx>@Ix<{z61xutYxP4Q!Ys zvADji)Bn-6Q&}cyTFXq*k^LI<_%LJn+68^nBdt*IZk;-i*l0pZ1HO1}fpHVURVbx?pf@&o z?{)>u17@#!5_vE2jGxs!G+gB86$fs=L0N+C8bf>g+}In4n;dfoFxYiX0uWMDQDz7*>Cj^ZHmqR%&%qXlj?2%RI}|R71X3Gc?}MSK zU=?!8d3QkeckhAw-~S4Ba(ML&Fm`6nZT{RdHdUe%9}@43n5-^=$?!h~`xHCH`G2X% z{a6NVL7cmZi{##$=!^p=9Q>87c=F1kQ1Apq%RwYHv{h*eCXXi;cqDELzozcy^iv}l zuiUW5I+Wi6Qvxv`N$ zE73Z&)0}LYNfDK&(0Fizmg)bqV}a{)JtPF!X-P8a{Mni5fPy|UoKu_^t_5$>_}!7H zYkUC9d0}{V=$qrm7SYb@`(4>5P_Jz!;eS?!%zxNV|BuS>PZ9MWEvtW++W%F{>W|g` zpIKH+jLZP$f4b@7oE!k=fB9ORtN`YJ_*#EYO8!+r|5HjbaWekXHUHlyJrf#V;`Z24 zI-hE$>Fm1IL{B?}kW79^{b&Wty0;}4oJX-`Nf3>pY@B;}&>kQ*m1-(0Gfxnr$Izrr ze0ckI+|A=2@YJ`F71qwsB@fDQNAReJC(aLR%rGG$uruye{2ayM(%?dZ0Z8dI2hMy?4EwGgFSPM#Y{TzF4I`Lf z?@-T64rYm*N%z&(N1+2RcH*5LZWmsJN^o}EP6|{Y+L&{iv5TsK_R5VHmK|~?vPU-Z z1ZjTf+qu*sf`P z6YW@qV{rhW+P>=D>1f`3rLixO=VZvk&c9LmXpZ}MsP@iPLl@PQsLBLon}YeSl{+w_ zJ`fq$sNuDs42S-;BeIb30W_5-Ld|L_PSz;TJhnzjec;;FWBZQxv$%cC*l(&X#wuAY zhQ;5e=0qSZYM|WiEzqQ1+l^Lsd((p6#4pcQ+zTDc?}uJ(a)}88H$WqsHni4WJu)av zDU~x}3mlkGtDtJMP34fg7A9s1I-n=QZCn)DR!pMcOLZHA29F&T``9~UhLIp5se)HJ zTvPImE)pb;@A6PvVtx12v$f8M<{=AER>pG4X>Qd)uFfM|WM|d0v%3#J(+7uEg3bn- zzsJQ+Cb|GOvU~iCCR$f|VKy1RIc(O*yO#JRByT3~hQTEYAi*MTpy>O70sMPoW8Da` zV?sXf)1HHpJ7?tM0onlHNbjZC(!yh>8D2DaC#@7t)l{|G#^;$j^I%v%?1$#fV=Znq z`X{I4JEy1YLzyd;HpVNZ)H|uHS@=|ug>u6^dJJPM2nn3%jFmukB=lkY?RUr-8%GrT zVpE=q+Uj%7uT^ra!BB<3t@`nr@B{t_=VmL!Ey6s8ZZ6Ub&XZV_ppqdQ5b0JIE2YYG z--Ths@er%d{Y`ob63BLIQ?^hR8Y~L%R+*OXWlZ=UV{m5BT)vSJ?xUJOI1U@KYT2GR zXtg0JG+6QC*$$70Kc~?m4k_Bx4b7;bp-92j`B@^m3xGst_1d>a^~4nGk$zqkHhc-O zxo6&G3$J=&C;A?=w4pHhbAD>hAKPUZD1lfYRBi=BBz5yN7wETy6D~o?!3(4*^W}){ zb?&OPyir8j7}bk802&lk-##rD6FVyhQkwJ*g!%?L7Ypw=Ap(MF8%bxYr%|pK!lyL^ zHo~#UjU-3NI6i3=1sOK2)G^B)vS@59Ej^62zm^I?v9}m6J4sX*0gs1eTl+95RgsU| z$Q0mgbzq=CJFZJMu zl;REPGJ_Gv1`ZMbT9|}Rrvh>-{52**O-CfWKg8J=Sdsm)m%@;ffe-o-%+1HdL?W-y z70q$2L?Zo0lu>qcF;-|)YkE1-3&EW`T5>M2_hD>~;QgJ)U2HgqsC5N$M%GM$a_*Z1;ga+a)7TrEvB{XTv zG%F8qE{eKPURhxpNV`CGI^#|c3LU4V8HCpI8IpICOYu5S>5&)2^N$V`Nm5ts6SnMM z&Gny#qcW8Zr*x0po@99@WI8oVZM|gsJI4w*iP#Goag-_M5UImuHrqagqzl?p zckbJ+-(dy$8$0U!bfRHGtJ9-uZ{LTtuY9vFI0(p2o$Gl1DmPa3jk6q%A|@v9Fe;~# zv-AyAsM53HqsO^%gTs=mt14fne=0hDF z)6~NlMx>pV1t+!%G|?=w1u_A!HlUJd-m>RlI<>T1b-1;jD3KQGWT=P0$~0}82>vj`%8Al#ROpflQ;dJ=V&bdCa`DWWd7SZ+E*o6 z`=CF&O!gZBR5UvC@7pS}8d#d`X0d`3Bgk}<6dtzXwgHW2o^>9NUdvNG7GaE@n!Kq| zVMplV;MCg5Ot~nj1q+!aTx8`o)9j;rPq$wKL_YB(lmeh0z6YD1B|Ar=NY4e{3VQWn zx8@hx3R4cwNMP4kl18UkVN&4LA0zadm3yjdRxG^FlCUPiP!Gv1;ukle#^V_&MN?Nd zLjY}njO2c?eh4#@8;raXtl)n@x`w%b>kq$8u5wOB$_=$G#`$?#T~`=^I#^$>M3j+? zeKg~%G_7CQR4@<>wX=MpCrE9eJVP7cncNf<*$`l&qYG;s{Bqacl-L2=F5kC%$8}aK z&;Cv&XAw{&p1B%>1Mlq_6BR_d6jg1PcOg~T=0=_!mSDq;Nb=%MfEa*Ff+3E!eWvr_ zxG7!*=MC}c^LhRmEW$5I(qpfm2X~z_&|B zq-)Asncf!|*k<1RKUX@-Uqgw1Tj_s3@BhHKS^i&z#DA{-Z?E+KS=@h%K(qX{(dJ)S z3=`u&d!_#O1Uf}i^A7^;o2PGR5MawTt>&UN+xZ|vF2vqmFElGezzq*aH^bgcHZwD0 zceG@$n|wfm_-cd^H6Sv;-B}nk;EGJ!`FVYF(#Nr7+C!|*Yl~r-{cM;`Uq}3?uGr%K z4P#2r_4D?A3Nc_f$e{@eHCc~b^AJ+3K|?$tPXanh;%SUg67-5h&iG_HPJuu64a5wB z_Q@S_?x+0InCkI6R9C_i-}{GmmkjZhfas@mm%ilT+MH*@Ds$|+MG9@I;iZHoQPwMw z9U<7J@mAb~FJse%sS!PD&>fXL&)gQn9^m$I!zbPAv8xR)9@*2ihKJ1pyNRwj5|YE! zh9(4e_&W5ZuP1W-1PpQ9vJu<0Eop#bocCO&^_4HO&d_}5A~ply+HX8(h^nu$R!%}m zhxoG*-&LmKU9U3sq-V5z@Bqyx2BX%^7?;!Lq@KAKz;8)1`c8{sn>`;2Db>*x@@cSJ zHfhJRz*@S&9MqWV$+Mukgp*tI(l_K6WPw~e8Xvs_y3j52tYVhZgo#lB!Px~VbU%rU z@!id!TH++_o2gvcYE>%!GYl?)1B(hnpB=0YH#~b&(z_Oyu<5VaPRm7|uRg#F%QKF% zwENB^J+pq%p%LQEB2y%7>?PR!;6b8EDVGyXA)ujk2?rSC znGZT($4X+Eb?WE|U0MT^RSM>qOUTu4j8xe`)&!W@E`mqE_}fqPNq{Hkbk0{BtQ-hBCixa-!>><-48HNHuSS3d3h#S7QvhjpO?1Fz$8 zph~AB9p!%PhHo-HeabT0b@`_|z0>%;h2d8gFT%0YYL9?u2KnVfz2CP3n@5!?;n}iJ z#a3&h9*eLB$oU(qvb)5xxX|@d`&%JTLsey8o74^U-E2P55t)GI0l^CAHTt-U$pOtK zVTS&~YAonoFWO<%tiOcIQ0(*rZ(CV8C@2xlb8krQikzE-J?=OeDo@J--EGg|AYkfbp1hVT9 zGh?~-9JJlxtqqtH19{I+7e{mG^>^Zb*rE7GUqW&-yAD6byDK+3Vk5jlu60C8GT=?n zg&2`Gc_KxC9#SU)>q{h=$(}y|al6meITjI}sg|ldz>g`t)10HCSFF=0MRJau^bdo* zpU#%I@jK}^p=^kp8?g`IWJkMwk;+v|7VP1R4C^0|LNWm5 zSMJ&n;chLkSA8;Ze+d!7a26S-5E&;%kl9ebvsV=y{Rp@om z(As2u&CDhYefow=?@GNc*Ln`-W^~}Ku0NAO7q?PNp?k!n3ziFc;$tr9Gu*VU=Bd9% za@e00n~OfOK37B|j~MAJ|7p1W71?K+AI~>_U2D2-k2+y3p=UoreJhM0k0k?P2tugL zd+s+&w4v?>3dzOeXP9L45Ab3%0BiF^a!{?{TWz>sjf55iDgIvd9jB$;b4^CI+ZGT#3eeMt%fa$JXsJbj-9c>poa}Y#_(6;wNliRR96hFX(Hv4!6O6%iNQ|rnR9X^oPl9D@q#}11LUkY*9$~~T zPBD?Jdmz37kvNsK!UtgPA%%dPhXhOmOyE$S;%lZ|z-ydhW8d=na?JboBZ~SExhVKc ze&faMordt{Oj)uK(HECQ*=UnoJ?s%Bu#R4!@g3Q^nI-YBHLLJf!IipN&R(tXNNaNC z%m(=!N&O`=mv%ygw961bb1eqMz));FB$*V<&SQFsOwpBepVNN(p=l6n$MtHO{oXCn z&|68T=DnqU=b0^<8(_>+o@Sbhj<5kev6uYX-9hT4LbKw$`_HP@;@ zmfESt6kmB=DsW<3W_v%DQ8HZ?=<6OA8;DI;>pSXJO89^DQ)R!28Nxh{@9}Jmk`*XU zFQ*R8EM zC+3reZ?&=covI1KY!ElZoi*Zzwp#<@2mFc20oS@!p*YUH9*^=MevPBq@c@z*kHN=! z9Rz8&`2xcKzZp0{PZ=(t09MVsPExPz=Fm^Wd)4yOq$Y4U=EvV4b9|*F{EmJDT z&3#cFM&^XCQ0u)^p;5fDkRYg%S=fXhpGUii??vj{`?cW!Eo2>!8(JM|EJ!>CEmi<6 zR{CBY?QS!q7hrBEHx4r#F#~I*0tj4|4F^PdV!+^vl*0s5-I*b90%FziH-T@dzoJnE zLTD11Z?CQde9qaR0JU!**3HBe&qO~MR15M)_$lR79ynCU)2eh@aXoE`!8y@c#y>uUnxbvddZcE;*rd{SI2CfPw+Nf$|wG%&bCg3Mv}3Q0UY zjlZ+k9mEE5_4Yl>D8@lr| zZGgh#fiG>5L1YKiSbY)`i&f;whhPg>30Du>9+PwjT*<2ID#E`xvQyg z`KR;~36KfBKCC>wV>XE%Ct?l;M9B;bll5|TR2z3Sl?Yntm~E@U_15NCJ}Nh3YX{xg zS>$c&MmmPfsEMWLc+gLPR7eLXE!WZwm_Pf%3_oA<1*m#sgy9AU)^zP%vKTqA`Mp`YBYT_b~CK?s0NHZ&)>|?%{brQSg#fjuI-;JiK}Z4!Zja z2QMIJUwB)MJCPz8S5S6D1JT;hz5^rPe&CMfkJsP8r?dMoa`Lg>W$eLT!5LG*cPROX6j7vziMjYpw zI>;Q2@r~M(eMQDzI>xrSL#Cmu&!*eL_NdrX777Bz_-0og6ZMzn>2|z9b&Q|m&zi2L zL*301*V3krkj&4^p7*O`*Xny94Ix-8Xa8F+IK4?$uN7b4U)KWIxY`{5Mq~Y@&HmrJ z34h9w|ERJ4Oa}h0o51o9H{ySG)wBGu{J&ph{VzIk|AWoI#Ry>evsv%AweXj`<8R3_ z*1zUI|B_|Qzh?{n{QU1_Sq!#r++NeoyKhKd9e=kPtzzBx#|lfQ32=CveC>Nf=kD3x z$p*!jSjnoT_lF#Y(Yh)KpIHY^yu`kjMXRQ~Dl@;=>y5iGdx3+>6|={mS*Fx6Mky1w z!eVEnxqRyNX)lL+X-9ed--8LlIqEruPE9k96f?=|O%p}4NKJ2@*L>bvWY{ZTYARJ{ zu|n4%x^C79!D{Cw8L-az2eVo$sx}vyEphGJ2Ho|Pn`Dip?bilx8U!q+;tv~{%dPbc zI*`;3C+06kTzGj;VL>6^&C=1JxPKC^+hUg`toQuv!?DhsRdE`$W#CyHgmzvUm0hLB zv*zr)!@(F^a0`6cY0L81Vr^Q1JVoxDV~gYGNLiTKoB0SpQS|^>TjCoHmgr2m>ft2% zG5IhEj>YBkN~K43>+aYYS*HQ)Y*b0(bNfhl-N|VmTW98e74w^bK+|CKY9cuBFW+|O zAIh8NT+u>Jsu)*84Y>n)FAS&1Y5T_Lli*wsT^wAFN(Jn0;FaC2lgWK`yZD+^_4nW% z;iPvPO)E+rf!nVX*jz)|if?2}%nck z-0_hFIu6a~*Uou-L`CVRer9x?Og43(erswfVPi&-9Svec=FmZb>^!i)8mF6^0YMTq z9nl~bf4i=ZqcFK~&`LH9ed618HX$A8tVW{s|ElR1edJ^6{yn3RoJ^?P)@lvv&5UM_ z+5OuCcu27I8!%^n)viBbZ(~l{#Lw?Ylc)@#$6H>y+J1%v4!aT=Zf%Yd)2_^+E-|x= zUH< zbw;BOKb+UpoDWa|N|{O{v0gofDCcfo+8r>a3Xclxz75f&(A7W(Q|r}_8^^!jfKgZA zMvI60eVj2c?_l-VhYGGO@`{CWXO10pHLeN3ZspKE?fGnz(_O_!B?+!~b*6RfOHD@y z>x{|ee^*96RXbraxHjGjEq{!OIWcfyE65ONGLQ6o>$K`1=pFhcUbA>cL_BR!Mh9b* z=I>PWQ@-e?54(t4LQc zmtYSvK<3rUo@XZqT#rLIK*G~0x^bf733wm<(nPww9V+Z0rO)7nbK9WTVTGW%iD-wH z0F}7;(M&!;s>-;I8br8T3#zjk8w-sByAlQ|8PZyViu9Pok>|VJRG%k=-Tbz+=jC_I zk0G_h&M@UGSz|yzUFA)P$hVs zdbXW4ETe%)cq~^aAeUbzG{7gxXx|c|Dslq4`Gu|_*gki{Ax96r@SMkGZztaJl3oZ2+)xKj zI8kL$murXCL5ULfp#ufUoSg>25fM2EC}cG#93bq!rWKNFf>2rEpvXC!>|Ah3k~qsz zUe&3Ti_Lo`mk^WjBlwBT})Bg|}Fu@B3YlpNIB@8u=OqHC^#pN1^7bEtpl={`{ zN9^RkNZ*s6RwVc>QPhT4v9N_KOH+&<{HTXqXd+H$833XiY#g72!j{svb3eSaPS;X; z6E$LkLm+l=2T?qTJ5X60VicEfE@j5h8CmnsKTTtyh8EleH^D{(`e#!u{J3S7IF2p2(oGufDvto zO6I}*g`@mt$r<7`!s3ffjMJaiLoHY})8fsA=O#%k?AOM48{RKWXj9f4{^i8`de=_JNIsZZ5 z8kmQnuulIS=DC=+;qP(GEn|JJ_IpT={m3k+5DhG)^X(HdiFh^z8QoymT!XT)AAMD9 z%ytGYr{^^N9EmAig&~_X@+~bdyZv z)vw%wn7480eWx_MPB!oB9>s*GX=|oUsV7P?cnax)IOpMds8TNZmjEk|GllZwQ9bMi;lRwb>b|$go9o)yu9krX=w63o$8qP{c6$?m#4T_tL zgM-o>QO!f3s4opH`Zn?XdKrE|aYTwj;q)m5*Y<(c8KvtBY>+0Ufd#hv;GtesJVo6} zZ1}LDd$tQ05I2LSO{&eyHAPhjkPro12LyAQar(YLNjOXp>*Pjw9D>95bI;c^MDH|| zZ|6c23(LbKcqgOwBk;3L#_1V{m*Ra1*EQIiXxEo(^gMoaV7*6!cNq6^E5G>hMC^MK74MXJoDSUVfz-uT5^7}8Lo)lsnYu`#wAr!9iLWBY zBn^dLjC20AUdLwmMsUg82ie`GBpMqd&P2QdEWdw;K3JaQIMsRMW_KGJsmX2}X@45b zSEXsRZU`;#0Z7KX(psi03_)hp5Bm7*`Rr$MdtI?@=^^pbfDYcciLyG{+K48 zT`3F_8AW0ksAP0~ka+XUdJ^CHUwf^k2NBbz*PkRtiXa^BDsOxHXJd7|g52zH+D^~7 zV;dh~ZDTy~Ur5-Z@S^;dLs%8m1GyXHvp%*a2By-%zEer{O;un0$mdn~1W|<7GsxWVJ+Z%lII`D8r2iUfGUgTI=!cJB1IRZ%9t&cEzJyRn@<_!He9U30 z{2bo~FXUC7We;EWt{Ca|8(FKP@M&R3g^W{ZJc974UG~Q2##+0^?YaQ1cvNCTuXh)t ziz1Cu;cwWTJaTq9UEKmOs%V4-M6PE)-|UZd8)6S3qsi-Jjl2jbF6v3jBX%C*i_Ql} zw-|(l>C5Q?15GdxmJPfBp5grh@1W_Pj0WTb{dpr;8DZ^M8Nu1^CDKvm!jjSwT=K;4 zYEV#ed-+;6egs2C6_6gBb#A8M%10GU;QlHBSE(EDlpV0i6}z#r$mm4;N;|?5qc(7j zXQlMK^V)Y8_6d>_@523W^y6Q8)c(DG{8KmmNB#KE397$0FZG}G;~&fa`}N~r66n83 z!{5>LUxnrWHP-oue&hnM{$tqu@9D?CD(!#jN9O;7ST96l<9Dow;J4L9EYE>$FxZIi zXGaKww!9+e*a6b4ybfFs`rU}8mN7O(%c<_=Dh`cm?WN^W3QcMTO)NoxOUDLtXZJ2F zPoMwoIyo%L=%!AyxRNwn?Sz;?T?j)WD$VnzjrM9w&-Wdvj-L`Uic~Ru2jEb zwWh=)|dw(SA&C!QJA#QO&bH&7mr=tO@${%}31Yg+nQ(~|ZYLoE9+ zz5FeRR&1`=T`jGZD-{aMNJ5F$P}$2+e3n-|7wy)h95O2RZWNrRQ-DVS`XL|SGAR(h zq3o41G8K_jb)&If{+lgpou7MTZ@Rn@I{3;rAh9xHCMS;uG+V*Qy@&x*q@miSSDaEq zJaO#k8Bn^~7-q?kFE}J{;WJg=LI#kyq|6(aQu~=5QmaT0OEGyo=HGcDKHe?w3%dFI z>kYBdOn*uSqCcPWzFdXmX(ELn?=KbieBk4%vY9-uZIY!|he>y4a$r&+nFu9R9|9Mh z_imVk$kXHpYtvZ@H>~vO?bv9jzLJe2rQnNxVHGV=%LW{|3cZUapHuU>ESgf&H-Bgk zpe$QaILd3DB%Yn7Z>aAP>kte?Kru(pyEkUn&?@sKSg(W!&4S9Sa#&%h<$5DthTq|s z+Aq<+Ay{`yqtukLu(1kIOC}?nr1OfE0^=86LyR<)La%dj^oBUt*>7}or|gYz-nf~b zgKFbk$0wlBzR!1Zv|)5~{hkW(WyYNem+J`y$bJNfw7khS+~#m*pAjAY$|2gEBh=6J z`&yVO(@WOl(e~GA2B3ir2gv<;lKzVz}mBLZTa) zsov8eFpZ#i>Wc6snJI{M$xC68;yV!t?A5f=Mta%qdELwXLZ`xk4p299L*bA8HA2Xd zcVo0rhckgOIW1K~#;60#$o>tn7r`!=a(uG1akaeZFv_o%NGTo>mV$UBXk*XOcw`aj zc}~f+I}p(~z$c2oaCXf)>J}HirXOGS&LUg!M6t8N;B;!t*e=sMejIP>J&CW(eT{GK zD2IfiVz0NcJXdJ{-VMDBj_dwF{gR-um21g+TJSZ8Ltj|iy4=ld(zvO=5pBF(8X8ai z!@$O*ox+OZ(-pfkqGhIGknCjz<-5RgiGI;;Ofkc}pZ_gMA2cO&$|?1iajnd6>Lhjf zW5RhygIx=SY)5rfQ+SYYt1pO;cwx{O43z5aMfWvp=5k7 zY1UlG%9BxO$isF5E!6?_cTgneHabkX5!ES`O&nUo20FXs`Q#4%urb4c0v*RaI{=5| zxdK8R&98E%)g9Vq5UY$IZ5){20wJ2R<5Gc@a|WmG$QO;Ow2pZbV+>aHJ?KKBTyqs> zMu`|z!8hQrfN%6$Qh+tt!W-aDG;b!)eQ2o32U;*QMa1f?uB1t6dy>=r3BK{nogF1nDnaK`lBNk>LEHl#)lkPy$lT2vs5*-3f2l7&A6dPD~=Uumm) zVB!zu`QfA@nHdY9eCGY!tv|fwg$$R<1W}Sdgqm4t6Aq8lb8h0f%wak>h2d_#8{H8) zo^UvF?RRAZZGSX)hy^Bj^ysJ^g0>In^;}Mba(?1LYbT8O%%V=gR4E5a8b1fu?D9#5kFCoI_Mq!IikXj2AH{Ww?eq<3B&J$vNcC zzB0xP2@!qbL9^vp zw`sCB=JdUXi1fWlmv?M_{}p&iiaILY0-a)>JKs+TSL-D~g{#48Z-hXG?9fE-4Bx;$ zu?oP1(FdYirFH&FyL zUl93;6fBicrPJo>KS=m2G7oE3y20`>y2YkLr(>n7HlX5s>;Aaj(V_sz`i%6a3WJwY zudvW$;VYcZUIbR0vJuS~Lu8|XA~5KdBBuY^=(ep^z+(J*BX+4~@9ggUu{Rf&r^o+> z*hjT^|DWj^>tDS0{{>z9v(^8v&4a9e4h8&|?fyTP|NlYP{vIp)H`5BtoWEy1{-&$H zp|z2;)&l>Vl?mI^Oo{R)qCCtr>oG{xuyn{}=Cp?CnHQ#6Y5e} zN3-?R&?z)g7l}+qP}9^L3Uwr%d%wsCXj-22Rb zYUb9NQ_s0CH-1(7)vnK4>x-(ZBZ{4wwKjbG3vXAYtK!J-&T;YRV`D^=rHT8B!iZ}} zdNo@aK74QI(Q63ZI>JOk4@|S4(QSHTJbH?L$;V-bVe78Rg=VK8ioTx+%`JDI)<4JFC=n`3V)_2Y#yUFqYTQC zBy6U{4WvNDQq8RLccRFq6WZ?~C>otf4SBiqM@Q#_FUE{#z`K$n473*eHS9wWUwo_> zlWeALXEha-q%&vcQi}M(n8~|JsfqUN!`C!1bTM#)Qy?g?WVF_?4k7ss3>b<-&Mf46 zIbtc0?}BjFI5CQ>RDfOaf|z=&GViCUvW<@C$;s zSN{2lc{67Xa$Ha1{8dm8vz(hn@0o*8((a!!i9+yRvdSMN7c>heZ(s+c{?||#IE*qp z238r#UTbG1uB(YacQf!JjFWPWDniDal)la!3#kGIx)wpl1*egs>LtfaCr0qn=|8b* z0NSdaRp*(`qNpUO21Rnp%P8pYrUlWmt-!TgvqT&+;A69=fwjUOFx!c$(F4XCL03H8 z6B7u^xgdGn^a?it>SGS7Xhij32IOOg@7#`N^-$o5@~zt?*4_!Vscr~|BUtbqVNSos z=%Z6vLZMuN-k1qfvT#HTAz^sQTQ1qBF_(Z&zJv8ftu?-Axbz_p3Jw5aILU$I8vXG+ zo0L<2ncg%4_Ae>3Ca#251}R)cMGuKUH&SCQ^~Kk8bXS^_w6xg5<#Jz3a5UQ(Q0~AX zyQGwquN~)k7_;mb+ATci{0UORGXu31jkALb#d5u7?3)NN_l{x5r5K>+TD{O8ko$_& z{JUd>MX*_$xS0tPMWW&w>iZyrblLu9BP;4}@(lht_J$CLB}T&><|rQi+I?jG@(qGN z7puoXtML3eCD<<|gC>ck&N5vxf3{%2ae1>|0V)%2|BSC;MI<~c7y9Ly|Y z(mMwOm)Y+ir1|~f=oLo5Q0q1R{PN-pf}f~fh;C}^IDhMeS+75N(6kk66Gprf5x&q( zu79vAaI_xTBdd$obEgE8f^PffEW3;pbkE*+WS3URsu(NDf4o}bZ50&&#=etuDzGU8 z=#uYJkULtoU-1qknc>Z|j2&8zO#3Dgt3v%_;=$g8Ub1J|O?%S=CttZFh$dM+LQVN> zDn!gkn>?TC`qapmL=pcS!?4`R-OPmJIHpm=$DbWyoJh4AAzf*^rGf@B@*>zO7!=DQ zV=K!JysI9-yB4(cH1&c^1cdJL%Es8+d>}CjghvL&6_LjEjdo(Ad)eyXq0c0<#*krN z4#zoMi|b;h5WMuFve}~JbMA!p`M&R)4U|DP6jic5NOC!xvxNpWOGw)$@s(35%?ORJYz+2xxN4u@K0ZVnwDWf z6iHti~npKuh1@$0i6hUlv_b0)fQ=)jlPZiGpI+ZhFMuBt!is z$4@gp!CNa|{I*=Y^-~|XPhDh7KK-f-C{su0Q49ouYvd{Q_@#?s8Wmb@ut3+Cl5X3f z_%WtI65UQfObJ({>~>vqo}q)pGY-EK(Uf#EYp6n$OC;@(M+k6Jq!tnfD`i@Amf?1f zb=BsIXcYrewoL1lLNOsc9;>=DPbt``z*KX_U=T8?N^56v^ih;+j&oq;-5}6H=<-0>{bWL}ATseiE{Rs$bM)xsb6?_1!bM2IXrpGXr_& z3Y3fokWi6|>YjYSOd+xb>u_dCDY-ln8Y2Q{b@{0Dq@;F+$?wz3%k>``j+%^ZeyD7} z*sI7^#oCT^_U!5c5hTGwfr|?jH=Be436EDmtNRO-E$Imn*yZZ9SCcff^-S9=;iJVk zIdOZkfbgw*r9LV%5NFGvXQKCtYP%6iP8%Agk!$IDOfg%D4rl#`*u*s$lN38WY#qq5 z03ciywVw>J{uyP0h3dY-16{ZDgp5!Y2_WFci-y(~^?0d>5xulgvx56{x9GKPde6+* znP}9g&kOtXZB1r-yLQHG?Dl<6ZeZ;8qY$kq@{tLBXM$jb^n7bPIs+OiSJWMOYmTU^ zBg(4JpGc_;rh*j&M}*nlo5xDqg)J*m-4`TNYO>kMeGJQD)Vgi zVKjOP31vV;tX9QkK+Apha=RbJpD2qw?mst~gf(iUcXFYZyQWr98o8fpE2en%OrLZ$6
      =&TeyAc`fPCkE-znv~;Smi_Bf5Vw6=ETx%+k*LMMs+@?eRGl ztYe2J`i1wB!fBXfLstUru8sMblKK8;257R@n6+&V?5=R}Yun}QhF8jiS3mc-;5l~| zK!z2LmG5lD{j+6l;}c}&nE21X7&87#hZ6HYIh2_HTMngv+6n*d@&EZD(u$_FO+=*HiIYTKQT2Y7-S|$dXw`oG{*7#7l z0)zdjqo(m^o@nn#T`s0nePwj9%K3+&XRn+YSEMDGb~KBeayhNjob+nsp9?IW?=+ea zs@BRV;Sawp>~D(I?>#(|`$a?X^T}<%9uDf-Sa!v=u;|r=_D;+p#jtHefYz3?#|8Gz zUr|AW@hh;)jD{mGA3HrUX3rtW7I)ocznuwdG25AmW(xhV%2_ldARs#jYGGMmG8)p& z5+hWRv2J59KJ!2poa=k7{E-iQ;;uN64?py=euiZV8GWcU#GR*P8RGX_Fg(qk)rH7m zQ|o^H9y67VmS`3;n`Ll2V!V%>nEKCd5f3u9S4(E4!`>>7;`D*4x@@T0n0(q7c2r6O`L4JHaPA^ z@4qAXXYFkk7jpH$5%Gr~ZIF9t#p4Y!i<-TwW2=eY4*OKNa0~eBqe1&UPIxK6r-1Qj0`4{8oWj^`GI7& zhd1`R)9&Vc<~(=CwR{VEnWUe;mM5t{TB=DS7+{OJq3^3;03_qE_ohcb>6sNc`t=fn zRuqrEkc+?P+3CEsAZEHxA;2EDq*c5Rjy3AXa>RU8-7r(=F1k#2eBLOd%nWv*d{}Ve zcZ;v_g)|h|$Eba1*gG^=N?t*_A4A-r^K&SB-B%%sEF9bDG z?|Y_5TV6w7V1kTMNL>?8CJ*zYM|X-(e${^>jf&4w0@Mo?R`$cmn+~nNx6BU@GF^~h zup&;ZUdr5(T;?>Rkk>mrOly<+*C#CqC^x3=dlg6If?|SC+Xg|`v^t^0;I8>>4!JUvf)Mu(FI@vON%sQgHPYZhR*m(gkMYn@L z#e=6RS!AHVpVS^kHQaB3J+NY^Zhb%j@u6k-$rnW>k+Fy2HPOtV0i|M@Y?tKFy%!aB z=~7ccf2>a~_)U)J9oGfjxQ#ogWv(5nu2_9pwKq)g84@I!3DK#;1}d&{Nz}!B)3wOCRtI=|uxJ{Qe<-2A z0?KK11;J~MxS1zh_0pNEeKp)+{gzYH3rE1VwFT%m&ksWajOumj?PGB@G>h6_a;*$u zN*zC64UFd(;hYAxI{6ylW){G?pG!fW_DexL?~U*d9qED`#jT5`;3h9u%@xxOxYMMV zsxz;L5%}<eyF(WowzCkEM+SkSMBg;bOAuP-^ z%IebWG{2men*%`rj>qcGCS5Hu3+hu@YKvNwYCd9O8=WslDQ2!K>n{*2|HKC%PcQ@* z|L&**J;E|&L?vc#@5IA`7hH-wOlp0+s^N=jba+e>E4lx3J_VSF+EH&3{5DZ{e!!NA z6bzVN+>OGM_R#TJfvd2<8H1hzX! ITMC2~xRim)@0LQX8?y5QGC}meuB>dI3x( z1nz&rM6}*VkMn06ZIY2&fhfCwu{02`M zM2_$s$h8is^zg98)|rXSTz~3G09-+-DqQHdAYs>McL@$bU!UiJrelk#Jyo5Zh+Y1? zlS4<%ZIPfdIjwMzcu0{&ur5JKSrC>gy8}>8EHrkqB#gYJ3>&-bF4(0=W@Kh`$f(L6 z!3o6h+Y*SrSB?j*lr)6{{hx2D7%7Gb+|QsGf~mUKEg{M^4#J_9nJXd)L?)O7=6JhN zWeVY7)V+A#%%>X$!XT;Ya-=nP7#(*QztP##0UZ*wde(s4gBL%mrr4;?wN677b6!5d zHDS`$NDS%-?j|hz`ROJ>kK~79GGs#Kw&!^bENrW$CPlvFzNy zUfzDcsj*K@q3wkzS4dwV&;FzrKL&a!hxQHO;AST{x)S)Z82?ayNRF6DsMKR;XXUso)Y)&$Ql{CxSf9;K^& zoZ9sc{F|47xVoV}s-YG0=mB&3;lc2?dHGCVxfkSnAX+TdBCrISnmW^wb_WF?bp!29Y^1;A_uFfS=hb>j7LW{m$?#sbMH zv6U4}(6pP9tNeJJi8@o1)XTMP?$WzGH(}n4b`|2>t9?~4cMIF&NY+!CR7zQ#jt3a1oq5Boda%rN0z2p# zVml-%? z30j;O_dCX~)*j_llKs-{`4}0r&e23mZ&X@tgfx@r#t$&?NX#ULVs751cULqrE>%M3 z4nkNDK1R*emjcJGIHZEUYf8d1H^*F!!R#{MmL?}%A%(+id!P{_3xcj9|;4dA_9wZ759+)W#-k?;je$>MhP>Iz&D!@>n&Dji zq-n8uS&1C;N6-#kD0esZ-QiA|hI4Bin|P9_%$1`@=kG^Q12Vob{4%H6XDxNaWFW_m z5k&7xmA~RZcZ;!wq4cyD5UESM&(f`{l^AGwT z=KoeI)<4gBe~}#h4+bXxWxo5%xc1-oiLm@Doe%5RfckGN0?UF#>e=Vxf^5gqxC*gvDZ7PhEPZ0p-s{&9Zx9 zlC6%_+SSdiN;wVh!mfE=d%ZI|Kg+K)KH70g14^b72oWJ2nqc2uUyX0mDcTM%i%NOb zNfOR4Q*Z0eA?5(*@piABW{Wj#O2>;Ib7-JUvMqOT$z6pO`p3Y^u}P((WIP#z^#O2I znjd++4cjJ&Zd!{fuZ|TD$NKu71p(*FyFf%^KVyD92KNV;n_@P)m1{Nv{SsUye898T zK~FkvX=nnJ{R+OFfp-FN?d}qtL!^FAMbyvDNd6ef8fOXx+XZa)FpT(Xo}T-L_~Nlf z9$UzqrKPEnji`5=Prd8on5uR-YL5M`J~Xn{#am)n^V?rok6U7S-1_>n5zyC4&-cTZ z-~0Jv%1v!Q##NkiE&-mBO!DAngRzN?q+7frHn}S%A=Htp@jDyuXpT2E!Xp*7mqCnR z{ODDMruNHtl#uR*CgJj;iV}cgI(LutPS3h*I0E!pF^9Qr5Zj`m!P=`+iQjcS1ZPK$ zS-2K>dwK_=G*}OTK>e`q$G&Bl^0xxrcyjf03>MIs3CkEUS;7jTsTd}vAI`3xRT-ILp_FvDF?h80NM*BTo7 zyqi`WV*)TL)DCOo@bZlVv;z{Cu6TFG7)B{)QK=r$OdgaP$V`=3R}GY!Qa{Y~^Tf;7 zHT;_$+2^$Ypn>r~*Y>m&a0WR)zd&bBkS_MUsibdQR)c7K!%J7haq(}Tt z8qSRhyx(HNq0IL^d2^h`AvJe?1kxi(&FUV+IJ3*W-yqhc3J<_Z)a*pV3)*%~fej4IJx zY=mNzE9tgyH3<~%0VL|IY&Y;wom=pwu7vSJvbs)5rsCzpQ*e|0skG0q27Z85W^Nh) ze+p2ph6$VXAKQ`VZXBK!@3~<^oA+CIrxWvegF1(%_QvCK;|op7A_)cDSPk6)|LTvk3!>e%EN|4 zXg51DO+#;Ak2J3l7)ht~d7FTNhy2tRm z<=g9T>=!Z!2dNdFlgai1pkx`HhnVSA+moRn74;^U^t@KNX;79d)WwswhX+hZ5sQxW~|qJy?k@>qA=Go?T~0-bNTXm|ye^sR4#q+m{(& zyv?cR{2dtSfPfqF652B=;EYP0Osqia@`I)CqF=KvXwznG@S)Gf$z`4l^1%DohO?aw z)yaTkNmmoW|Py-7chv@V>3{ApvM6Z_mbBbJ7`!*|3&b=cm zbhADat;AtS;Fw;o{1to}rY*6Wx-k3P>l{ok9;{3`+JLX@=W6?3GRi^8Z^3FHgbA0VRS8tUUl(GI zh~~E$Y^wvon`EtJ$+KtOKaXNc%C1Kj+Wpv_QOX)`7>>=>u^>4)ua{@JT{ejEi<`rh z-y~w1dgg7kP^mjw`96I%HxsbUUG~l9`Z{L1+%i%(CLf?zTfHcG+D6-z0OP*ig5RFH zsoo!1VCg#DR}}AVG-!w8eSDBlg;xgMLsO9>h29f+15yBSyaNI@r5(@A@Vzq`u%$g1 z12t)B>kc_3l=TrJFT%aNLf~(Vwp>+hk`{pD`DExVC0ki%ub5ZbW_&qM~25us*j_vF^FwvS3`@BuxBI1ipy`zwKf z_?QjPgbKJy9(1xv({IbGthPMTp+)4fhgbHfMS|x+Ju;W?Z^5V&J1ZdJqk$ui_r~fn zXG0gu1`~)5Fr({!9qn=Yl9TuwgfYlRKo^cco|C*dCJKrgx*Kfzf!QE_Qgwc=j1}0W z{%i_##k5oDq^x>7vTPyatJg9hde;y9|EbRRRf1eK?;h2AoScV z2?X|ckv`igN@t^rPSBli4x!^2*?jP#^Apz+5$yDCf8q|!D5bFJQJn-=7UN1Pq>S-O zw7!Q>T}r+lwjqrpaPTosU8X(f-=bN0X6BtN{G_jn1;?UfW|>2C1H$BSY3{=MWg~kL z8l`bG+fSj>JqhCH`e7R?)HNQ`hH$YFiUxzG-LQS9);%Vu(JE32>pY>DB6{O8&k@VaNy?tO4@s5>Cx@t>ItsWQB zwW;mb2+{W=y~Jf`;h)bw5cJKU`3U|EG}24)RD+|Wvh=}a+2Sl$yc^liqfteHh!T?i zMbT2{*`MJ;-~G@nnMU(GO{IP#K9GFfz4m`mN1~FHIz)%Y#Wz0o*ru?kdF@(D2yBg|h34Hyy-Uj#pWeQV&*)RU7%k96^f&C3*{{h=s{{QK~ z{`UC){E6nT*#6f9+y9$v|F7wCf4|-Qdsmr%r4?gg`M1fwLPNvhi|oIGxpGtHM>U|O ze771@+)~pt%@Rs0lu2c8Vr3R)(X1GxkYNzNDh=i!yQON+t`EYRp&Z#>o?4O1zpM3} z#NhJ+yq+#tp;eDhE)391r28#uC2QsTB`YtS%X}(KTyHPi_HHQ&Nk zg4xt1!NsnzBip0(R^2IGrP~>H-QaFqOgCL5J`5M!RqAD+vSoIUPf3yvr)xKv^7eIP zez^Re6aO+5WqHxVvpI9GYD^JJ=w}4>Pf8<@3u3pzBe-c?!oeuDa`~0m$kpOwe6yar z4sSPc8{y}G9wtFCAnL#i?`Q*FTMe);6SEJ>k%-fydWwu`chXvnNz$;vFC>~w{M?2XV3YzxjP7)A#3 zM+D{i?$UxI%_cHorou7sW`lF|W%uOFIgN)r?7@NqH*M#eW8OhO6_&6{@3qxn4k6?%#$98Jh5 zPQ@f|<$sKQ0{aYHqYzM?1rU)+^}YC#eoUg;Gbc2eY!8-KXnq&TvL`>J{Wbk;;&yM2 z+dKg}1^?ZmwnBT2xS4*aff)KhyVO1vsu05VxZ}b9zCw@H099xxjU*^BAP}artg%7v zkA_uoL+EbL`ZUR`9X*gar_NjnM9Vc&vFc0{O*m@XM|2A2<>M(czO+9H9=RvmveiHseX+$ce*o&NZ@5>g1Z*)0zl;{*y@5i-3W|kjd zMIi(@bZ77`4j=WN7%t+_TU=_M8+b?oU`dfg$zHLcB;ROncKv}$gqd3{nX%UwMdB#w z#HDikdNX2$wvln=+!g`?{G1y*2gqXr4y3$+c3tqer31Kg;(T`3xZZBv)tzzb%PPI@MDE_UaaX{_|lxr5x^kI1RGJ`9DsgejVF2}5@8 z*Pzkc@kf#ombs$lb0Iw0m^z`iw*aymHF7#xpe9O>BUiv$2%ztfj@Es|h>f=ErHA<% zPk;gY!B^a0U9NFQr{fo|*mau#(_cxU)X*dV0&@@x;T@w~X^c}bYj8W{pLA)jwUZfU zV#t6vYucG0@9t2so(?8>5U@1SzCR~xYE=;A-vvl&H0KKSmho)J;ULQk@m`u?#5)C< zuvoR@XpUgJk<(;U_Rep<$ruvNo*uTqZ#ZdR+AxjicFLrBoU=9z59a8&yk=Xiy)U5U zgf84}5=w72egs^1*%6a7Jh6lvaH}r5Z-D~cmakt{s1}Ha~T&o!o&`7 zRXC>WoF*~`2H#*tJvqgGbJlVUn_3s`tA*UWwFg@Z?l2wWkpwZP+D)O&p+!(6qSt9? z5@Wis3(kp?6qiQA7NOL|zlD%T%2|Ve?sc5!-Xd%+AC8!PprP{|&0vIF1*;;ew8sk& zZrZdnvz3F0)5%-HP0`Fa7-^vSnntG2fklHo#Bcwfi=(%zUU^x zhA1S(x@pC`-L`dtZ8To`0_}ts!B+fam?S8^NU@HG@{FhRWh3 z1tD|2a&W*V$qpE#*Ub5u%oFYMBLd!wVIv!3yXQbW(3irhdd=rf44{ zH*{}HXYdUS%7oe4*}n}x?PnuuS1+;t(Nm&Hj{wYtk2FE0gYU)8ESdVPI>{1!Z#`p*TOmMajU>FpYSlVJL+BCfn%t;zq=OU*?HN?x&L?EktpQsH%c zM`eG6-RAyXSQW&Rj0PHDch2sM5fnktF4-99C=gTl?4q#>UdzFfGv|{@sE21irP~J! zUw=S~;T@RI4Rp}#&$o^dNo@-oEc^B+Krl=MWy*i9;HX!%?)3MwYv^hcBx05|z*$BY zC96xd?aePdXN^8|(dU+Q$};xOMwvA93^lO`wDfzgIspG74j(U1lPr?ZWR2B_C^ZIE z2SE&-W=hxFy2scGr6oB0;-&>$&twp%1JuYBOdYOc-k@mMlJ|52c}+rSYBqVAoc8C%muwSm?D9@XVo&N!Y>4tZJqKJA-Y*mLI)~i+4_5C4KZG#wYBG8YINea}Yc$fB2Pi3w*H@mq2n%4?b z4>4bhF30tBzKqGLvZ@wM{xHRKPL2?ZMpmb_x{3zwfiEF!tynd!bW_dTYUyJP-|;-J zL1p6wqF#A7`qS6d+quA;9)K_5T~fxeMM?A-xgLjZ&p`iS_qgo?EUSt6FZlbvlt{7s zlSJwZH2)j@r!4L6ERXZ{*{RxG-1$#G<@vSXWl9j^apYL`9zK4>5yXkad@Tw zx(0};;;sW~-i1eu1;88j>xJMJ_=4fhmM72F!{X^nd;*Cp-nvAE=C33 zmVLZKd$%~04G9-r`!K)TP!-%F_*~q*it#)~Y-731aN5)9E0CO#*)~-op4!McZbPGn zshepbGXyvIwABLhH!>pbRON@PU%p0@65Y$Td931G z98OI$_Jd8WTc&3t7wu%G{rqSJ9}Pa-NU1d6AO6q#fpiWF-q1cU6X(Wvl~(~3 zbM7FrqX?^0m}8Ep#iEU-<2V`TnGkSb@9uUI*0>S&!9Rx_m#2(sH03dcw=K3I<@lNn zwTVrPae3z#bCZ$Is!)+_od8L(F@{A#1g3YH{h5m=={5yZ4L)aEHHwrgneq7LUCvYz z*BK*kyfxpgYfceVaj+eeI6l#hjQRL;_)vu)z3$`;`4C%;=)`TR|RpK!3K$V|DW)+r4lb6ppXj?FVf zyyi_Ahj52DmgA}&-Oe&vpTH~jGmZxIOy6GauH}s(ab&TBY&)V#cJ=4xVALgXJ8bq%FuA*^j=^m&$YkC*k57J>4nBTlg*IJ)KdyS?YQMB1M2Va9f(V=6=A_X%>BBvsrk*#UEb_Od~%NPA2jic+4P4&_5KVY`_<=-juI}34Gg>+j7d0KAvskF z?ijcuSI8}@~fLyO`t|vTMcn!bHZNv&^wd*+v94n0z6A_?NPNa z(+|#(J!9SjtUt5h>FU<^8BjfEdcbDd4FmSvQ3;s$cVfG@C23S51}3)1 z$qLCe4CR4%5yAsvf9#FQyAJ9L7X)6K3&M*2EPBZ$Ob1RV{1k@zZOq=AYH9}9{snGe zNXgAL`ysBy3lfO7Ac=U+ke@lidrpaeVVOG^dfn_M;5_!yDv}cD*U1<+vo#P7BZ!JD zo>@xUVFW@XBw2+>0rc)=k;-7rGN)A67;FL5bF`N&p!VRHNcPFDr(w)= z&*2UtHgmu$|FAgJ6aS&j3Y)ji6l{mhc!V;+6~*BwGKrhIaW zeRlDyNPP*1sB9rf#4r2R1ezp=`MY|G(S$yRx^?w6nYEptb(cc}+AEijm&iMs+3BI) zZJniYCfW?T?@Oc{enTf)Ub}?GTdMy9^ez)Hp0IT2iYXru&XJ!xK zbYT<&fr%<-ho-(584Ngq;-u0FJPO7jEVUkxEE3dV3gsLrBG-E!F%FN{k18rBBXOR% z**^*@HcyIqDkpI`d<7PnOS7`E>xa`?k?KY^A=IbeX;;V(#t+9VVXaN!?YxE9t~?Hx7_r@f60JXpK);qksw~2LLHCm7QCr+U6~>b3=l5RC$Dr3BS(*1Vq-E&% z$WF_s$>X;{dZ6EwNG6zYy8lp^H$pQN=jzpWW1B6ASs0cDeNhZ0<}@o21<6^XR5vp3 zGk)@FlHj=Hk#Fym3u>)d3WMeeN#?B+C~<~}xg4v1xrK>@&x)z|1K#D6XZOivC^d}y z+pc^7ms3NXWK52RJ)bVLS1|RUa4L=-hfj>Cfed&)k%`FrOzb+ChNf*bk{ZFw;j@lq z{*d*%D?5d6zdMWDg%T=FIzBSgVVf&{?2kCA^4H+!!jClqXd(ZsnoLg}=qPox=!Ei5 z_iK+B^?t%5$*_lY`}2^x(-;`GV5CGo(Ap(_kHm3b=W;VMj{*5!^dIe$1#}=c`>lbU z(n0|l`o}Y5d@S20_;UQa|xG(D}zj z?0-u?@y{Um|3*LYf6>bS74iN75Wl)Vz69-GMEf6EoPXEHf4%r>|6u)F#OT*2f2YNN zYemcYSFZj)AuG&ZO(XxN_@d%JsPIdC@kNE=CSvs01VF1v0lynMWZgQn+7g5)WeeF! zO#4%b8c0|+o*ymR#bb9O3&QA#pg^L$AD86YTeSwt5a~8_yIh}j`>9%5J9S7&M6|<` z#3^>bswyKEx`;B%KfT@`F>BU<$_8MVIz0Qp1Tt$Df{{p|>rNByA%-OIyyn-=eny7s z%7KN0LsFUorcU91%v2pbqQ31M{l;E%YH;q`8a(L39nGcH{FmjR)|ND$Kmdn9h;2iOnNj?(mQ4YxgDjEe{Q6`Ew8QGx6v#4UHU3b z*XS@&QB;`uOHuwy@mW9){>u4$OTC$V59llzecMLcM3MeY=6za8fspjo0#VW%ZIiKB z2Wtq_vk?3XfmWn`d3dDNc1c}y!bhO{K6sdYmgv+h_ocjC*-tbhJ>Q6c7&%7iP#?+? zGh+A1O9>q&nnX~v>+ziM60sshBRWGO(vA{DWQ=4qJkOCbf%^oP%W?q@l})4QY`%g^ zXv*2EEjf-uG-68?%d2n6g=@iE{vOlL8=SA1?zRkDgFuyKlmF1Ulbq&vyX~r?lk)`I zeyHX9K<1HSnc*WD3<=fTnK$27%`PhAt2&-8TX zQkcFJ^C6ggG`QPoroc%g2e*z=fkVq2I##`=@%<3rxtkTvAmDrwQ2+7$jA6yv_QwDF z>d<*^DIRR8L()QG*-PLx@STKow#B=(9g}O5I_dNgDuwPpN z=&%s^vRebLrMjMH9;s3!P~P8n0)C2J<6R$v>iqOj4q*;rCVOT|S}v{RsBby3D$X=y z+BbMPoVAog6gyYAs4pt=89y11ZtWPAsu*84zL=cU#2YKzjB_7wD{b?tt9d5)Ev^BI za(Qrt{-BIi^OLTrk#+unPbnL6D1vGUI zG-E%&Ew!XC0ABW%C|1hp8I;WD`76nMo9^ z_X!MNx5?JK>p|MMQhC!1eUE+!K|pW|cBLeS5YA*rG5F+XB55v7EEE3OZ=?opJ|Az)i0T+`qr<|2lxnTDu#7LfJxNdE6bSA z^JLYRdtb|?#E8Xnh}ucY!ZOJEB5OrbdCexJcPSx`~>c1SKt5DL-o}J zLHM@Y@cV9PWQ#p-WhOe5Bpbqd7>&PKL}(a#m!#0aGFTV|>J6L;P7{nt00j&imG=Z0 zKM0|oV0nEnOd-xJNY)KZ#=JMnFK)C|-Uq@?zvO;Z4HWKoEeXZEDeu9IGX-V*|v!`@euXFD4nC+haR%D0^ZzAp4=9wX`|fTt4gHM9sX(EWtZ_miOU zQ5m~H(rq!I3Y>|p;z`q4p~KMJ062^_pPX?gxyE7ti|sg@3hAY=>>hFWOk*jsg?0Jw zznCVNcWFXo7;pI)CYyiYyR>J`WZuE>X*-{PkW@^#6x`o%&6d8NPqp?~+%M<>)DS;` z=0dK{_Bc{UrDR_w>Y1lFLNb3Sz!J`%$;M{2uDhnW&kxW;geujR@KG>P5Lc`M^ zxV*#`4ZQ{)V)^XFD#TiB*_)Gv^sz>Q(xWDnZI1oc=SH+U41KS&na$dl0ojdL4VKoN!h%%F8G?C5+SRZ`79n?iT#fv~^(pa{?Pd0+@c+@wa#x%8H6Pp$CyakVz<;f~`j-mgzd_wU5HRci4ypO~ z5(NK=fdBUR|NJWSF9gi+SGxUs|JPTV;9n91|BA+c=iGm^lyZEr@ZUDU|G~olUlH%u zcbEuR|I<+V^*##$>)%F#|M(6&!B-^xe^NCED*@YoBcPD&UkR6)zxL4oCObD^kHxRE zUR+ciDK-9JnLsXi+^`zjb*0LXbTgw0aYg(UF;^i>#N|Hj`r!=>k~n{|;kLYzzz+l_ zup>dKey-Yc@?OTqR#jO!r=L_|W206xDiU8<#*8SEw|DYK`@J!FWWdMfTMMkLs}Z|~MMfKz-}rNve+B}dJ~19QI> z!8E;4Fe_u)9Rd=DrSqWi#m1K9V&RI{4zjIEb1E*!0)g~85I2%u0-hpZ#!5x#wPAry zaU;X$jqQYmK)2v@Nf>Mq?<6^aoS%R=%}154D!85{m5wGbZ?SAWtF-{i3}($w>yp+; z(72)e3pFj}j}r=&JlD$64(E^oF=bU9y@dwaqWr!In_jqRwq!fFIDIV}>p690F4)D^ z#VA%UF=CG~b@`ASIRU&_Z2jpYZ(FGYz$%w&4vDadd4gMYyxpC>^iYZ@QPi)hJ4{}v zF48M1Y|y;`isa>S(k5!lQ5`v{F6k<{IdqV3w^}hYw4Vo1e)LGvna+j0pa)B{_I-plb4ZZ zJWzp5bv1t#g>^DG;Y4W)>0(TE7xqMvs&6NB^goOL7jtg`RN0oL>*DT^xVyW%ySux) zyC?3DxVt3ou8F(5ySpZK>C@e}PQ5xERquAc7ndM{9gDr@Vzc)e^PB(t#~3J>4}w)$ zIu7E{^b=|L%Ci{&4(33@-wsf5a3}Tv@C~XWK1aQxps3h5$uyF9?(d& z@@K2yTxx@d-4b&s3%Cf20o{!qf7(&bC`oOg*#2(HZAg$z`333NGy`H3;cO8PgA3t2 zfqEgcEoSyO=iQ;hU zH~qdb#mB97Cm%tM$08;autL>u=Q6eJA#u6jO|r>QJSZo49UZr&W1n&&^sc9!yJGI!#vJ=g3d`_WV% z%{!9aYq1KW7suM%NW0oiX(g)zULMnj!Pi9M-7?R_9EvHM>)YZFTbWbee0B(mz@JV9f41oHFKu6kljrJ1*Aw9wCz33t#efx8X=|&2S!+x*nKi zedoPaDh^`Mz#Ib&)j}c7V*pai{>`1xQIB9qR>Z-Gktmu5d^aLHZh2I`euuq0xrYX% z&6Y}hK6zl9x91l@746Y&QOcLwvYImJ&0)zwnNZi2c4oXPgSk1?t2 z0ldC4G+`7+)*p2UFg5&I3KMwSj>{H6U{x<*seKT3u-ORB-`7!u$PrT(a>ZLs=!mnA zJ`00VdhyA%6a&5v!|@wxS5+rSaW8t@x=St`1exj294;9l%N{z5X^nKSSN+SAkU*mG zRT~Ah0@11hzB$bn^-0m-SexX1LYZ5;@X47F#=t%%oxT=h+@(Qg*lu3ok|bqDC$#nT z_pW^B%;<0qt)~IJ4!7GECJ{qqQb0YcA!MdVNx)8L_7}6>le%pzJT3d4k3;DrX(zcl z<2UzYYZtS#cDspZPmhmfRi6t?2U=xL&e7#!(EzT)n4Uo1?ID9&qEs*Vh&lRD*Z1ra zjo%4!Tso;WX1V3RdmoUPodaO?%za;>Mv(^0P{WBOV;HAq-epPe#?qor+9J)#;1L>d z@u8?M+0kqu$J%-l&;x=N`}st8r>~zImLUmStxrsA#C^c?-xz7JrpjpHZDfre*(m~Y z4kDP~1rtdiTt#?}te^T`s$uwK&6<4?l87=GN-kEU*>`D zD@XmpqU*!TCeE14@;MyLpYslVh()+lJX$Ru)rpAZLN2)4h|ZwxZEMw@w$X`k-YWS< zodXTYV%@YFbA^3Uks={nH8>P`JcGt*pOB1oRPCLa(L8AX3+|n0j@qzZ9i+a3KDD_f z8mhW=N;XLVzmOAdZR`MA4h2w--ET(%jYA%k@JH@v)PeGvyZ}x3#}e?ak)~-{oTD`D zvWwuo!FG$&j$7~EK<-P*v;+>zS&3cp>Dm^RKwFe4TCfbZ=-DbN$)FMTAVL~#E5Yy3 zK9rK!AKR)c%4m7pur_KNCpq$iKg523*DHov*_ZuFYCHjx%@Hmr6-lrPMG(=!WX(?P zIT#U<9e8%NpSF)?TpQ&X7)&TnCv{XXq6U&Vx17bO}21%@<)AU5_SqTB8 z9k0z~ROI%$kM>ao3cgRh+~;ZDUn(B-V=7x4ZmsrL%~Nh%)#?i^0JnhR0=%{r>i;6UwoUXk>j zQ78c!o~zeZMskUbFKZ`cr+es}jl0&h9OBcSent1h^Hdo@bX zfe(<`v);vp$DN-Tzw?_b*||GPw|^F}A+)r8+ya;~g2W<5r>xx!sJw8o0M&yt4!|3u zxs%vJD6M6Y&ECoXoKz8$7b!ksdo=Fo8Ieh9tUa(lb%fkgfK&S9gkAEa?wts5={R0L6j=0(WUzvaZfw=!T{r>{u z{&WAQ|0&J+%W3?->ygv_r{>JU%=)i#^B6XWg$`j7^1 zu<*Zm{vsldPTIpp9GSWAhHdvtX=?tAOn~t9t{wTRG1sS?{R?(VJ<+)T=u&yrjV-Wb zt^P!ABK!9SS5;FnI;WN|%L1@WlWo%qeDF=qKCuz1@II#@<${1{;w43%@F)^ZAKF9! z`qJQ|Y4>inFm?Q`$hep#7atlq)585lGX8 z#(T;kx$h@GvQDmGDWR8MUk8zC8%%kg*1Pt!tlmsJOK7|>e^Kfx?%NJ=DPJyQhcapB zk#zP*u$ys8tnVnc$jcWmO;m5*_RRz+5Q|P6JbYk614_!N;Qwwh%uAcMP!GaNsa^HG ztexnABb-^uCXMX)c|LkupEzLg23%EbNSZJ*c4~F&G{9JtT>{kLgwo{Txv@vGD{xI| zk4aoOiHYA}=(u}JjkX9q0-tTC@`585qOCZX3E9%SQq-)ke^4c8HfMOb00G7+YPvL! zKq24smW|6Vp~2WLW*qbsrsYr1^1xXWe|YYXycnr8r@pFUorUEN$!)C7M2g6eb#tYG z91G|t>Vyd}M7gW`*pDIebMuwvZWRyxZ5E5pohcXM=tSGV=WbyBiYM@4eluruS6Jt& zXPL(5?51Iqg184pH|#8EA`BYaIUq_vfGroRXCW!AU!yNELeH2CV_oxkds|`erzs11 zo#)|0mHeZq^r1|NPbhO>9M&lJSEjx{*xYz zie3{k*c^5k$WA{arXR2TSrw{#@W!!V9#cLFT$>xzxa|jM!%@@8Z>nP{>N<3NBRyZ5 zC!v_d^brLx&4-r(+N~s&m6XYReNT_Hf@p}AVRp>-2J=%P594L-qD|+9A5RUyX%xds zxE-0Db~F=HZ~%dzCu_wxlwrbqh{V3f$U*&(Y)U{OZB^@Z@5FOXIJvPj&e#0J5aqNq z*Hr@rVW^wG=Xad=7%MFf7z3Pip=nos=sqMHR*%u$ZtubY($XR9@GfQs#Q-WSuE5Z8 z((LY1H2abw9J%a-YuC7vAJ@F}A~(^vfcBHhh0Eh1m(KPVl8c32?_N9!ZgM@zWKu8i zD-|=Qf^Or3mgiLf9d2Ocb-HmnGi49YivS~7amuAB3AH)ukWtA$!dGetX+RNN1yj@l z1!4BuNg@q(&c)#e-lPE>aR$Q(jW^n-v3gp=Yn;NYMXsllH0X^9wM6hU-*75_cSj~G zAPiwmeM4u!7gWp5mYV;Dux2zsr=Z3g(`K`|QqrH%6u(`k1o5(#&Jq;o9>RLmRFMsT z3;`b3Qwe}WlQ2dD)FSmg?}|G7yF>3nb`%RUVSlsm?2%s7m7)HStH+!#%`^h^np@Rk zF9ph44N<`io>im_|JY9ME*i0`=b+_j2oprC?SUCvifu8*4YtbljHj>T{s*?#=`_Xf zyz;Le+I<08LSfljFHApxX$H$X$$@|?!p6%&624*U&cMa)`R zTQhn09O&MVMcd5Mez0ZvRs%MD#3Zu+$$BwXN7d*oI_|4{PK52c3U1$u`D&k>PqmhP z$UxGAx`Sv3`)W+TJXXe$zAE-rCYp{fJpbnP9r1nt4ux=2VG$lxU)ZVeF}kP%E%3{;*N0MV3FOjhtx#svivD|ePeUg4?+8^3pYJ~Q@BLlOMZR6SGkf&GKc2rRv*q{ z87xOK^V<%8k1c^)4jb2{^)6y>$1I)b99pxHeiS?h{>ei%Y7~+rxlM4GpGKNEblr|& zQ8;#|UV?P{VhaKGX6R;gy2aQ(kwdh64VX)RuFvM7?PTKd0V1=wE{ua`@uo-o9 z49H<{Hua}k?r}ykCwG2QGqW=!UscXHhdfem?M=tfk|QQO3+lYsp4&Ok%HC=`z@p|z zlB>R9Rd1?@C-Dm?HP@n6*P_wjeBv*r&*yZCmf6?iLEdNG4NC~jDFnTEufn^_AFH|5S*q?8<4V5` z(2tg1+kux->R1oWu$&lp!ejWj(QYV(K*^!gUu}YiT?DMIyx2DtJnnuXN`u{Hw``=S zxKP}Zmki}mXXrzW9uZ@GVqn$-eWM48H+CG_1>s+1Rng$~b{{NXRW@a3Wz!ZwN33u7 zd7}P$y`Q1omw(dB*01mEO>nXW7I1k&Myoqw|6rvHJBTbDfG#HcDK6M+2OF=*_#reE zW_^zsyaZU&6(5KB@(KDdz$bvwWin1qexFyU%TGoXLggnt>zE4j){>QrxqJj(hL*oXNYS zIs3`?y?OnKeHE#hhWg*aiWitnI3L~%A1aTm))=X2cCBNgYDwbfFuNpRrF1!8h4ol< zKlIiX`Q_h53*?l=_3WW8wyrkcAUE@kF#ZC_|Lj`$O9}iB#{7FA|L?hh+5V)u|IZcC z_^*8&|CI**XWjeH`u3mG_x>cN|4Swi_CI@S{s!d#a!vOl4Xx@g6Nv9u1r8xR>+MuT z3d#Jyd~;SAS0&~R5yM<^*4JF4xu&+ZmbU%OIlV26N%>}@ev99R@xONBGRN42IMuVh z)a)TNzH{9U?-UTK`c)jYcu5iK1eJskLRH5`t_oirsrnb2rzJE%Ie<%J5|%nUmwe%h z2g~wAdP!uzj+Ie-s70b zx4Dt$eP6e0DgoRkKI0sm+c*2R;;EQY75>_)}>SJt@o2n zI*}#7S=L3U*2i5%Wu)pyIFcU;X7fd`LVGqA8F)4i7;n9OvFEouu-F+D4e%~^?dS_v z4PaD3lES)rwQ;EksIQ4aK8f$WN19c)v>Pfj1pLKcN+Z> za_vteWD%?GU~*$OI3gdDQJmWG7|{19-fnJ}qx2$gI3N}3sr)DuhthY0(XKK6h8FG( zPC4vnj*jo4PL~Za6CLE{-LGw@jDAs3r39Y5ZLh5J4bQ@4axSr~^qxL-NiJ~FSrzOH zu;zvPv|wpg(?_8dJk779-OlsfzREb^#JJ~+t5w}$kKSjwi2n9*&l);1RNB_SxE$6; z;g~~Rj`nkmNY8$cRw>`ur!;mqyUll9r6uk5kKDIq?WwHn9U}UyPOji(JVhy^ z;bp6Y@{@o?(F-amP7|_N7KuQdgd!Q$fMi!5tvde1x)x*j=%AwurZI>g5BOjMj0X!H zf9F0|9Oh~hA}n+#7R-0z9XcE@DzMM&89ImNcOLqVf2GR*CeYW#OHW4uWAP;YmEL`2 zJ%9t`Z|3P6BNjJ5#}Jg!FqtNiVtl#{Vp( zY9jnq@Pu(bP8UoecRmDI1N&#j8af<-c`XM5DKJ9%2<{I+TNug&e-RRd(|U3)_4R70 z-vkf`cfxmtu^^ld`xVd%E@GWd@BCqh000m^V?bc*0jy;~poro!OMxGvZ@wMUCDz0h#k3ZaJ}SVz{fG-Xw%(s%yU@a(_ta z?7wDMEbu>Y4?5~L>Zo2ggc<}su8D&voWjPW)Cg?gKMZwb)U5nsH>p>X$70O5b3t#( z?-uyE2bzrxD(M%1;3zPtm6eI&gDHO2L`&1i-iANrY&*WrsR-QoqDjk~R{EgO z^daI^G|R^0kr}#nv!NB!n-e1o+@sBDaG#;3q1_DM#+ACTy(I)tF>=pY0!`c_E$ckc zb+T(5loditNg;%pINRtnMiHv#+cqG}C5;c@E@JPGM1H>B+wzG>GRx*Tq(_ah4iqDC zUrR16#SEXf>8mnssqqJKrn|O)eG{C@3Bj)YP%05MpOf1MN`UkJffhNJAr0N&V+YQvjBA8~n~d-hAg8+z@jzAVrkysorf7LZmcDIMEZ^&LP} zjA6kNeOJ^B`nH_oBzT=zYL2jr&ych;9Yq!SgFH_1sz~!5TQf_%y4$*oibvw6xp#@% zWmE>1=->N+grA9$#{7111EQ`7$UL;pB!oyG z6ZN{654&tH?9?V&SK(e2`ara&;3GHNrX&ytg#vBRk`PJ7R5u(L_OAdcO1{%IlPlMP zrl{#DHCn?7!>LI%{u(#ce*{918W23tT0QEQ1LN7`)khgyfmEX1uI(k0HsaiI9#%tH z#+4M-FXSod`WRd!`QFia6*(T;gK-(wUizdz3Oo~f`(sJNxCjJ57}ny1Bt@Ujj<1+M z;InZErGJ%cAAzKKV#sY6gbt!NN z`n0>C+>0@pqv}bc%)a#pIif*+ipT4rDiRu=FO{T)=FTyisnT{iiaP()oAq_zO@0kO zFzD=o+ai(${pJk>B1?G2!M>T=I)YvmOmZndhxrmbGTUoS*#!vc^d&oxM@Pk za`Y&ZQCUG0JY(+f-$-jg3}9PrHSR}Dh|zJsVA$}*?o5>eLMT}^RgH=Ii9I`|@redu zxzH7Cxu39`2ayK5_n*@W5UW&GXqD0#a3&hFK?H-pFJfHSc{ZY2Bxox=B zv}Gu+Gic^x<2at6==;zk$GxkX-}$(ma9O$`^arMMeYgckiaHvGH%Dlozm(ANe;Dae z_k8MKz0N_#9YtJ1;1Dv2gpvb#fOZO`vhV~-0z$dto6cWl)4uRh zg&p!(y-e2kn1Ahdbj$ZXZJ3HV(}nsW1GqAGYRJSy4-f)999KZk#}kI4Qnwgalg_HCz2BcXq0!(kpNGXT=mEeMnq;2m0H!t(%R}Rq2mv z`|9~*;QNOIL%=uOvM15w@`Sgii^~B&K>O%Hr@uh)KbfQdx?-}>?Y9E$%Lp#Kcte~0LQbEEugVEyNfgZ}_))~~&Se^u#TP?d_Eqetj^QhNqa zj6_*--Q>aNHxv-}5;zc6NRr81B&-$MrQYz1MdtFMQHj$ey2wi}<9RvEz=$1!um%9i zA;nAn@uCyP50cDrEdleL9K_(f&tJc0yyuA`#*8mnk962Ox5CI@!R*qVJ<#DCI1~XL zQEttzNQT5+$V}FMTDfl4ytTA30V=y*MvE)~vMOadhPpvCF4<(xLj@N{x~kU&wkl$` zxFwsUtBa&7fTSyrq${3e{n-$=ilf^-v|=Cas)j_{kfeKAv3tj-djoT+IS5PrreG%^g4W1Y6zJS7*-m2Hx~l#AEKVvWs?0^PwJxg}9|Ef*{B# zQ@HTy21HFLxW?PGMJ8;SvX3E58f2raL=}T3;i{tDm9Te1s`9VizidCWDo1E8%yBzO zvN27QU2w=g|k4I7}Ds9A3L8=`S_11&wg&B`mq)*eYpOI!%Has+{Yz})o|u6*Jn z-9EM|>{XTWIDk>JeNwB#6>VxA#`SvvBJO+BRhbR?@6~OYZdCtY5lxP}3~U0|a_lK9 zg149S<@af5MQU4eY*#B+Y>p%9b{)=$% zN2bD``=zn};ko)(`=xy?djBn}_iuT+f1Lh5zg6}p-`U^7!M}Fb|Hb|m`UtC2}i&{Jtds2B0<&itqB=Pj)^wkpAPKBs}Eokn)qoC z&7Yr5*}a*HdwFwv-!H2+H+-qh<-uIgj5`QDG(bd>;xg-VZNKvg$rf~vIk zqij2jN-C;oAUMfNW)o)f7T#z*#)&$}TDWVY)s_nEsg*RO!-GJ;YMjTu83=gB;{T2V z6nGr$OW+Q}*xKD>-=^v@G7B2Ohe)X@-Rur%D0EIn-Q`ph@bM4d)OA;cwdPJVLi zJZuz=kZ6s#EUuI{wcRu`bPuJL5gU_ZYFoTd)SMZY2vw4~q!dQ&2$cyJ1&#!B7?9l> zZtEcEwRg}F0ooH4uRDekcl4yR;n?A<(3vaKw%hx~*|$2eB|i;(rmlBMd=%yf=$-wEf1W&m^I;0vXRUOTZ2 zP8kC)_JK3qgC29i>|2cpOHKUC>;;*FaG|E@ikrF6$wh>^dv5uuo;?499Rj>#$OChk zh%Nb{sp8&l0+#(i(1->f$$BC5Y+qROu7IWR{`~NA(y$>sP~|sV)0}0Bbv0mXEm(S1 zPr%SNQEL^~?~^XcYBi?pxH3u}7q8(ywtSL|TfUXkK(A`)&C60W7g))jn6)wuICEpvYf-SKh5F+EBUj!=1uzF3yh&h*qYR zB8hLSeZ#64Jm~fGI%9ocMKEik$3*5lGLr85Ha6;tY2YTL*+s(C8rjJ?u#MbA+;VRm zOoRgO=zIA0Dv8`=76xJASpKd_TjjLQ6e&;w7h61AH(jV zsV`35$Ky`bE4LmOup3FG=K%al<42ul4RD6oB&=hPK;QQ5HmN8uDC)-9V0w+NGJ6hw zu*Y;l?`OB`lq7em-hBYK>$6<+`mvbq^ z;wyDY#r1Piw1ncm0O9~3_}CS|*d6U&oh`3BHX+}+)hhynP{}9i@u>(C6_KbgKv^suzd@XFgm;QYvt-` z!@^s(67<3Yz}mWd7RAKEG*ZXJA&g<~Ez1oC$b}Fop&j`;Nr#-|Uu*`tgOb3k|tI+U-Qe^-adJ!CKQ`RQUS?n~ACF zQ7nfQ>>2h13svb$B}a_KqAOK<%AdgXOG+tcti4uipbG z-yRPgx=Z?nj1oU=hvWumL_K2Z495ZyLny`o+fbw+t8H!^mbyGd`ly8MNj57jb{gYy zrT(hG2UE-^d~+(v(PWS;3OTHaj@9phiuub~v9}*2B=7cGT~ZyX5||Q@tKIQTweYTV zZ7FYu0&IFsi6^cmkmu;qMeWkxYT6xTV^Md!=YBU@Y57hUJiK-#6ZQ9u1icVqFbNEJ zWrzz|s(9BL+qgyn1O)3MzC~2TPODuiq~i?B1Nk?dLSnlCX2Fr3CS;c_diJ1JB6a;~ zk3bxf{>7ZjQv}Wv;_#G^`TF1Kp6NQJY}vpM3hLpiNgXVY3r+N>8AI#>4!#y_?mHN; zGT6WmOLB*&{93^4z&2Y+B#*BlOnd=(bM1!U&W#jnqmcD!!m;hTNwnR^D;iWv5iUri z9V)Vw)BdvQ*QpzAnl||T+CcO-6z^P5z2IpC@UN(_3^_y@3y>jku?mIttQ}mQ86kki zn_`Csk<{Rt!`!n>?`?6so|`q(b(9M9wl@ z<>e?QQ?Qjodp;(S+@&an)nnzFYOtYABBoPF=nA6nf>h!ia5h}%QO3Jh;@OL2%7!Dj zZYT%$UeVb;S?a7Fe3lquJ1;|gkiZs`Kf27IM(syGVJqh1kJ`ZU5{B>r8;&fOdYQ|svz5j5(=WJ_7L%AeOYy5% znwSG+{tOHlYSeWb7rCT<8bw)bfRM`v&!^PFCpKcr^+s}7QgswQM>6Cat*>R%aodjyEZP*EWywzi*1k&wU@!>&C{c^6aCpbY-jrGAKkI-@xkGlw(TG=XH*yGvlDsGMCaOpj!R7VVhH zp3_tAV3G4?EA{3LiycYZH{;)a=_g%db&H2Rrk2oRhg{530?m0DeB|FeAvxW0WzbBl z!cAP)tIRDVKjAaApHgM!sUyujNzKd}XGhr4bStse?Y*L%JTj@n@V(#2wxxDU>xc4e z-8Tk<8aE?s$GO{oW*6Y)uXW`mriiHezM4F2rG0d-{$?q*E9i;&VP@dB<9s>KXDPD3 zCIW(Z+xwJT{peM!w8S*7D|cwf*QK%k4h-CH{PQm+uYbA>|0A6L-7@?u_2IuYdHw&o z4F6l{$v@|W{A&~0U-9^VR-wfI=M!0{icWO_D}qmVcVNmX=`8F45y5n`>gvYNDUUUs zN(kH@eWO5|E?*y+bL04At)|jbXxt1Z)AO6>C?k_(BOlL~z1!Qfp?ag>MUqBYU1RW_ z6;81(9QP_0fyJY&ql<3c4^Iaefjpuy7t-e)_s4T`PEGKsdZDY*n;gAQ5W(dS1op`) zBUk}F?N9a2u9GCSC$0P6E{RPjgZJ$SaGK*}wZwZ-XElCg zt9_zZ78vEsZ-_MQ1r4UztX=uTLmwwi_a-}oY0Y9-OPJM=Wc3ndea4`4If0*Ige>lp zE=&#ch8|MrIF3Jo(>c3xn`JSG;6mG|NXIHisOzhqV3g;z%E5MhH@ynsnyzoDf&??> zYxZl9sfn$aL0EEVxEWg`$|tZA(?+U2U#lpVCduFHmSHf(EXaS!_HoSSM4aQK5GNGr zHA|=~h4Z1Hr{7c-;`>f(DTwss&lmu%F_jxB8Mh8b9cd{qktTo!-Bdm*3&(Kr>Hwxg zJx6L1n9LZOmnDD}iL4oCZvE;_Z8|-WAT6@EM=28J%5-cG@h=ZG; znp8&YE>mzYEyOK8s!&%vuB=;4NT3GLRXoHKMU7jYSJ3<^7VNRIlQWgtnJ0%M{)JIabPBeKcjR%?tJMcZcZmD0FH-g4`KasZYf8{%?Kcs5Qi+PtQ@8 z@LkB#Yx~#57w{SwlS&f9`o|5V z{CP;8=>ni~OAI6G-$i6!V!2d8<#UJEAh(sgu8I6st0(cKY~JtO`c^V}WjJ!=JHY7I zPk4)K#~c#Qx)TW`{LfsHC_6p*!ZrCRON3pxe+`k+1O2>|FXe?W&x7^Za^ZbA_iEOq zD(z{0=cn1U2&|pG=k^hBHjxL2MqLo0o{zOUq}B%=+63&dJI$5+Z4r$NYa6H+liyL z=Q?&K@GH`kp%1Dwp@G7r!~}N?w{Nfaz=h-rMt0gtEauGV`~~eZ?|@Jp1!(Sk+}=;m z*N;A^?xSAZ?&0%i z;sep$Bhe_Mcvut)rJsWzoQce1o-X9f8&;i?JR@mFYlqd zJCZrx6Ue{(!9W9jA!D?LQw8<=s!zQ|{5+HvZ``*&a(5h$x~a^sX~VC1e01%r8Bls0 zvE(np4N_%$QyE!dh1=_rnR_=>49c}f{CLxkk;ewiIF&J)skGuAbaU2rJm|N6*foiY z^h5o!&s0P8YL(^M5YPnXkPW8{`0p07HB!CrL$k2nFhDC0z;5zxy5GExI`pP|DBCmV z<&X|Ob@yqM#O5$>MH9^Vs$-kV!L9{Y?#Bsv_%E5SE~}!mW!{0X=F9l%qW$wH&a7|B zb^yIFf0|miC@mivYt6yAIrA>Z7y&j8Eb?RT80S9pWPTKZ1HT_k{N5XiPUbB|7#qfe z(WFeC^#JlX7=vWB?EUVuV3&ohi8k=F3G-)%Y1LYf(ueZG!gZbQDaX~%w=!1xdTDyp zb;y}2q{3S9@6J^qO*}moeTTL<>e!Xak@y)>!)a`G?n#@ukVtTh#&Ng9?vqww;EGOY zyF1D=3$+v%X&pK8=ti$gb0ZC}r%X>>Xd_}2OzH5i&97v|JQWvl-#ZyyEo^wdA6HpI zFLGR+VDH*983r9-R}c5NlLR&i2kFS^s)~)1h7(s3aJ-fv9X={u8&OS%>U8*0&VndMP$T^ z?NOJpKKf*U$^d2unrp_PBMk67AX2lqE&5hWY|Rzd1tgeH@m(GEkd(7J8F&Fc^e1aO z=T*$1)eU57&j2Ylej4dVYXyA{;fSZA>1o;zqwl(xlzZyt4Aur3O(Sr{+NS=&kVa|0 z`FKCx+=_2qV?hdcN%=4j4P=9qT3nD^CXie%6GFBF+yDkHi5VCZlr#ClQ==jp#zf-r zC{6Vb&&eYk1onHvLzEd?piu7)b0@Bhjl3|e+&~JQUHw@lTY}#@svqSy z8iJ%3D6j~CvJe~IkqB!c2hnMwDJvvRqMy4{bc5Tgpn@2bkK_JNj9T zPgXB~00ubNvJ(gX(V#1_$rXG+@)XF0nx^ik4P1|tL8g4VD;K4>w%>^JS~Ql~>yVkS zV9BE9L;pZ5`6|;zc1F%l>SNHBOb8?9XqtmS;!Ja=ecM|vpWCQfj|_zja)ggJ86UE- z48I2%?3)f~RJaWV(gWw1D&7Zkvs>K_x`_*BV2NmTkR{P@Q!~7<$p>h|n4gIxQka+l zv`TCuVz{`yT}MboFOA^?#=e{;M>u2NZ*Z=O7SC0=O-YvG74^%1M`Vs@6J`Ac)PJ98 zPawL>!@$4p9;!$bwjEAjD##iBE3GO%lW}8+pOg(k9U7ALs~LHahl%aXdQ+vIHjiq2 zSk)+lIyMxgaioKNe*l&B;8^Nc)OD^#t0E=QrHhAPzf)% zBhX@%k8Q`RY#CAa$MII@tL<|F@aKhEcG6;&pbQY&8F>3xsM077svG@-)mH2u{yv^n z+xHN-UVLJb!b7%=tF5c`tN^!nkH@USCLA)=a(Im7C0jl2p|9r4nI7nh<5>|rCVu3U z0Esgbj3DcYqJU29_f6{t#%W+u9a6xlX*I!?06(iyHIy-^N#lll@xp4tb=!cgew6e3 zM`H8GysZMTn%%U=Mayt1Dg?Yy3E5_3uUX{~fcvGHXjR5`jMh$3_&ZL!b1N+1Ss>TDAW2*9o2Bm!O=?$LV802v|X8oqSx+sM8cw$;+^ zs4XamA-h@t@B+Pb0Ql*%(A9L1X@1{SU$e))0c;GTKL*Y{M9alcA5o7`pA65#8O^cb z>$pNdX%u?DrE8%ySe_nvhnj^dkT$O@X$7f%1vKnEZ(av%fsV;h=HlQEu7(8&tm*+@ z_h$H=A7=w!d50`NDaRiG$PhOfR3g#h%m}(p+$??gAis(j&+({vCOmPJkL%?|vp;f3 z1v+8BSDe)B*Ii3uI`IPbEyQle{mSM}tTJUXrz_y$`*hwAf7OyiUSdBR?dt%F8eGN_ zNV7i5&M)YZ&$QGsx1EmDd%nX5_AZ4?Kvc_^tMHHxFl!9i%@BHtln`rrZz6stk0}~u zuc02%$#6v`(*jp=is;j%0uU#^1~c`xHRIYV(<2xt5D2(Sr8VYz1i?9KITSi?HXH_1 zGZjM&X|~&IsKXtAKKuP@IBqyWN{jJqQ1X5gemac#BMe|QQi8IE;8tCf+j=ACORY#c z4K&2;1L!64BiB{^w#rQ0T4s^O6+_f(ZUv; zG?+B-7O^O$~{wao81J!yTnb{*daLJ+6g7Dv&p?73;Taih_j;um{pZLJB1r!RPpc!rE5vfh~Mws z9Q#V`lC<0d1&8F@VfkAEPnp3t^J!A}b}#wcH^^HsXXT9ST#6)iMrrjGfK#S?O7z=)_Gd%*>tfnV9LJ z=magCo#ag%h3stX?QBhKo$=YB=!ER7?HrZt4UE3d7B+FUFfvgT6NLKDL^B3PMta8o zT=Ub3S{pc<2%8w$8Gl{l-+#&*INCUIbN~A=PWVj!_Q1u)*6H6a{ukGylXo;RwlH$G zbHrz$|B@rVzMY&MO$=)|IAt+CYQ})22b2MV6sH zo2X|(j8Zc4TiMy1JIh)TuOy)Ec1`gNweRUk%sb8FJoxT};)zFiUkaaI{yMsP7j9lt z0RZT^K~Cue1^^I-XoUdqkJSbN=n!iAqVjOcEN_hUVl;xYHBAElOr6>ADWzqaHfBU0WvrJ@P)G{ZHev z1sad1bghH$QFtoISBHUgAPC@Jzu?W<6DmSQOE7DL#&;bS=_$aXIXg7Xo4Lk&T2)Z$ zWS#x)Ets7;Vhjg2xQSyfcCp9O6fv%mApzW8;#t`guwhlg=8^{5z0$Nv<)>8{Z4JRY zwHQzys12e$kq;t4XOli~Zfbf=(I((xA#AqS(w?<9gOxCxzj