+++ /dev/null
-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);
- }
- }
-}