Search in sources :

Example 16 with FasterList

use of jcog.list.FasterList in project narchy by automenta.

the class MyConcurrentRadixTree method compute.

/**
 * Atomically adds the given value to the tree, creating a node for the value as necessary. If the value is already
 * stored for the same key, either overwrites the existing value, or simply returns the existing value, depending
 * on the given value of the <code>overwrite</code> flag.
 *
 * @param key       The key against which the value should be stored
 * @param newValue  The value to store against the key
 * @param overwrite If true, should replace any existing value, if false should not replace any existing value
 * @return The existing value for this key, if there was one, otherwise null
 */
<V> X compute(@NotNull AbstractBytes key, V value, QuadFunction<AbstractBytes, SearchResult, X, V, X> computeFunc) {
    // if (key.length() == 0) {
    // throw new IllegalArgumentException("The key argument was zero-length");
    // }
    int version;
    X newValue, foundX;
    SearchResult result;
    int matched;
    Object foundValue;
    Node found;
    version = writes.intValue();
    acquireReadLockIfNecessary();
    try {
        // Note we search the tree here after we have acquired the write lock...
        result = searchTree(key);
        found = result.found;
        matched = result.charsMatched;
        foundValue = found != null ? found.getValue() : null;
        foundX = ((matched == key.length()) && (foundValue != VoidValue.SINGLETON)) ? ((X) foundValue) : null;
    } finally {
        releaseReadLockIfNecessary();
    }
    newValue = computeFunc.apply(key, result, foundX, value);
    if (newValue != foundX) {
        int version2 = acquireWriteLock();
        try {
            if (version + 1 != version2) {
                // search again because the tree has changed since the initial lookup
                result = searchTree(key);
                found = result.found;
                matched = result.charsMatched;
                foundValue = found != null ? found.getValue() : null;
                foundX = ((matched == key.length()) && (foundValue != VoidValue.SINGLETON)) ? ((X) foundValue) : null;
                if (foundX == newValue)
                    // no change; the requested value has already been supplied since the last access
                    return newValue;
            }
            SearchResult.Classification classification = result.classification;
            if (foundX == null)
                estSize.incrementAndGet();
            FasterList<Node> oedges = found.getOutgoingEdges();
            switch(classification) {
                case EXACT_MATCH:
                    if (newValue != foundValue) {
                        // clone and reattach
                        cloneAndReattach(result, found, foundValue, oedges);
                    }
                    break;
                case KEY_ENDS_MID_EDGE:
                    {
                        // Search ran out of characters from the key while in the middle of an edge in the node.
                        // -> Split the node in two: Create a new parent node storing the new value,
                        // and a new child node holding the original value and edges from the existing node...
                        AbstractBytes keyCharsFromStartOfNodeFound = key.subSequence(matched - result.charsMatchedInNodeFound, key.length());
                        AbstractBytes commonPrefix = getCommonPrefix(keyCharsFromStartOfNodeFound, found.getIncomingEdge());
                        AbstractBytes suffixFromExistingEdge = subtractPrefix(found.getIncomingEdge(), commonPrefix);
                        // Create new nodes...
                        Node newChild = createNode(suffixFromExistingEdge, foundValue, oedges, false);
                        Node newParent = createNode(commonPrefix, newValue, new FasterList(new Node[] { newChild }), false);
                        // Add the new parent to the parent of the node being replaced (replacing the existing node)...
                        result.parentNode.updateOutgoingEdge(newParent);
                        break;
                    }
                case INCOMPLETE_MATCH_TO_END_OF_EDGE:
                    // Search found a difference in characters between the key and the start of all child edges leaving the
                    // node, the key still has trailing unmatched characters.
                    // -> Add a new child to the node, containing the trailing characters from the key.
                    // NOTE: this is the only branch which allows an edge to be added to the root.
                    // (Root node's own edge is "" empty string, so is considered a prefixing edge of every key)
                    // Create a new child node containing the trailing characters...
                    AbstractBytes keySuffix = key.subSequence(matched, key.length());
                    Node newChild = createNode(keySuffix, newValue, emptyList, false);
                    // Clone the current node adding the new child...
                    int numEdges = oedges.size();
                    Node[] edgesArray;
                    if (numEdges > 0) {
                        edgesArray = new Node[numEdges + 1];
                        arraycopy(oedges.array(), 0, edgesArray, 0, numEdges);
                        edgesArray[numEdges] = newChild;
                    } else {
                        edgesArray = new Node[] { newChild };
                    }
                    cloneAndReattach(result, found, foundValue, new FasterList(edgesArray.length, edgesArray));
                    break;
                case INCOMPLETE_MATCH_TO_MIDDLE_OF_EDGE:
                    // Search found a difference in characters between the key and the characters in the middle of the
                    // edge in the current node, and the key still has trailing unmatched characters.
                    // -> Split the node in three:
                    // Let's call node found: NF
                    // (1) Create a new node N1 containing the unmatched characters from the rest of the key, and the
                    // value supplied to this method
                    // (2) Create a new node N2 containing the unmatched characters from the rest of the edge in NF, and
                    // copy the original edges and the value from NF unmodified into N2
                    // (3) Create a new node N3, which will be the split node, containing the matched characters from
                    // the key and the edge, and add N1 and N2 as child nodes of N3
                    // (4) Re-add N3 to the parent node of NF, effectively replacing NF in the tree
                    AbstractBytes suffixFromKey = key.subSequence(matched, key.length());
                    // Create new nodes...
                    Node n1 = createNode(suffixFromKey, newValue, emptyList, false);
                    AbstractBytes keyCharsFromStartOfNodeFound = key.subSequence(matched - result.charsMatchedInNodeFound, key.length());
                    AbstractBytes commonPrefix = getCommonPrefix(keyCharsFromStartOfNodeFound, found.getIncomingEdge());
                    AbstractBytes suffixFromExistingEdge = subtractPrefix(found.getIncomingEdge(), commonPrefix);
                    Node n2 = createNode(suffixFromExistingEdge, foundValue, oedges, false);
                    @SuppressWarnings("NullableProblems") Node n3 = createNode(commonPrefix, null, new FasterList(2, new Node[] { n1, n2 }), false);
                    result.parentNode.updateOutgoingEdge(n3);
                    // Return null for the existing value...
                    break;
                default:
                    // This is a safeguard against a new enum constant being added in future.
                    throw new IllegalStateException("Unexpected classification for search result: " + result);
            }
        } finally {
            releaseWriteLock();
        }
    }
    return newValue;
}
Also used : AbstractBytes(jcog.data.byt.AbstractBytes) FasterList(jcog.list.FasterList)

