Package org.apache.helix.controller

Source Code of org.apache.helix.controller.HierarchicalDataHolder$Node

package org.apache.helix.controller;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import java.io.FileFilter;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.helix.manager.zk.ZkClient;
import org.apache.log4j.Logger;
import org.apache.zookeeper.data.Stat;


/**
* Generic class that will read the data given the root path.
*
*/
public class HierarchicalDataHolder<T>
{
  private static final Logger logger = Logger
      .getLogger(HierarchicalDataHolder.class.getName());
  AtomicReference<Node<T>> root;

  /**
   * currentVersion, gets updated when data is read from original source
   */
  AtomicLong currentVersion;
  private final ZkClient _zkClient;
  private final String _rootPath;
  private final FileFilter _filter;

  public HierarchicalDataHolder(ZkClient client, String rootPath,
      FileFilter filter)
  {
    this._zkClient = client;
    this._rootPath = rootPath;
    this._filter = filter;
    // Node<T> initialValue = new Node<T>();
    root = new AtomicReference<HierarchicalDataHolder.Node<T>>();
    currentVersion = new AtomicLong(1);
    refreshData();
  }

  public long getVersion()
  {
    return currentVersion.get();
  }

  public boolean refreshData()
  {
    Node<T> newRoot = new Node<T>();
    boolean dataChanged = refreshRecursively(root.get(), newRoot, _rootPath);
    if (dataChanged)
    {
      currentVersion.getAndIncrement();
      root.set(newRoot);
      return true;
    } else
    {
      return false;
    }
  }

  // private void refreshRecursively(Node<T> oldRoot, Stat oldStat, Node<T>
  // newRoot,Stat newStat, String path)
  private boolean refreshRecursively(Node<T> oldRoot, Node<T> newRoot,
      String path)
  {
    boolean dataChanged = false;
    Stat newStat = _zkClient.getStat(path);
    Stat oldStat = (oldRoot != null) ? oldRoot.stat : null;
    newRoot.name = path;
    if (newStat != null)
    {
      if (oldStat == null)
      {
        newRoot.stat = newStat;
        newRoot.data = _zkClient.<T> readData(path, true);
        dataChanged = true;
      } else if (newStat.equals(oldStat))
      {
        newRoot.stat = oldStat;
        newRoot.data = oldRoot.data;
      } else
      {
        dataChanged = true;
        newRoot.stat = newStat;
        newRoot.data = _zkClient.<T> readData(path, true);
      }
      if (newStat.getNumChildren() > 0)
      {
        List<String> children = _zkClient.getChildren(path);
        for (String child : children)
        {
          String newPath = path + "/" + child;
          Node<T> oldChild = (oldRoot != null && oldRoot.children != null) ? oldRoot.children
              .get(child) : null;
          if (newRoot.children == null)
          {
            newRoot.children = new ConcurrentHashMap<String, HierarchicalDataHolder.Node<T>>();
          }
          if (!newRoot.children.contains(child))
          {
            newRoot.children.put(child, new Node<T>());
          }
          Node<T> newChild = newRoot.children.get(child);
          boolean childChanged = refreshRecursively(oldChild, newChild, newPath);
          dataChanged = dataChanged || childChanged;
        }
      }
    } else
    {
      logger.info(path + " does not exist");
    }
    return dataChanged;
  }

  static class Node<T>
  {
    String name;
    Stat stat;
    T data;
    ConcurrentHashMap<String, Node<T>> children;

  }

  public void print()
  {
    logger.info("START "+ _rootPath);
    LinkedList<Node<T>> stack = new LinkedList<HierarchicalDataHolder.Node<T>>();
    stack.push(root.get());
    while (!stack.isEmpty())
    {
      Node<T> pop = stack.pop();
      if (pop != null)
      {
        logger.info("name:"+ pop.name);
        logger.info("\tdata:"+pop.data);
        if (pop.children != null)
        {
          for (Node<T> child : pop.children.values())
          {
            stack.push(child);
          }
        }
      }
    }
    logger.info("END "+ _rootPath);
  }
}
TOP

Related Classes of org.apache.helix.controller.HierarchicalDataHolder$Node

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.