<commit_before>package edu.uw.zookeeper.client;


import static com.google.common.base.Preconditions.checkArgument;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;


import org.apache.jute.Record;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.ListenableFuture;

import edu.uw.zookeeper.util.Event;
import edu.uw.zookeeper.data.StampedReference;
import edu.uw.zookeeper.data.StampedReference.Updater;
import edu.uw.zookeeper.data.ZNodeLabel;
import edu.uw.zookeeper.data.ZNodeLabelTrie;
import edu.uw.zookeeper.data.ZNodeLabelTrie.Pointer;
import edu.uw.zookeeper.data.ZNodeLabelTrie.SimplePointer;
import edu.uw.zookeeper.protocol.OpSessionResult;
import edu.uw.zookeeper.protocol.Operation;
import edu.uw.zookeeper.protocol.SessionReplyMessage;
import edu.uw.zookeeper.protocol.SessionRequestMessage;
import edu.uw.zookeeper.protocol.client.ZxidTracker;
import edu.uw.zookeeper.protocol.proto.IGetACLResponse;
import edu.uw.zookeeper.protocol.proto.IGetDataResponse;
import edu.uw.zookeeper.protocol.proto.IMultiRequest;
import edu.uw.zookeeper.protocol.proto.IMultiResponse;
import edu.uw.zookeeper.protocol.proto.ISetACLRequest;
import edu.uw.zookeeper.protocol.proto.ISetDataRequest;
import edu.uw.zookeeper.protocol.proto.Records;
import edu.uw.zookeeper.protocol.proto.Records.MultiOpRequest;
import edu.uw.zookeeper.protocol.proto.Records.MultiOpResponse;
import edu.uw.zookeeper.util.AbstractPair;
import edu.uw.zookeeper.util.ForwardingPromise;
import edu.uw.zookeeper.util.Promise;
import edu.uw.zookeeper.util.Publisher;
import edu.uw.zookeeper.util.Reference;
import edu.uw.zookeeper.util.SettableFuturePromise;

/**
 * Only caches the results of operations submitted through this wrapper.
 */
public class ZNodeResponseCache<E extends ZNodeResponseCache.AbstractNodeCache<E>> implements ClientExecutor {

    public static ZNodeResponseCache<SimpleZNodeCache> newInstance(
            Publisher publisher, ClientExecutor client) {
        return newInstance(publisher, client, SimpleZNodeCache.root());
    }
    
    public static <E extends ZNodeResponseCache.AbstractNodeCache<E>> ZNodeResponseCache<E> newInstance(
            Publisher publisher, ClientExecutor client, E root) {
        return newInstance(publisher, client, ZNodeLabelTrie.of(root));
    }
    
    public static <E extends ZNodeResponseCache.AbstractNodeCache<E>> ZNodeResponseCache<E> newInstance(
            Publisher publisher, ClientExecutor client, ZNodeLabelTrie<E> trie) {
        return new ZNodeResponseCache<E>(publisher, client, trie);
    }

    public static enum View {
        DATA(Records.DataHolder.class), 
        ACL(Records.AclHolder.class), 
        STAT(Records.StatHolder.class);
        
        public static View ofType(Class<? extends Records.View> type) {
            for (View v: values()) {
                if (type == v.type()) {
                    return v;
                }
            }
            throw new IllegalArgumentException(type.toString());
        }
        
        private final Class<? extends Records.View> type;
        
        private View(Class<? extends Records.View> type) {
            this.type = type;
        }
        
        public Class<? extends Records.View> type() {
            return type;
        }
    }
    
    @Event
    public static class ViewUpdate {
        
        public static ViewUpdate ifUpdated(
                ZNodeLabel.Path path,
                View view, 
                StampedReference<? extends Records.View> previousValue, 
                StampedReference<? extends Records.View> updatedValue) {
            
            if (updatedValue.stamp().compareTo(previousValue.stamp()) < 0) {
                return null;
            }
            
            if (previousValue.get() != null) {
                switch (view) {
                case DATA:
                {
                    byte[] prev = ((Records.DataHolder)previousValue.get()).getData();
                    byte[] updated = ((Records.DataHolder)updatedValue.get()).getData();
                    if (Arrays.equals(prev, updated)) {
                        return null;
                    }
                    break;
                }
                case ACL:
                {
                    List<ACL> prev = ((Records.AclHolder)previousValue.get()).getAcl();
                    List<ACL> updated = ((Records.AclHolder)updatedValue.get()).getAcl();
                    if (prev.equals(updated)) {
                        return null;
                    }
                    break;
                }
                case STAT:
                {
                    Stat prev = ((Records.StatHolder)previousValue.get()).getStat();
                    Stat updated = ((Records.StatHolder)updatedValue.get()).getStat();
                    if (prev.equals(updated)) {
                        return null;
                    }
                    break;
                }
                default:
                    throw new AssertionError();
                }
            }
            
            return of(path, view, previousValue, updatedValue);
        }
        