Example 17 with FasterList

use of jcog.list.FasterList in project narchy by automenta.

the class NodeGraphTest method testObjectGraph.

@Test
public void testObjectGraph() {
    MapNodeGraph<Object, Object> h = new MapNodeGraph<>();
    h.addEdge(h.addNode("y"), "yx", h.addNode("x"));
    ObjectGraph o = new ObjectGraph(3, h) {

        @Override
        protected boolean access(Object root, FasterList<Pair<Class, ObjectGraph.Accessor>> path, Object target) {
            System.out.println(root + " -> " + target + "\n\t" + path);
            return true;
        }

        @Override
        public boolean includeValue(Object value) {
            return true;
        }

        @Override
        public boolean includeClass(Class<?> c) {
            return !c.isPrimitive();
        }

        @Override
        public boolean includeField(Field f) {
            return true;
        }
    };
    o.print();
}
Also used : Field(java.lang.reflect.Field) FasterList(jcog.list.FasterList) ObjectGraph(jcog.data.graph.ObjectGraph) MapNodeGraph(jcog.data.graph.MapNodeGraph) Test(org.junit.jupiter.api.Test)

Example 18 with FasterList

use of jcog.list.FasterList in project narchy by automenta.

the class NodeGraphTest method testDFS.

@Test
public void testDFS() {
    NodeGraph n = g1();
    List<String> trace = new FasterList();
    n.dfs("a", new Search() {

        @Override
        protected boolean next(BooleanObjectPair move, NodeGraph.Node next) {
            trace.add(path.toString());
            return true;
        }
    });
    assertEquals(4, trace.size());
    assertEquals("[[true:a => ab => b], [true:a => ab => b, true:b => bc => c], [true:a => ab => b, true:b => bc => c, true:c => cd => d], [true:a => ae => e]]", trace.toString());
}
Also used : FasterList(jcog.list.FasterList) BooleanObjectPair(org.eclipse.collections.api.tuple.primitive.BooleanObjectPair) NodeGraph(jcog.data.graph.NodeGraph) MapNodeGraph(jcog.data.graph.MapNodeGraph) Test(org.junit.jupiter.api.Test)

