Secondo Sortby分析

函数代码

  1 /*
  2 3.2 Operator ~sortby~
  3 
  4 这个操作符类型由给定的属性列表流元组。
  5 对于每个属性可以指定清单应按升序(ASC)或降序(DESC)对属性的顺序。
  6 
  7 3.2.1 Type mapping function of operator ~sortby~
  8 
  9 类型映射~sortby~ is
 10 
 11 ---- ((stream (tuple ((x1 t1)...(xn tn)))) ((xi1 asc/desc) ... (xij asc/desc)))
 12              -> ((stream (tuple ((x1 t1)...(xn tn))))
 13                  APPEND (j i1 true/false i2 true/false ... ij true/false))
 14 ----
 15 
 16 类型映射函数确定给定属性列表的属性索引,并生成相应的排序顺序规范。
 17 属性的数量,属性索引和布尔标志,表示一个提升(真)或降排序顺序
 18 (假),被添加到值映射函数的参数列表中
 19 
 20 */
 21 
 22 ListExpr SortByTypeMap( ListExpr args )//类型映射
 23 {
 24   NList type(args);
 25 
 26   // 检查表的长度
 27   if ( !type.hasLength(2) )
 28   {
 29     return NList::typeError(
 30         "Operator sortby expects a list of "
 31         "length two.");
 32   }
 33 
 34   NList streamDesc = type.first();
 35   NList attrDesc = type.second();
 36 
 37   // 检查第一个参数是否是一个元组流
 38   NList attr;
 39   if ( !streamDesc.checkStreamTuple(attr) )
 40   {
 41     return NList::typeError(
 42         "Operator sortby: first argument is not a tuple stream!"
 43         "Operator received: " + streamDesc.convertToString() );
 44   }
 45 
 46   // 检查是否有一个有效的元组描述
 47   if ( !IsTupleDescription(attr.listExpr()) )
 48   {
 49     return NList::typeError(
 50         "Operator sortby: first argument does not "
 51         "contain a tuple description!"
 52         "Operator received: " + attr.convertToString() );
 53   }
 54 
 55   int numberOfSortAttrs = attrDesc.length();
 56 
 57   // 检查属性规范的长度
 58   if ( numberOfSortAttrs <= 0 )
 59   {
 60     return NList::typeError(
 61         "Operator sortby: sort order specification "
 62         "list may not be empty!");
 63   }
 64 
 65   NList sortDesc;
 66   sortDesc.append(NList(numberOfSortAttrs));
 67   NList rest = attrDesc;
 68 
 69   // 过程属性描述
 70   while( !rest.isEmpty() )
 71   {
 72     // 提取属性规范的第一个元素
 73     NList attrElem = rest.first();
 74 
 75     //切断第一个元素
 76     rest.rest();
 77 
 78     // attrelem可能是一个原子(不可选升序/降序说明符)
 79     // 或两个元素的表 (with asc/desc specifier)
 80     if ( !(attrElem.isAtom() || attrElem.length() == 2) )
 81     {
 82       return NList::typeError(
 83           "Operator sortby expects as second argument "
 84           "a list of (attrname [asc, desc])|attrname.");
 85     }
 86 
 87     string attrName;
 88 
 89     // 处理两种不同的情况
 90     if ( attrElem.length() == 2 )
 91     {
 92       // 检查类型attrelem
 93       if ( !(attrElem.first().isAtom() &&
 94              attrElem.first().isSymbol() &&
 95              attrElem.second().isAtom() &&
 96              attrElem.second().isSymbol() ) )
 97       {
 98         return NList::typeError(
 99             "Operator sortby expects as second argument a list"
100             " of (attrname [asc, desc])|attrname .\n"
101             "Operator sortby gets a list '"
102             + attrDesc.convertToString() + "'.");
103       }
104       attrName = attrElem.first().str();
105     }
106     else
107     {
108       // 检查attrelem型原子
109       if ( !(attrElem.isSymbol()) )
110       {
111         return NList::typeError(
112             "Operator sortby expects as second argument a list"
113             " of (attrname [asc, desc])|attrname .\n"
114             "Operator sortby gets a list '"
115             + attrDesc.convertToString() + "'.");
116       }
117       attrName = attrElem.str();
118     }
119 
120     // 确定属性指标(1-based)
121     ListExpr attrType;
122     int j = FindAttribute(attr.listExpr(), attrName, attrType);
123 
124     // 确定升序/降序说明符
125     if (j > 0)
126     {
127       bool isAscending = true;
128 
129       if( attrElem.length() == 2 )
130       {
131          if ( !( attrElem.second().str() == "asc" ||
132                  attrElem.second().str() == "desc" ) )
133          {
134            return NList::typeError(
135                "Operator sortby sorting criteria must "
136                "be asc or desc, not '"
137                + attrElem.second().convertToString() + "'!");
138          }
139          isAscending = attrElem.second().str() == "asc" ? true : false;
140       }
141 
142       sortDesc.append(NList(j));
143       sortDesc.append(NList(isAscending, isAscending));
144     }
145     else
146     {
147       return NList::typeError(
148           "Operator sortby: attribute name '" + attrName +
149           "' is not known.\nKnown Attribute(s): "
150           + attr.convertToString());
151     }
152   }
153 
154   return NList(NList(Symbol::APPEND()), sortDesc, streamDesc).listExpr();
155 }
156 /*
157 
158 3.2.2 规范操作 ~sortby~
159 
160 */
161 const string SortBySpec  = "( ( \"Signature\" \"Syntax\" \"Meaning\" "
162                            "\"Example\" ) "
163                            "( <text>((stream (tuple([a1:d1, ... ,an:dn])))"
164                            " ((xi1 asc/desc) ... (xij [asc/desc]))) -> "
165                            "(stream (tuple([a1:d1, ... ,an:dn])))</text--->"
166                            "<text>_ sortby [list]</text--->"
167                            "<text>Sorts an input stream according to a list "
168                            "of attributes ai1 ... aij. For each attribute one "
169                            "may specify the sorting order (asc/desc). If no "
170                            "order is specified, ascending is assumed."
171                            "</text--->"
172                            "<text>query employee feed sortby[DeptNo asc] "
173                            "consume</text--->"
174                               ") )";
175 
176 /*
177 3.2.3 定义的算子~sortby~
178 
179 */
180 Operator extrelsortby (
181          "sortby",               // name
182          SortBySpec,              // specification
183          SortValueMap<2, false>,  // value mapping - first argument
184                                   // of sort order spec is 2
185          Operator::SimpleSelect,  // trivial selection function
186          SortByTypeMap            // type mapping
187 );
View Code

 

 

