[ 
https://issues.apache.org/jira/browse/DRILL-4726?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15468359#comment-15468359
 ] 

ASF GitHub Bot commented on DRILL-4726:
---------------------------------------

Github user paul-rogers commented on a diff in the pull request:

    https://github.com/apache/drill/pull/574#discussion_r77705853
  
    --- Diff: 
exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFunctionRegistry.java
 ---
    @@ -218,4 +302,141 @@ private void 
registerOperatorsWithoutInference(DrillOperatorTable operatorTable)
           }
         }
       }
    +
    +  /**
    +   * Function registry holder. Stores function implementations by jar 
name, function name.
    +   */
    +  private class GenericRegistryHolder<T, U> {
    +    private final ReadWriteLock readWriteLock = new 
ReentrantReadWriteLock();
    +    private final AutoCloseableLock readLock = new 
AutoCloseableLock(readWriteLock.readLock());
    +    private final AutoCloseableLock writeLock = new 
AutoCloseableLock(readWriteLock.writeLock());
    +
    +    // jar name, Map<function name, List<signature>
    +    private final Map<T, Map<T, List<T>>> jars;
    +
    +    // function name, Map<signature, function holder>
    +    private final Map<T, Map<T, U>> functions;
    +
    +    public GenericRegistryHolder() {
    +      this.functions = Maps.newHashMap();
    +      this.jars = Maps.newHashMap();
    +    }
    +
    +    public void addJar(T jName, Map<T, Pair<T, U>> sNameMap) {
    +      try (AutoCloseableLock lock = writeLock.open()) {
    +        Map<T, List<T>> map = jars.get(jName);
    +        if (map != null) {
    +          removeAllByJar(jName);
    +        }
    +        map = Maps.newHashMap();
    +        jars.put(jName, map);
    +
    +        for (Entry<T, Pair<T, U>> entry : sNameMap.entrySet()) {
    +          T sName = entry.getKey();
    +          Pair<T, U> pair = entry.getValue();
    +          addFunction(jName, pair.getKey(), sName, pair.getValue());
    +        }
    +      }
    +    }
    +
    +    public void removeJar(T jName) {
    +      try (AutoCloseableLock lock = writeLock.open()) {
    +        removeAllByJar(jName);
    +      }
    +    }
    +
    +    public List<T> getAllJarNames() {
    +      try (AutoCloseableLock lock = readLock.open()) {
    +        return Lists.newArrayList(jars.keySet());
    +      }
    +    }
    +
    +    public List<T> getAllFunctionNames(T jName) {
    +      try  (AutoCloseableLock lock = readLock.open()){
    +        Map<T, List<T>> map = jars.get(jName);
    +        return map == null ? Lists.<T>newArrayList() : 
Lists.newArrayList(map.keySet());
    +      }
    +    }
    +
    +    public ListMultimap<T, U> getAllFunctionsWithHolders() {
    +      try (AutoCloseableLock lock = readLock.open()) {
    +        ListMultimap<T, U> multimap = ArrayListMultimap.create();
    +        for (Entry<T, Map<T, U>> entry : functions.entrySet()) {
    +          multimap.putAll(entry.getKey(), 
Lists.newArrayList(entry.getValue().values()));
    +        }
    +        return multimap;
    +      }
    +    }
    +
    +    public ListMultimap<T, T> getAllFunctionsWithSignatures() {
    +      try (AutoCloseableLock lock = readLock.open()) {
    +        ListMultimap<T, T> multimap = ArrayListMultimap.create();
    +        for (Entry<T, Map<T, U>> entry : functions.entrySet()) {
    +          multimap.putAll(entry.getKey(), 
Lists.newArrayList(entry.getValue().keySet()));
    +        }
    +        return multimap;
    +      }
    +    }
    +
    +    public List<U> getHoldersByFunctionName(T fName) {
    +      try (AutoCloseableLock lock = readLock.open()) {
    +        Map<T, U> map = functions.get(fName);
    +        return map == null ? Lists.<U>newArrayList() : 
Lists.newArrayList(map.values());
    +      }
    +    }
    +
    +    public boolean containsJar(T jName) {
    +      try (AutoCloseableLock lock = readLock.open()) {
    +        return jars.containsKey(jName);
    +      }
    +    }
    +
    +    public int functionsSize() {
    +      try (AutoCloseableLock lock = readLock.open()) {
    +        return functions.size();
    +      }
    +    }
    +
    +    private void addFunction(T jName, T fName, T sName, U fHolder) {
    +      Map<T, List<T>> map = jars.get(jName);
    +
    +      List<T> list = map.get(fName);
    +      if (list == null) {
    +        list = Lists.newArrayList();
    +        map.put(fName, list);
    +      }
    +
    +      if (!list.contains(sName)) {
    +        list.add(sName);
    +
    +        Map<T, U> sigsMap = functions.get(fName);
    +        if (sigsMap == null) {
    +          sigsMap = Maps.newHashMap();
    +          functions.put(fName, sigsMap);
    +        }
    +
    +        U u = sigsMap.get(sName);
    --- End diff --
    
    Here U is a FuncHolder? We checked if the signature map already has a 
function associated with it and we ignore the new function if so. Is that the 
right behavior? Or, should an exception be thrown? If we throw an exception, 
should we clean up the partially-completed work for the current jar? Or, are we 
saying that the first function wins and subsequent identical signatures are 
silently ignored? In any case, we should document that policy in a comment.


> Dynamic UDFs support
> --------------------
>
>                 Key: DRILL-4726
>                 URL: https://issues.apache.org/jira/browse/DRILL-4726
>             Project: Apache Drill
>          Issue Type: New Feature
>    Affects Versions: 1.6.0
>            Reporter: Arina Ielchiieva
>            Assignee: Arina Ielchiieva
>             Fix For: Future
>
>
> Allow register UDFs without  restart of Drillbits.
> Design is described in document below:
> https://docs.google.com/document/d/1FfyJtWae5TLuyheHCfldYUpCdeIezR2RlNsrOTYyAB4/edit?usp=sharing
>  



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to