-package org.simantics.scl.runtime.chr;\r
-\r
-import java.util.Arrays;\r
-\r
-public class FactActivationQueue {\r
- public static final boolean TRACE = false;\r
- \r
- private final PriorityContainer[] containers;\r
- private PriorityContainer[] activeContainers = new PriorityContainer[8];\r
- private int activeContainerCount; \r
-\r
- public FactActivationQueue(int priorityCount) {\r
- if(TRACE)\r
- System.out.println("priorityCount = " + priorityCount);\r
- containers = new PriorityContainer[priorityCount];\r
- for(int i=0;i<priorityCount;++i)\r
- containers[i] = new PriorityContainer(i); \r
- }\r
- \r
- /**\r
- * Adds a new fact with a given priority\r
- */\r
- public void add(int priority, Fact item) {\r
- if(TRACE)\r
- System.out.println("FactActivationQueue.add " + priority + "@" + item);\r
- PriorityContainer container = containers[priority];\r
- if(container.size == 0)\r
- activateContainer(container);\r
- container.push(item);\r
- }\r
- \r
- private void activateContainer(PriorityContainer container) {\r
- if(TRACE)\r
- System.out.println("FactActivationQueue.activate priority " + container.priority);\r
- if(activeContainers.length == activeContainerCount)\r
- activeContainers = Arrays.copyOf(activeContainers, activeContainerCount*2);\r
- adjustUpwards(activeContainerCount, container);\r
- ++activeContainerCount;\r
- }\r
-\r
- private void deactivateContainer() {\r
- --activeContainerCount;\r
- adjustDownwards(0, activeContainers[activeContainerCount]);\r
- activeContainers[activeContainerCount] = null;\r
- }\r
-\r
- private void adjustDownwards(int pos, PriorityContainer item) {\r
- int priority = item.priority;\r
- while(true) {\r
- int npos = 2*pos+1;\r
- if(npos+1 >= activeContainerCount) {\r
- if(npos >= activeContainerCount)\r
- break;\r
- PriorityContainer item1 = activeContainers[npos];\r
- if(priority > item1.priority) {\r
- activeContainers[pos] = item1;\r
- activeContainers[npos] = item;\r
- return;\r
- }\r
- else\r
- break;\r
- }\r
- PriorityContainer item1 = activeContainers[npos];\r
- PriorityContainer item2 = activeContainers[npos+1];\r
- if(priority < item1.priority) {\r
- if(priority < item2.priority)\r
- break;\r
- }\r
- else {\r
- if(item1.priority < item2.priority) {\r
- activeContainers[pos] = item1;\r
- pos = npos;\r
- continue;\r
- }\r
- }\r
- activeContainers[pos] = item2;\r
- pos = npos+1;\r
- }\r
- activeContainers[pos] = item;\r
- }\r
-\r
- private void adjustUpwards(int pos, PriorityContainer item) {\r
- int priority = item.priority;\r
- while(pos > 0) {\r
- int npos = (pos-1)/2;\r
- PriorityContainer item1 = activeContainers[npos];\r
- if(item1.priority > priority) {\r
- activeContainers[pos] = item1;\r
- pos = npos;\r
- }\r
- else\r
- break;\r
- }\r
- activeContainers[pos] = item;\r
- }\r
- \r
- /**\r
- * Activates all facts with priority less than the current priority\r
- */\r
- public void activate(Object context, int currentPriority) {\r
- if(TRACE)\r
- System.out.println("FactActivationQueue.activate " + currentPriority);\r
- while(activeContainerCount > 0) {\r
- PriorityContainer topContainer = activeContainers[0];\r
- int priority = topContainer.priority;\r
- if(priority >= currentPriority)\r
- return;\r
- \r
- Fact fact = topContainer.pop();\r
- if(topContainer.size == 0)\r
- deactivateContainer();\r
- \r
- int newPriority = fact.activate(context, priority);\r
- if(TRACE)\r
- System.out.println(" [" + currentPriority + "] " + fact + " oldPriority=" + priority + ", newPriority=" + newPriority);\r
- if(newPriority >= 0)\r
- add(newPriority, fact);\r
- }\r
- }\r
-}\r
+package org.simantics.scl.runtime.chr;
+
+import java.util.Arrays;
+
+public class FactActivationQueue {
+ public static final boolean TRACE = false;
+
+ private final PriorityContainer[] containers;
+ private PriorityContainer[] activeContainers = new PriorityContainer[8];
+ private int activeContainerCount;
+
+ public FactActivationQueue(int priorityCount) {
+ if(TRACE)
+ System.out.println("priorityCount = " + priorityCount);
+ containers = new PriorityContainer[priorityCount];
+ for(int i=0;i<priorityCount;++i)
+ containers[i] = new PriorityContainer(i);
+ }
+
+ /**
+ * Adds a new fact with a given priority
+ */
+ public void add(int priority, Fact item) {
+ if(TRACE)
+ System.out.println("FactActivationQueue.add " + priority + "@" + item);
+ PriorityContainer container = containers[priority];
+ if(container.size == 0)
+ activateContainer(container);
+ container.push(item);
+ }
+
+ private void activateContainer(PriorityContainer container) {
+ if(TRACE)
+ System.out.println("FactActivationQueue.activate priority " + container.priority);
+ if(activeContainers.length == activeContainerCount)
+ activeContainers = Arrays.copyOf(activeContainers, activeContainerCount*2);
+ adjustUpwards(activeContainerCount, container);
+ ++activeContainerCount;
+ }
+
+ private void deactivateContainer() {
+ --activeContainerCount;
+ adjustDownwards(0, activeContainers[activeContainerCount]);
+ activeContainers[activeContainerCount] = null;
+ }
+
+ private void adjustDownwards(int pos, PriorityContainer item) {
+ int priority = item.priority;
+ while(true) {
+ int npos = 2*pos+1;
+ if(npos+1 >= activeContainerCount) {
+ if(npos >= activeContainerCount)
+ break;
+ PriorityContainer item1 = activeContainers[npos];
+ if(priority > item1.priority) {
+ activeContainers[pos] = item1;
+ activeContainers[npos] = item;
+ return;
+ }
+ else
+ break;
+ }
+ PriorityContainer item1 = activeContainers[npos];
+ PriorityContainer item2 = activeContainers[npos+1];
+ if(priority < item1.priority) {
+ if(priority < item2.priority)
+ break;
+ }
+ else {
+ if(item1.priority < item2.priority) {
+ activeContainers[pos] = item1;
+ pos = npos;
+ continue;
+ }
+ }
+ activeContainers[pos] = item2;
+ pos = npos+1;
+ }
+ activeContainers[pos] = item;
+ }
+
+ private void adjustUpwards(int pos, PriorityContainer item) {
+ int priority = item.priority;
+ while(pos > 0) {
+ int npos = (pos-1)/2;
+ PriorityContainer item1 = activeContainers[npos];
+ if(item1.priority > priority) {
+ activeContainers[pos] = item1;
+ pos = npos;
+ }
+ else
+ break;
+ }
+ activeContainers[pos] = item;
+ }
+
+ /**
+ * Activates all facts with priority less than the current priority
+ */
+ public void activate(Object context, int currentPriority) {
+ if(TRACE)
+ System.out.println("FactActivationQueue.activate " + currentPriority);
+ while(activeContainerCount > 0) {
+ PriorityContainer topContainer = activeContainers[0];
+ int priority = topContainer.priority;
+ if(priority >= currentPriority)
+ return;
+
+ Fact fact = topContainer.pop();
+ if(topContainer.size == 0)
+ deactivateContainer();
+
+ int newPriority = fact.activate(context, priority);
+ if(TRACE)
+ System.out.println(" [" + currentPriority + "] " + fact + " oldPriority=" + priority + ", newPriority=" + newPriority);
+ if(newPriority >= 0)
+ add(newPriority, fact);
+ }
+ }
+}