Example 19 with FasterList

use of jcog.list.FasterList in project narchy by automenta.

the class NodeGraphTest method testBFS.

@Test
public void testBFS() {
    NodeGraph n = g1();
    List<String> trace = new FasterList();
    n.bfs("a", new Search() {

        @Override
        protected boolean next(BooleanObjectPair move, NodeGraph.Node next) {
            trace.add(path.toString());
            return true;
        }
    });
    assertEquals(4, trace.size());
    assertEquals("[[true:a => ab => b], [true:a => ae => e], [true:a => ab => b, true:b => bc => c], [true:a => ab => b, true:b => bc => c, true:c => cd => d]]", trace.toString());
}
Also used : FasterList(jcog.list.FasterList) BooleanObjectPair(org.eclipse.collections.api.tuple.primitive.BooleanObjectPair) NodeGraph(jcog.data.graph.NodeGraph) MapNodeGraph(jcog.data.graph.MapNodeGraph) Test(org.junit.jupiter.api.Test)

Example 20 with FasterList

use of jcog.list.FasterList in project narchy by automenta.

the class SpeechPlan method next.

public boolean next() {
    // long start = nar.time();
    float dur = nar.dur() * durationsPerWord;
    long now = nar.time();
    long startOfNow = now - (int) Math.ceil(dur);
    long endOfNow = now + (int) Math.floor(dur);
    FasterList<Pair<Term, Truth>> pending = new FasterList<>(0);
    synchronized (vocalize) {
        // vocalize.rowKeySet().tailSet(startOfNow-1).clear();
        SortedSet<Long> tt = vocalize.rowKeySet().headSet(endOfNow);
        if (!tt.isEmpty()) {
            LongArrayList ll = new LongArrayList(tt.size());
            // copy to array so we can modify the vocalize rows
            tt.forEach(ll::add);
            ll.forEach(t -> {
                Set<Map.Entry<Term, TruthAccumulator>> entries = vocalize.row(t).entrySet();
                if (t >= startOfNow) {
                    entries.forEach(e -> {
                        Truth x = e.getValue().commitSum();
                        if (x.expectation() > expectationThreshold)
                            pending.add(Tuples.pair(e.getKey(), x));
                    });
                }
                entries.clear();
            });
        }
    }
    if (pending.isEmpty())
        return true;
    // TODO decide word..
    Term spoken = decide(pending);
    if (spoken != null)
        speak.accept(spoken);
    return true;
}
Also used : FasterList(jcog.list.FasterList) LongArrayList(org.eclipse.collections.impl.list.mutable.primitive.LongArrayList) Term(nars.term.Term) Truth(nars.truth.Truth) Pair(org.eclipse.collections.api.tuple.Pair)

Aggregations

FasterList (jcog.list.FasterList)48 Term (nars.term.Term)17 List (java.util.List)7 Truth (nars.truth.Truth)5 Pair (org.eclipse.collections.api.tuple.Pair)5 Nullable (org.jetbrains.annotations.Nullable)5 Map (java.util.Map)4 Predicate (java.util.function.Predicate)4 NAR (nars.NAR)4 Task (nars.Task)4 LongObjectPair (org.eclipse.collections.api.tuple.primitive.LongObjectPair)4 java.util (java.util)3 Supplier (java.util.function.Supplier)3 Util (jcog.Util)3 MapNodeGraph (jcog.data.graph.MapNodeGraph)3 NALTask (nars.task.NALTask)3 Bool (nars.term.atom.Bool)3 Test (org.junit.jupiter.api.Test)3 RoaringBitmap (org.roaringbitmap.RoaringBitmap)3 MultimapBuilder (com.google.common.collect.MultimapBuilder)2