sortby的具体实现

  1 template<int firstArg, bool param>
  2 int SortValueMap(Word* args, Word& result, int message, Word& local, Supplier s)
  3 {
  4   bool traceProgress = false;
  5 
  6   // Operator sort2 (firstArg = 1, param = false)
  7   // args[0] : stream
  8   // args[1] : the number of sort attributes
  9   // args[3] : the index of the first sort attribute
 10   // args[4] : a boolean which indicates if sortorder should
 11   //           be asc (true) or desc (false)
 12   // args[5] : Same as 3 but for the second sort attribute
 13   // args[6] : Same as 4 but for the second sort attribute
 14   // ....
 15 
 16   // Operator sort2Param (firstArg = 4, param = true)
 17   // args[0] : stream
 18   // args[1] : operator's main memory in bytes
 19   // args[2] : maximum fan-in of merge phase
 20   // args[3] : I/O buffer size in bytes
 21   // args[4] : the number of sort attributes
 22   // args[5] : the index of the first sort attribute
 23   // args[6] : a boolean which indicates if sortorder should
 24   //           be asc (true) or desc (false)
 25   // args[7] : Same as 3 but for the second sort attribute
 26   // args[8] : Same as 4 but for the second sort attribute
 27   // ....
 28 
 29   // Operator sortby2 (firstArg = 2, param = false)
 30   // args[0] : stream
 31   // args[1] : sort attributes specification as list (ignored)
 32   // args[2] : the number of sort attributes
 33   // args[3] : the index of the first sort attribute
 34   // args[4] : a boolean which indicates if sortorder should
 35   //           be asc (true) or desc (false)
 36   // args[5] : Same as 3 but for the second sort attribute
 37   // args[6] : Same as 4 but for the second sort attribute
 38   // ....
 39 
 40   // Operator sortby2Param (firstArg = 5, param = true)
 41   // args[0] : stream
 42   // args[1] : sort attributes specification as list (ignored)
 43   // args[2] : operator's main memory in bytes
 44   // args[3] : maximum fan-in of merge phase
 45   // args[4] : I/O buffer size in bytes
 46   // args[5] : the number of sort attributes
 47   // args[6] : the index of the first sort attribute
 48   // args[7] : a boolean which indicates if sortorder should
 49   //           be asc (true) or desc (false)
 50   // args[8] : Same as 3 but for the second sort attribute
 51   // args[9] : Same as 4 but for the second sort attribute
 52   // ....
 53 
 54   SortLocalInfo* li;
 55   li = static_cast<SortLocalInfo*>( local.addr );
 56 
 57   switch(message)
 58   {
 59     case OPEN:
 60     {
 61       if (li)
 62       {
 63         delete li;
 64       }
 65 
 66       li = new SortLocalInfo();
 67       local.addr = li;
 68 
 69       // at this point the local value is well defined
 70       // afterwards progress request calls are
 71       // allowed.
 72 
 73       li->ptr = 0;
 74 
 75       qp->Open(args[0].addr);
 76 
 77       return 0;
 78     }
 79 
 80     case REQUEST:
 81     {
 82       if ( li->ptr == 0 )
 83       {
 84         SortOrderSpecification spec;
 85         int nAttrCount = StdTypes::GetInt( args[firstArg] );
 86         for(int i = 1; i <= nAttrCount; i++)
 87         {
 88           int j = firstArg + (2*i - 1);
 89           int attrIndex = StdTypes::GetInt( args[j] );
 90           bool isAsc = StdTypes::GetBool( args[j+1] );
 91           spec.push_back(pair<int, bool>(attrIndex, isAsc));
 92         };
 93 
 94         //Sorting is done in the following constructor. It was moved from
 95         //OPEN to REQUEST to avoid long delays in the OPEN method, which are
 96         //a problem for progress estimation
 97         if ( param )
 98         {
 99           int idx = firstArg - 3;
100           int maxMemSize = StdTypes::GetInt( args[idx] );
101           int maxFanIn = StdTypes::GetInt( args[idx+1] );
102           int ioBufferSize = StdTypes::GetInt( args[idx+2] );
103 
104           size_t fan = maxFanIn < 0 ? UINT_MAX : (size_t)maxFanIn;
105           size_t mem = maxMemSize < 0 ? UINT_MAX : (size_t)maxMemSize;
106           size_t buf = ioBufferSize < 0 ? UINT_MAX : (size_t)ioBufferSize;
107 
108           li->ptr = new SortAlgorithm(args[0], spec, li, s, fan, mem, buf);
109         }
110         else
111         {
112           li->ptr = new SortAlgorithm(args[0], spec, li, s);
113         }
114       }
115 
116       SortAlgorithm* sa = li->ptr;
117 
118       result.setAddr( sa->NextResultTuple() );
119       li->returned++;
120       return result.addr != 0 ? YIELD : CANCEL;
121     }
122 
123     case CLOSE:
124     {
125       // Note: object deletion is handled in OPEN and CLOSEPROGRESS
126       qp->Close(args[0].addr);
127       return 0;
128     }
129 
130 
131     case CLOSEPROGRESS:
132     {
133       if (li)
134       {
135         delete li;
136         local.addr = 0;
137       }
138       return 0;
139     }
140 
141     case REQUESTPROGRESS:
142     {
143       ProgressInfo p1;
144       ProgressInfo *pRes;
145       const double uSortBy = 0.0000873; //millisecs per byte input and sort
146     // old constant 0.000396;   
147       const double vSortBy = 0.0000243;  //millisecs per byte output
148         // old constant 0.000194;  
149       const double oSortBy = 0.00004;   //offset due to writing to disk
150             //not yet measurable
151 
152       // constants determined in file ExtRelation-C++/ConstantsExtendStream
153 
154 
155 
156       pRes = (ProgressInfo*) result.addr;
157 
158       if( !li )
159       {
160         return CANCEL;
161       }
162       else
163       {
164         if (qp->RequestProgress(args[0].addr, &p1))
165         {
166           // -------------------------------------------
167           // Result cardinality
168           // -------------------------------------------
169 
170           pRes->Card = li->returned == 0 ? p1.Card : li->read;
171           pRes->CopySizes(p1);
172 
173           // -------------------------------------------
174           // Total time
175           // -------------------------------------------
176 
177           pRes->Time = p1.Time
178             + pRes->Card * p1.SizeExt * (uSortBy + oSortBy * li->state)
179             + pRes->Card * p1.SizeExt * vSortBy
180             + li->intTuplesTotal * p1.Size * (2 * vSortBy);
181 
182           // -------------------------------------------
183           // Total progress
184           // -------------------------------------------
185 
186           pRes->Progress =
187             (p1.Progress * p1.Time
188              + li->read * p1.SizeExt * (uSortBy + oSortBy * li->state)
189              + li->returned * p1.SizeExt * vSortBy
190              + li->intTuplesProc * p1.SizeExt * (2 * vSortBy) )
191             / pRes->Time;
192 
193           // -------------------------------------------
194           // Blocking time
195           // -------------------------------------------
196 
197           // Estimated time until first result tuple is ready
198           pRes->BTime = p1.Time
199             + pRes->Card * p1.SizeExt * (uSortBy + oSortBy * li->state)
200             + li->intTuplesTotal * p1.SizeExt * (2 * vSortBy);
201 
202           // -------------------------------------------
203           // Blocking progress
204           // -------------------------------------------
205 
206           pRes->BProgress =
207             (p1.Progress * p1.Time
208                 + li->read * p1.SizeExt * (uSortBy + oSortBy * li->state)
209                 + li->intTuplesProc * p1.SizeExt * (2 * vSortBy))
210                 / pRes->BTime;
211 
212           if ( traceProgress )
213           {
214             cmsg.info() << "p1->Card: " << p1.Card
215                         << ", p1.Time: " << p1.Time
216                         << ", p1.Progress: " << p1.Progress
217                         << endl
218                         << "pRes->Time: " << pRes->Time
219                         << ", pRes->Progress: " << pRes->Progress
220                         << endl
221                         << ", intTuples: " << li->intTuplesProc
222                         << "/" << li->intTuplesTotal
223                         << endl;
224             cmsg.send();
225           }
226 
227           return YIELD;
228         }
229         else
230         {
231           return CANCEL;
232         }
233       }
234     }
235   }
236   return 0;
237 }
View Code

 

posted @ 2016-11-21 16:40  DemonSword  阅读(108)  评论(0)    收藏  举报