⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 orderedtuples.java

📁 A framework written in Java for implementing high-level and dynamic languages, compiling them into J
💻 JAVA
字号:
package gnu.xquery.util;import gnu.lists.*;import gnu.mapping.*;import gnu.kawa.functions.NumberCompare;import gnu.kawa.xml.KNode;import gnu.kawa.xml.UntypedAtomic;/** Helper class used in conjunction with {@link OrderedMap}. * It has the tuples from the {@code for} and {@code let}-clauses, * as filtered by the {@code where}-clause. * * The tuples are sorted using a linked-list version of merge sort. * * The sequence of n tuples for m variables is represented using * an array of length n where each element is an array of length m. * A possible future optimization would be to instead use m * different arrays of of length n.  The advantage is that each * of the M arrays could have the "correct" type for each variable, * and so we avoid casts or boxing/unboxing. */public class OrderedTuples extends FilterConsumer{  /** The number of tuples. */  int n;  /** The sequence of tuples, in input (unsorted) order. */  Object[] tuples; // Actually: Object[][] tuples.  /** The compator functions.   * If there are k comparator, the array's length is 3*k.   * comps[3*i] is the i'th comparison function   *   (represented as a procedure on a tuple);   * comps[3*i+1] is the i'th set of flags encoded as a string;   * and comps[3*i+2] is the i'th collator   *   (either null or a NamedCollator).   */  Object[] comps;  /* The index of the first tuple, after sorting. */  int first;  /** Used to chain the tuples after sorting.   * I.e. if the i'th tuple (is sort order) is tuples[k],   * then the (i+1)'the sorted tuple is tuples[next[k]].   * The end of the list is indicated by -1.   */  int[] next;  /** The return clause, encoded as a procedure on a tuple. */  Procedure body;  public void writeObject(Object v)  {    if (n >= tuples.length)      {        Object[] tmp = new Object[2 * n];        System.arraycopy(tuples, 0, tmp, 0, n);        tuples = tmp;      }    tuples[n++] = v;  }  OrderedTuples ()  {    super(null);    tuples = new Object[10];  }  public static OrderedTuples make$V (Procedure body, Object[] comps)  {    OrderedTuples tuples = new OrderedTuples();    tuples.comps = comps;    tuples.body = body;    return tuples;  }  public void run$X (CallContext ctx)  throws Throwable  {    first = listsort(0);    emit(ctx);  }  void emit (CallContext ctx)  throws Throwable  {    for (int p = first; p >= 0; p = next[p])      emit(p, ctx);  }  void emit (int index, CallContext ctx)  throws Throwable  {    Object[] args = (Object[]) tuples[index];    body.checkN(args, ctx);    ctx.runUntilDone();  }  // The following sort routine is derived from Simon Tatham's listsort.c.  // However we use array indexes instead of pointers, and the next  // element instead of a next field.  // I.e. p->next is mapped to next[p].  // Instead of NULL we use -1.  /*   * Demonstration code for sorting a linked list.   *    * The algorithm used is Mergesort, because that works really well   * on linked lists, without requiring the O(N) extra space it needs   * when you do it on arrays.   *//* * This file is copyright 2001 Simon Tatham. *  * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: *  * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. *  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT.  IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */int cmp(int a, int b)  throws Throwable{  for (int i = 0;  i < comps.length;  i += 3)    {      Procedure comparator = (Procedure) comps[i];      String flags = (String) comps[i+1];      NamedCollator collator = (NamedCollator) comps[i+2];      if (collator == null)        collator = NamedCollator.codepointCollation;      Object val1 = comparator.applyN((Object[]) tuples[a]);      Object val2 = comparator.applyN((Object[]) tuples[b]);      val1 = KNode.atomicValue(val1);      val2 = KNode.atomicValue(val2);      if (val1 instanceof UntypedAtomic)        val1 = val1.toString();      if (val2 instanceof UntypedAtomic)        val2 = val2.toString();      boolean empty1 = SequenceUtils.isEmptySequence(val1);      boolean empty2 = SequenceUtils.isEmptySequence(val2);      if (empty1 && empty2)        continue;      int c;      if (empty1 || empty2)        {          char emptyOrder = flags.charAt(1);          c = empty1 == (emptyOrder == 'L') ? -1 : 1;        }      else        {          boolean isNaN1 = val1 instanceof Number            && Double.isNaN(((Number) val1).doubleValue());          boolean isNaN2 = val2 instanceof Number            && Double.isNaN(((Number) val2).doubleValue());          if (isNaN1 && isNaN2)            continue;          if (isNaN1 || isNaN2)            {              char emptyOrder = flags.charAt(1);              c = isNaN1 == (emptyOrder == 'L') ? -1 : 1;            }          else if (val1 instanceof Number && val2 instanceof Number)            c = NumberCompare.compare(val1, val2, false);          else            c = collator.compare(val1.toString(), val2.toString());        }      if (c == 0)        continue;      return flags.charAt(0) == 'A' ? c : -c;    }  return 0;}/* * This is the actual sort function. Notice that it returns the new * head of the list. (It has to, because the head will not * generally be the same element after the sort.) So unlike sorting * an array, where you can do *  *     sort(myarray); *  * you now have to do *  *     list = listsort(mylist); */  int listsort(int list) throws Throwable  {// indexes    int p, q, e, tail, oldhead;     int insize, nmerges, psize, qsize, i;    /*     * Silly special case: if `list' was passed in as NULL, return     * NULL immediately.     */    if (n == 0)	return -1;    next = new int[n];    for (i = 1; ;  i++)      {        if (i == n)          {            next[i-1] = -1;            break;          }        else          next[i-1] = i;      }    insize = 1;    for (;;) {        p = list;        list = -1;        tail = -1;        nmerges = 0;  /* count number of merges we do in this pass */        while (p >= 0) {            nmerges++;  /* there exists a merge to be done */            /* step `insize' places along from p */            q = p;            psize = 0;            for (i = 0; i < insize; i++) {                psize++;                q = next[q];                if (q < 0) break;            }            /* if q hasn't fallen off end, we have two lists to merge */            qsize = insize;            /* now we have two lists; merge them */            while (psize > 0 || (qsize > 0 && q >= 0)) {                /* decide whether next element of merge comes from p or q */                if (psize == 0) {		    /* p is empty; e must come from q. */		    e = q; q = next[q]; qsize--;		} else if (qsize == 0 || q < 0) {		    /* q is empty; e must come from p. */		    e = p; p = next[p]; psize--;		} else if (cmp(p,q) <= 0) {		    /* First element of p is lower (or same);		     * e must come from p. */		    e = p; p = next[p]; psize--;		} else {		    /* First element of q is lower; e must come from q. */		    e = q; q = next[q]; qsize--;		}                /* add the next element to the merged list */		if (tail >= 0)                  next[tail] = e;		else		    list = e;		tail = e;            }            /* now p has stepped `insize' places along, and q has too */            p = q;        }        next[tail] = -1;        /* If we have done only one merge, we're finished. */        if (nmerges <= 1)   /* allow for nmerges==0, the empty list case */            return list;        /* Otherwise repeat, merging lists twice the size */        insize *= 2;    }}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -