View Javadoc

1   /*
2    * #%L
3    * prolobjectlink-jpi-jtrolog
4    * %%
5    * Copyright (C) 2012 - 2018 WorkLogic Project
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as
9    * published by the Free Software Foundation, either version 2.1 of the
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-2.1.html>.
20   * #L%
21   */
22  package jTrolog.engine;
23  
24  /**
25   * GarbageCan listing which Variables bound per executionCtx number. Each
26   * variable is identified by two numbers, vNr (its position in the Struct) and
27   * vCtx (separating the same Variable from the same rule used by the Engine at
28   * different times). The execCtx is a Number that the Engine controls that can
29   * be used to remember at what point in the execution of a query a binding was
30   * made (so that it can be garbage collected).
31   * 
32   * The GarbageCan keeps track of how many bindings it has registered using the
33   * depthCounter. For every depth there is an entry for every possible execCtx in
34   * both the map for vNrs and the map for vCtxs. Neither of the two maps should
35   * ever be empty.
36   * 
37   * The maps automatically expand in depth, width is updated by the Engine.
38   * 
39   * @author eivbsmed@stud.hist.no
40   * @author ivar.orstavik@hist.no
41   */
42  class GarbageCan {
43  
44  	private int depth = 8;
45  	private int width = Engine.STARTUP_STACK_SIZE;
46  
47  	private int[][] trashCanVarNr = new int[depth][width];
48  	private int[][] trashCanVarCtx = new int[depth][width];
49  
50  	private int[] depthCounter = new int[width];
51  
52  	private LinkTable links;
53  
54  	GarbageCan(LinkTable links) {
55  		this.links = links;
56  		for (int i = 0; i < depth; i++) {
57  			trashCanVarNr[i] = new int[width];
58  			trashCanVarCtx[i] = new int[width];
59  		}
60  	}
61  
62  	void addToTrashCan(int vNr, int vCtx, int execCtx) {
63  		// get and update the depth counter
64  		int currentDepth = depthCounter[execCtx];
65  		depthCounter[execCtx] = currentDepth + 1;
66  
67  		// check depth and expand map if needed
68  		if (currentDepth == depth)
69  			doubleTrashCanDepth(depth * 2);
70  
71  		// mark vNr and vCtx under the given execCtx
72  		trashCanVarNr[currentDepth][execCtx] = vNr;
73  		trashCanVarCtx[currentDepth][execCtx] = vCtx;
74  	}
75  
76  	private void doubleTrashCanDepth(final int newSize) {
77  		trashCanVarNr = LinkTable.expandMap(trashCanVarNr, newSize);
78  		trashCanVarCtx = LinkTable.expandMap(trashCanVarCtx, newSize);
79  		for (int i = depth; i < newSize; i++) {
80  			trashCanVarNr[i] = new int[width];
81  			trashCanVarCtx[i] = new int[width];
82  		}
83  		depth = newSize;
84  	}
85  
86  	void doubleTrashCanWidth(final int newSize) {
87  		for (int i = 0; i < depth; i++) {
88  			trashCanVarNr[i] = LinkTable.expandArray(trashCanVarNr[i], newSize);
89  			trashCanVarCtx[i] = LinkTable.expandArray(trashCanVarCtx[i], newSize);
90  		}
91  		depthCounter = LinkTable.expandArray(depthCounter, newSize);
92  		width *= 2;
93  	}
94  
95  	void collectGarbageLinks(int owner) {
96  		int currentDepth = depthCounter[owner];
97  		depthCounter[owner] = 0;
98  
99  		for (int i = 0; i < currentDepth; i++) {
100 			int trashThisLink = trashCanVarNr[i][owner];
101 			int trashThisCtx = trashCanVarCtx[i][owner];
102 			links.reset(trashThisLink, trashThisCtx);
103 		}
104 	}
105 
106 	public int[][] getGarbageLinks(int owner) {
107 		int[][] ints = new int[depth][2];
108 		for (int i = 0; i < depthCounter[owner]; i++) {
109 			int varNr = trashCanVarNr[i][owner];
110 			int varCtx = trashCanVarCtx[i][owner];
111 			ints[i] = new int[] { varNr, varCtx };
112 		}
113 		return ints;
114 	}
115 }