Github user Randgalt commented on a diff in the pull request:

    https://github.com/apache/zookeeper/pull/136#discussion_r140815418
  
    --- Diff: src/java/main/org/apache/zookeeper/server/WatchManager.java ---
    @@ -40,50 +40,110 @@
     class WatchManager {
         private static final Logger LOG = 
LoggerFactory.getLogger(WatchManager.class);
     
    -    private final HashMap<String, HashSet<Watcher>> watchTable =
    -        new HashMap<String, HashSet<Watcher>>();
    +    enum Type {
    +        STANDARD() {
    +            @Override
    +            boolean isPersistent() {
    +                return false;
    +            }
    +
    +            @Override
    +            boolean isRecursive() {
    +                return false;
    +            }
    +        },
    +        PERSISTENT() {
    +            @Override
    +            boolean isPersistent() {
    +                return true;
    +            }
    +
    +            @Override
    +            boolean isRecursive() {
    +                return false;
    +            }
    +        },
    +        PERSISTENT_RECURSIVE() {
    +            @Override
    +            boolean isPersistent() {
    +                return true;
    +            }
    +
    +            @Override
    +            boolean isRecursive() {
    +                return true;
    +            }
    +        }
    +        ;
    +
    +        abstract boolean isPersistent();
    +        abstract boolean isRecursive();
    +    }
    +
    +    private final Map<String, Map<Watcher, Type>> watchTable =
    +        new HashMap<>();
    +
    +    private final Map<Watcher, Set<String>> watch2Paths =
    +        new HashMap<>();
     
    -    private final HashMap<Watcher, HashSet<String>> watch2Paths =
    -        new HashMap<Watcher, HashSet<String>>();
    +    private int recursiveWatchQty = 0;    // guarded by sync
    +
    +    // visible for testing
    +    synchronized int getRecursiveWatchQty() {
    +        return recursiveWatchQty;
    +    }
     
         synchronized int size(){
             int result = 0;
    -        for(Set<Watcher> watches : watchTable.values()) {
    +        for(Map<Watcher, Type> watches : watchTable.values()) {
                 result += watches.size();
             }
             return result;
         }
     
    -    synchronized void addWatch(String path, Watcher watcher) {
    -        HashSet<Watcher> list = watchTable.get(path);
    +    synchronized void addWatch(String path, Watcher watcher, 
WatchManager.Type type) {
    +        Map<Watcher, Type> list = watchTable.get(path);
             if (list == null) {
                 // don't waste memory if there are few watches on a node
                 // rehash when the 4th entry is added, doubling size thereafter
                 // seems like a good compromise
    -            list = new HashSet<Watcher>(4);
    +            list = new HashMap<>(4);
    --- End diff --
    
    Good point - this was just cargo-cult coding on my part. However, 
internally `HashSet` uses a `HashMap` so the implementation is the same.


---

Reply via email to