        public static ViewUpdate of(
                ZNodeLabel.Path path,
                View view, 
                StampedReference<? extends Records.View> previousValue, 
                StampedReference<? extends Records.View> updatedValue) {
            return new ViewUpdate(path, view, previousValue, updatedValue);
        }
        
        private final ZNodeLabel.Path path;
        private final View view;
        private final StampedReference<? extends Records.View> previousValue;
        private final StampedReference<? extends Records.View> updatedValue;
        
        public ViewUpdate(
                ZNodeLabel.Path path,
                View view, 
                StampedReference<? extends Records.View> previousValue, 
                StampedReference<? extends Records.View> updatedValue) {
            this.path = path;
            this.view = view;
            this.previousValue = previousValue;
            this.updatedValue = updatedValue;
        }
        
        public ZNodeLabel.Path path() {
            return path;
        }
        
        public View view() {
            return view;
        }
        
        public StampedReference<? extends Records.View> previousValue() {
            return previousValue;
        }
        
        public StampedReference<? extends Records.View> updatedValue() {
            return updatedValue;
        }
        
        @Override
        public String toString() {
            return Objects.toStringHelper(this)
                    .add("view", view())
                    .add("previous", previousValue())
                    .add("updated", updatedValue()).toString();
        }
    }
    
    @Event
    public static class NodeUpdate extends AbstractPair<NodeUpdate.UpdateType, StampedReference<ZNodeLabel.Path>> {

        public static NodeUpdate of(UpdateType type, StampedReference<ZNodeLabel.Path> path) {
            return new NodeUpdate(type, path);
        }
        
        public static enum UpdateType {
            NODE_ADDED, NODE_REMOVED;
        }
        
        public NodeUpdate(UpdateType type, StampedReference<ZNodeLabel.Path> path) {
            super(type, path);
        }        
        
        public UpdateType type() {
            return first;
        }
        
        public StampedReference<ZNodeLabel.Path> path() {
            return second;
        }
    }
    
    public static interface NodeCache<E extends NodeCache<E>> extends ZNodeLabelTrie.Node<E> {

        Long stamp();<commit_msg>minor<commit_after>package edu.uw.zookeeper.client;


import static com.google.common.base.Preconditions.checkArgument;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;


import org.apache.jute.Record;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.ListenableFuture;

import edu.uw.zookeeper.util.Event;
import edu.uw.zookeeper.data.StampedReference;
import edu.uw.zookeeper.data.StampedReference.Updater;
import edu.uw.zookeeper.data.ZNodeLabel;
import edu.uw.zookeeper.data.ZNodeLabelTrie;
import edu.uw.zookeeper.data.ZNodeLabelTrie.Pointer;
import edu.uw.zookeeper.data.ZNodeLabelTrie.SimplePointer;
import edu.uw.zookeeper.protocol.OpSessionResult;
import edu.uw.zookeeper.protocol.Operation;
import edu.uw.zookeeper.protocol.SessionReplyMessage;
import edu.uw.zookeeper.protocol.SessionRequestMessage;
import edu.uw.zookeeper.protocol.client.ZxidTracker;
import edu.uw.zookeeper.protocol.proto.IGetACLResponse;
import edu.uw.zookeeper.protocol.proto.IGetDataResponse;
import edu.uw.zookeeper.protocol.proto.IMultiRequest;
import edu.uw.zookeeper.protocol.proto.IMultiResponse;
import edu.uw.zookeeper.protocol.proto.ISetACLRequest;
import edu.uw.zookeeper.protocol.proto.ISetDataRequest;
import edu.uw.zookeeper.protocol.proto.Records;
import edu.uw.zookeeper.protocol.proto.Records.MultiOpRequest;
import edu.uw.zookeeper.protocol.proto.Records.MultiOpResponse;
import edu.uw.zookeeper.util.AbstractPair;
import edu.uw.zookeeper.util.ForwardingPromise;
import edu.uw.zookeeper.util.Promise;
import edu.uw.zookeeper.util.Publisher;
import edu.uw.zookeeper.util.Reference;
import edu.uw.zookeeper.util.SettableFuturePromise;

/**
 * Only caches the results of operations submitted through this wrapper.
 */
public class ZNodeResponseCache<E extends ZNodeResponseCache.AbstractNodeCache<E>> implements ClientExecutor {

    public static ZNodeResponseCache<SimpleZNodeCache> newInstance(
            Publisher publisher, ClientExecutor client) {
        return newInstance(publisher, client, SimpleZNodeCache.root());
    }
    
    public static <E extends ZNodeResponseCache.AbstractNodeCache<E>> ZNodeResponseCache<E> newInstance(
            Publisher publisher, ClientExecutor client, E root) {
        return newInstance(publisher, client, ZNodeLabelTrie.of(root));
    }
    
    public static <E extends ZNodeResponseCache.AbstractNodeCache<E>> ZNodeResponseCache<E> newInstance(
            Publisher publisher, ClientExecutor client, ZNodeLabelTrie<E> trie) {
        return new ZNodeResponseCache<E>(publisher, client, trie);
    }

    public static enum View {
        DATA(Records.DataHolder.class), 
        ACL(Records.AclHolder.class), 
        STAT(Records.StatHolder.class);
        
        public static View ofType(Class<? extends Records.View> type) {
            for (View v: values()) {
                if (type == v.type()) {
                    return v;
                }
            }
            throw new IllegalArgumentException(type.toString());
        }
        
        private final Class<? extends Records.View> type;
        
        private View(Class<? extends Records.View> type) {
            this.type = type;
        }
        
        public Class<? extends Records.View> type() {
            return type;
        }
    }
    
    @Event
    public static class ViewUpdate {
        
        public static ViewUpdate ifUpdated(
                ZNodeLabel.Path path,
                View view, 
                StampedReference<? extends Records.View> previous, 
                StampedReference<? extends Records.View> updated) {
            
            if (updated.stamp().compareTo(previous.stamp()) < 0) {
                return null;
            }
            
            if (previous.get() != null) {
                switch (view) {
                case DATA:
                {
                    if (Arrays.equals(((Records.DataHolder)previous.get()).getData(), 
                            ((Records.DataHolder)updated.get()).getData())) {
                        return null;
                    }
                    break;
                }
                case ACL:
                {
                    if (Objects.equal(((Records.AclHolder)previous.get()).getAcl(), 
                            ((Records.AclHolder)updated.get()).getAcl())) {
                        return null;
                    }
                    break;
                }
                case STAT:
                {
                    if (Objects.equal(((Records.StatHolder)previous.get()).getStat(),
                            ((Records.StatHolder)updated.get()).getStat())) {
                        return null;
                    }
                    break;
                }
                default:
                    throw new AssertionError();
                }
            }
            
            return of(path, view, previous, updated);
        }
        
        public static ViewUpdate of(
                ZNodeLabel.Path path,
                View view, 
                StampedReference<? extends Records.View> previous, 
                StampedReference<? extends Records.View> updated) {
            return new ViewUpdate(path, view, previous, updated);
        }
        
        private final ZNodeLabel.Path path;
        private final View view;
        private final StampedReference<? extends Records.View> previous;
        private final StampedReference<? extends Records.View> updated;
        
        public ViewUpdate(
                ZNodeLabel.Path path,
                View view, 
                StampedReference<? extends Records.View> previous, 
                StampedReference<? extends Records.View> updated) {
            this.path = path;
            this.view = view;
            this.previous = previous;
            this.updated = updated;
        }
        
        public ZNodeLabel.Path path() {
            return path;
        }
        
        public View view() {
            return view;
        }
        
        public StampedReference<? extends Records.View> previous() {
            return previous;
        }
        
        public StampedReference<? extends Records.View> updated() {
            return updated;
        }
        
        @Override
        public String toString() {
            return Objects.toStringHelper(this)
                    .add("path", path())
                    .add("view", view())
                    .add("previous", previous())
                    .add("updated", updated()).toString();
        }
    }
    
    @Event
    public static class NodeUpdate extends AbstractPair<NodeUpdate.UpdateType, StampedReference<ZNodeLabel.Path>> {

        public static NodeUpdate of(UpdateType type, StampedReference<ZNodeLabel.Path> path) {
            return new NodeUpdate(type, path);
        }
        
        public static enum UpdateType {
            NODE_ADDED, NODE_REMOVED;
        }
        
        public NodeUpdate(UpdateType type, StampedReference<ZNodeLabel.Path> path) {
            super(type, path);
        }        
        
        public UpdateType type() {
            return first;
        }
        
        public StampedReference<ZNodeLabel.Path> path() {
            return second;
        }
    }
    
    public static interface NodeCache<E extends NodeCache<E>> extends ZNodeLabelTrie.Node<E> {

        Long stamp();
{'fraction_non_alphanumeric': 0.0925123956568129, 'fraction_numerical': 0.0003765769158350593, 'mean_word_length': 1.9906156156156156, 'pattern_counts': {'":': 0, '<': 73, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7248374', 'n_tokens_mistral': 4296, 'n_tokens_neox': 4163, 'n_words': 851}