You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by na...@apache.org on 2009/09/01 23:36:29 UTC

svn commit: r810253 - in /hadoop/hive/branches/branch-0.4: ./ ql/src/java/org/apache/hadoop/hive/ql/exec/ ql/src/test/queries/clientpositive/ ql/src/test/results/clientpositive/

Author: namit
Date: Tue Sep  1 21:36:29 2009
New Revision: 810253

URL: http://svn.apache.org/viewvc?rev=810253&view=rev
Log:
HIVE-790. Bug in union and script. (Ning Zhang via namit)


Added:
    hadoop/hive/branches/branch-0.4/ql/src/test/queries/clientpositive/union_script.q
    hadoop/hive/branches/branch-0.4/ql/src/test/results/clientpositive/union_script.q.out
Modified:
    hadoop/hive/branches/branch-0.4/CHANGES.txt
    hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java
    hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java
    hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/GroupByOperator.java
    hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java
    hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/MapOperator.java
    hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/Operator.java
    hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/UnionOperator.java

Modified: hadoop/hive/branches/branch-0.4/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/hive/branches/branch-0.4/CHANGES.txt?rev=810253&r1=810252&r2=810253&view=diff
==============================================================================
--- hadoop/hive/branches/branch-0.4/CHANGES.txt (original)
+++ hadoop/hive/branches/branch-0.4/CHANGES.txt Tue Sep  1 21:36:29 2009
@@ -532,6 +532,8 @@
 
     HIVE-794. MergeTask should use COMPRESSRESULT. (Saurabh Nanda via zshao)
 
+    HIVE-790. Bug in union and script. (Ning Zhang via namit)
+
 Release 0.3.1 - Unreleased
 
   INCOMPATIBLE CHANGES

Modified: hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java
URL: http://svn.apache.org/viewvc/hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java?rev=810253&r1=810252&r2=810253&view=diff
==============================================================================
--- hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java (original)
+++ hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java Tue Sep  1 21:36:29 2009
@@ -565,9 +565,8 @@
    * All done
    * 
    */
-  public void close(boolean abort) throws HiveException {
+  public void closeOp(boolean abort) throws HiveException {
     LOG.trace("Join Op close");
-    super.close(abort);
   }
 
   @Override

Modified: hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java
URL: http://svn.apache.org/viewvc/hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java?rev=810253&r1=810252&r2=810253&view=diff
==============================================================================
--- hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java (original)
+++ hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java Tue Sep  1 21:36:29 2009
@@ -156,11 +156,7 @@
     }
   }
 
-  public void close(boolean abort) throws HiveException {
-    if (state == State.CLOSE) 
-      return;
-  
-    state = State.CLOSE;
+  public void closeOp(boolean abort) throws HiveException {
     if (!abort) {
       if (outWriter != null) {
         try {

Modified: hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/GroupByOperator.java
URL: http://svn.apache.org/viewvc/hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/GroupByOperator.java?rev=810253&r1=810252&r2=810253&view=diff
==============================================================================
--- hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/GroupByOperator.java (original)
+++ hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/GroupByOperator.java Tue Sep  1 21:36:29 2009
@@ -701,7 +701,7 @@
    * We need to forward all the aggregations to children.
    * 
    */
-  public void close(boolean abort) throws HiveException {
+  public void closeOp(boolean abort) throws HiveException {
     if (!abort) {
       try {
         // If there is no grouping key and no row came to this operator
@@ -750,7 +750,6 @@
         throw new HiveException(e);
       }
     }
-    super.close(abort);
   }
 
   // Group by contains the columns needed - no need to aggregate from children

Modified: hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java
URL: http://svn.apache.org/viewvc/hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java?rev=810253&r1=810252&r2=810253&view=diff
==============================================================================
--- hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java (original)
+++ hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java Tue Sep  1 21:36:29 2009
@@ -322,11 +322,10 @@
     return "MAPJOIN";
   }
   
-  public void close(boolean abort) throws HiveException {
+  public void closeOp(boolean abort) throws HiveException {
     for (File hTbl : hTables) {
       deleteDir(hTbl);
     }
-    super.close(abort);
   }
   
   private void deleteDir(File dir) {

Modified: hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/MapOperator.java
URL: http://svn.apache.org/viewvc/hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/MapOperator.java?rev=810253&r1=810252&r2=810253&view=diff
==============================================================================
--- hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/MapOperator.java (original)
+++ hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/MapOperator.java Tue Sep  1 21:36:29 2009
@@ -63,6 +63,8 @@
   transient private boolean isPartitioned;
   private Map<MapInputPath, MapOpCtx> opCtxMap;
   
+  private ArrayList<Operator<? extends Serializable>> extraChildrenToClose = null;
+  
   private static class MapInputPath {
     String path;
     String alias;
@@ -280,13 +282,34 @@
   public void initializeOp(Configuration hconf) throws HiveException {
     // set that parent initialization is done and call initialize on children
     state = State.INIT;
+    List<Operator<? extends Serializable>> children = getChildOperators();
+
     for (Entry<MapInputPath, MapOpCtx> entry : opCtxMap.entrySet()) {
       // Add alias, table name, and partitions to hadoop conf so that their children will
       // inherit these
       HiveConf.setVar(hconf, HiveConf.ConfVars.HIVETABLENAME, entry.getValue().tableName);
       HiveConf.setVar(hconf, HiveConf.ConfVars.HIVEPARTITIONNAME, entry.getValue().partName);
       Operator<? extends Serializable> op = entry.getKey().op;
-      op.initialize(hconf, new ObjectInspector[]{entry.getValue().getRowObjectInspector()});
+        
+      // op is not in the children list, so need to remember it and close it afterwards
+      if ( children.indexOf(op) == -1 ) {
+        if ( extraChildrenToClose == null ) {
+          extraChildrenToClose = new ArrayList<Operator<? extends Serializable>>();
+        }
+        extraChildrenToClose.add(op);
+      }
+     op.initialize(hconf, new ObjectInspector[]{entry.getValue().getRowObjectInspector()});
+    }
+  }
+  
+  /**
+   * close extra child operators that are initialized but are not executed.
+   */
+  public void closeOp(boolean abort) throws HiveException {
+    if ( extraChildrenToClose != null ) {
+      for (Operator<? extends Serializable> op : extraChildrenToClose) {
+        op.close(abort);
+      }
     }
   }
 

Modified: hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/Operator.java
URL: http://svn.apache.org/viewvc/hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/Operator.java?rev=810253&r1=810252&r2=810253&view=diff
==============================================================================
--- hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/Operator.java (original)
+++ hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/Operator.java Tue Sep  1 21:36:29 2009
@@ -56,7 +56,16 @@
   // only after that operation has been performed on all the parents. This will require
   // initializing the whole tree in all the mappers (which might be required for mappers
   // spanning multiple files anyway, in future)
-  public static enum State { UNINIT, INIT, CLOSE };
+  public static enum State { 
+    UNINIT,   // initialize() has not been called
+    INIT,     // initialize() has been called and close() has not been called,
+              // or close() has been called but one of its parent is not closed.
+    CLOSE     // all its parents operators are in state CLOSE and called close() 
+              // to children. Note: close() being called and its state being CLOSE is
+              // difference since close() could be called but state is not CLOSE if 
+              // one of its parent is not in state CLOSE..
+  };
+
   transient protected State state = State.UNINIT;
 
   static {
@@ -359,11 +368,40 @@
     LOG.debug("End group Done");
   }
 
+
+  private boolean allInitializedParentsAreClosed() {
+    if (parentOperators != null) {
+      for(Operator<? extends Serializable> parent: parentOperators) {
+        if (!(parent.state == State.CLOSE ||
+              parent.state == State.UNINIT)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+  
+  // This close() function does not need to be synchronized
+  // since it is called by its parents' main thread, so no
+  // more than 1 thread should call this close() function.
   public void close(boolean abort) throws HiveException {
+    
     if (state == State.CLOSE) 
       return;
-
+    
+   // check if all parents are finished
+    if (!allInitializedParentsAreClosed()) 
+      return;
+    
+    // set state as CLOSE as long as all parents are closed
+    // state == CLOSE doesn't mean all children are also in state CLOSE
+    state = State.CLOSE;
+    LOG.info(id + " finished. closing... ");
+ 
     LOG.info(id + " forwarded " + cntr + " rows");
+    
+   // call the operator specific close routine
+    closeOp(abort);
 
     try {
       logStats();
@@ -373,14 +411,21 @@
       for(Operator<? extends Serializable> op: childOperators) {
         op.close(abort);
       }
-      state = State.CLOSE;
-
-      LOG.info("Close done");
+      LOG.info(id + " Close done");
     } catch (HiveException e) {
       e.printStackTrace();
       throw e;
     }
   }
+  
+  /**
+   * Operator specific close routine. Operators which inherents this
+   * class should overwrite this funtion for their specific cleanup
+   * routine.
+   */
+  protected void closeOp(boolean abort) throws HiveException {
+  }
+
 
   /**
    * Unlike other operator interfaces which are called from map or reduce task,

Modified: hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/UnionOperator.java
URL: http://svn.apache.org/viewvc/hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/UnionOperator.java?rev=810253&r1=810252&r2=810253&view=diff
==============================================================================
--- hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/UnionOperator.java (original)
+++ hadoop/hive/branches/branch-0.4/ql/src/java/org/apache/hadoop/hive/ql/exec/UnionOperator.java Tue Sep  1 21:36:29 2009
@@ -110,23 +110,23 @@
   }
   
   @Override
-  public void process(Object row, int tag) throws HiveException {
+  public synchronized void process(Object row, int tag) throws HiveException {
 
     StructObjectInspector soi = parentObjInspectors[tag];
-      List<? extends StructField> fields = parentFields[tag];
+    List<? extends StructField> fields = parentFields[tag];
 
-      if (needsTransform[tag]) {
-        for (int c = 0; c < fields.size(); c++) {
-          outputRow.set(c, columnTypeResolvers[c].convertIfNecessary(
-              soi.getStructFieldData(row, fields.get(c)),
-              fields.get(c).getFieldObjectInspector()));
-        }
-        forward(outputRow, outputObjInspector);
-      } else {
-        forward(row, inputObjInspectors[tag]);
+    if (needsTransform[tag]) {
+      for (int c = 0; c < fields.size(); c++) {
+        outputRow.set(c, columnTypeResolvers[c].convertIfNecessary(
+            soi.getStructFieldData(row, fields.get(c)),
+            fields.get(c).getFieldObjectInspector()));
       }
+      forward(outputRow, outputObjInspector);
+    } else {
+      forward(row, inputObjInspectors[tag]);
+    }
   }
-
+  
   /**
    * @return the name of the operator
    */

Added: hadoop/hive/branches/branch-0.4/ql/src/test/queries/clientpositive/union_script.q
URL: http://svn.apache.org/viewvc/hadoop/hive/branches/branch-0.4/ql/src/test/queries/clientpositive/union_script.q?rev=810253&view=auto
==============================================================================
--- hadoop/hive/branches/branch-0.4/ql/src/test/queries/clientpositive/union_script.q (added)
+++ hadoop/hive/branches/branch-0.4/ql/src/test/queries/clientpositive/union_script.q Tue Sep  1 21:36:29 2009
@@ -0,0 +1,7 @@
+select * from (
+  select transform(key) using 'cat' as cola from src)s order by cola;
+
+select * from (
+  select transform(key) using 'cat' as cola from src
+  union all
+  select transform(key) using 'cat' as cola from src) s order by cola;

Added: hadoop/hive/branches/branch-0.4/ql/src/test/results/clientpositive/union_script.q.out
URL: http://svn.apache.org/viewvc/hadoop/hive/branches/branch-0.4/ql/src/test/results/clientpositive/union_script.q.out?rev=810253&view=auto
==============================================================================
--- hadoop/hive/branches/branch-0.4/ql/src/test/results/clientpositive/union_script.q.out (added)
+++ hadoop/hive/branches/branch-0.4/ql/src/test/results/clientpositive/union_script.q.out Tue Sep  1 21:36:29 2009
@@ -0,0 +1,1510 @@
+query: select * from (
+  select transform(key) using 'cat' as cola from src)s order by cola
+Input: default/src
+Output: file:/data/users/nzhang/work/790/790-trunk-apache-hive/build/ql/tmp/1290779299/10000
+0
+0
+0
+10
+100
+100
+103
+103
+104
+104
+105
+11
+111
+113
+113
+114
+116
+118
+118
+119
+119
+119
+12
+12
+120
+120
+125
+125
+126
+128
+128
+128
+129
+129
+131
+133
+134
+134
+136
+137
+137
+138
+138
+138
+138
+143
+145
+146
+146
+149
+149
+15
+15
+150
+152
+152
+153
+155
+156
+157
+158
+160
+162
+163
+164
+164
+165
+165
+166
+167
+167
+167
+168
+169
+169
+169
+169
+17
+170
+172
+172
+174
+174
+175
+175
+176
+176
+177
+178
+179
+179
+18
+18
+180
+181
+183
+186
+187
+187
+187
+189
+19
+190
+191
+191
+192
+193
+193
+193
+194
+195
+195
+196
+197
+197
+199
+199
+199
+2
+20
+200
+200
+201
+202
+203
+203
+205
+205
+207
+207
+208
+208
+208
+209
+209
+213
+213
+214
+216
+216
+217
+217
+218
+219
+219
+221
+221
+222
+223
+223
+224
+224
+226
+228
+229
+229
+230
+230
+230
+230
+230
+233
+233
+235
+237
+237
+238
+238
+239
+239
+24
+24
+241
+242
+242
+244
+247
+248
+249
+252
+255
+255
+256
+256
+257
+258
+26
+26
+260
+262
+263
+265
+265
+266
+27
+272
+272
+273
+273
+273
+274
+275
+277
+277
+277
+277
+278
+278
+28
+280
+280
+281
+281
+282
+282
+283
+284
+285
+286
+287
+288
+288
+289
+291
+292
+296
+298
+298
+298
+30
+302
+305
+306
+307
+307
+308
+309
+309
+310
+311
+311
+311
+315
+316
+316
+316
+317
+317
+318
+318
+318
+321
+321
+322
+322
+323
+325
+325
+327
+327
+327
+33
+331
+331
+332
+333
+333
+335
+336
+338
+339
+34
+341
+342
+342
+344
+344
+345
+348
+348
+348
+348
+348
+35
+35
+35
+351
+353
+353
+356
+360
+362
+364
+365
+366
+367
+367
+368
+369
+369
+369
+37
+37
+373
+374
+375
+377
+378
+379
+382
+382
+384
+384
+384
+386
+389
+392
+393
+394
+395
+395
+396
+396
+396
+397
+397
+399
+399
+4
+400
+401
+401
+401
+401
+401
+402
+403
+403
+403
+404
+404
+406
+406
+406
+406
+407
+409
+409
+409
+41
+411
+413
+413
+414
+414
+417
+417
+417
+418
+419
+42
+42
+421
+424
+424
+427
+429
+429
+43
+430
+430
+430
+431
+431
+431
+432
+435
+436
+437
+438
+438
+438
+439
+439
+44
+443
+444
+446
+448
+449
+452
+453
+454
+454
+454
+455
+457
+458
+458
+459
+459
+460
+462
+462
+463
+463
+466
+466
+466
+467
+468
+468
+468
+468
+469
+469
+469
+469
+469
+47
+470
+472
+475
+477
+478
+478
+479
+480
+480
+480
+481
+482
+483
+484
+485
+487
+489
+489
+489
+489
+490
+491
+492
+492
+493
+494
+495
+496
+497
+498
+498
+498
+5
+5
+5
+51
+51
+53
+54
+57
+58
+58
+64
+65
+66
+67
+67
+69
+70
+70
+70
+72
+72
+74
+76
+76
+77
+78
+8
+80
+82
+83
+83
+84
+84
+85
+86
+87
+9
+90
+90
+90
+92
+95
+95
+96
+97
+97
+98
+98
+query: select * from (
+  select transform(key) using 'cat' as cola from src
+  union all
+  select transform(key) using 'cat' as cola from src) s order by cola
+Input: default/src
+Output: file:/data/users/nzhang/work/790/790-trunk-apache-hive/build/ql/tmp/1729338552/10000
+0
+0
+0
+0
+0
+0
+10
+10
+100
+100
+100
+100
+103
+103
+103
+103
+104
+104
+104
+104
+105
+105
+11
+11
+111
+111
+113
+113
+113
+113
+114
+114
+116
+116
+118
+118
+118
+118
+119
+119
+119
+119
+119
+119
+12
+12
+12
+12
+120
+120
+120
+120
+125
+125
+125
+125
+126
+126
+128
+128
+128
+128
+128
+128
+129
+129
+129
+129
+131
+131
+133
+133
+134
+134
+134
+134
+136
+136
+137
+137
+137
+137
+138
+138
+138
+138
+138
+138
+138
+138
+143
+143
+145
+145
+146
+146
+146
+146
+149
+149
+149
+149
+15
+15
+15
+15
+150
+150
+152
+152
+152
+152
+153
+153
+155
+155
+156
+156
+157
+157
+158
+158
+160
+160
+162
+162
+163
+163
+164
+164
+164
+164
+165
+165
+165
+165
+166
+166
+167
+167
+167
+167
+167
+167
+168
+168
+169
+169
+169
+169
+169
+169
+169
+169
+17
+17
+170
+170
+172
+172
+172
+172
+174
+174
+174
+174
+175
+175
+175
+175
+176
+176
+176
+176
+177
+177
+178
+178
+179
+179
+179
+179
+18
+18
+18
+18
+180
+180
+181
+181
+183
+183
+186
+186
+187
+187
+187
+187
+187
+187
+189
+189
+19
+19
+190
+190
+191
+191
+191
+191
+192
+192
+193
+193
+193
+193
+193
+193
+194
+194
+195
+195
+195
+195
+196
+196
+197
+197
+197
+197
+199
+199
+199
+199
+199
+199
+2
+2
+20
+20
+200
+200
+200
+200
+201
+201
+202
+202
+203
+203
+203
+203
+205
+205
+205
+205
+207
+207
+207
+207
+208
+208
+208
+208
+208
+208
+209
+209
+209
+209
+213
+213
+213
+213
+214
+214
+216
+216
+216
+216
+217
+217
+217
+217
+218
+218
+219
+219
+219
+219
+221
+221
+221
+221
+222
+222
+223
+223
+223
+223
+224
+224
+224
+224
+226
+226
+228
+228
+229
+229
+229
+229
+230
+230
+230
+230
+230
+230
+230
+230
+230
+230
+233
+233
+233
+233
+235
+235
+237
+237
+237
+237
+238
+238
+238
+238
+239
+239
+239
+239
+24
+24
+24
+24
+241
+241
+242
+242
+242
+242
+244
+244
+247
+247
+248
+248
+249
+249
+252
+252
+255
+255
+255
+255
+256
+256
+256
+256
+257
+257
+258
+258
+26
+26
+26
+26
+260
+260
+262
+262
+263
+263
+265
+265
+265
+265
+266
+266
+27
+27
+272
+272
+272
+272
+273
+273
+273
+273
+273
+273
+274
+274
+275
+275
+277
+277
+277
+277
+277
+277
+277
+277
+278
+278
+278
+278
+28
+28
+280
+280
+280
+280
+281
+281
+281
+281
+282
+282
+282
+282
+283
+283
+284
+284
+285
+285
+286
+286
+287
+287
+288
+288
+288
+288
+289
+289
+291
+291
+292
+292
+296
+296
+298
+298
+298
+298
+298
+298
+30
+30
+302
+302
+305
+305
+306
+306
+307
+307
+307
+307
+308
+308
+309
+309
+309
+309
+310
+310
+311
+311
+311
+311
+311
+311
+315
+315
+316
+316
+316
+316
+316
+316
+317
+317
+317
+317
+318
+318
+318
+318
+318
+318
+321
+321
+321
+321
+322
+322
+322
+322
+323
+323
+325
+325
+325
+325
+327
+327
+327
+327
+327
+327
+33
+33
+331
+331
+331
+331
+332
+332
+333
+333
+333
+333
+335
+335
+336
+336
+338
+338
+339
+339
+34
+34
+341
+341
+342
+342
+342
+342
+344
+344
+344
+344
+345
+345
+348
+348
+348
+348
+348
+348
+348
+348
+348
+348
+35
+35
+35
+35
+35
+35
+351
+351
+353
+353
+353
+353
+356
+356
+360
+360
+362
+362
+364
+364
+365
+365
+366
+366
+367
+367
+367
+367
+368
+368
+369
+369
+369
+369
+369
+369
+37
+37
+37
+37
+373
+373
+374
+374
+375
+375
+377
+377
+378
+378
+379
+379
+382
+382
+382
+382
+384
+384
+384
+384
+384
+384
+386
+386
+389
+389
+392
+392
+393
+393
+394
+394
+395
+395
+395
+395
+396
+396
+396
+396
+396
+396
+397
+397
+397
+397
+399
+399
+399
+399
+4
+4
+400
+400
+401
+401
+401
+401
+401
+401
+401
+401
+401
+401
+402
+402
+403
+403
+403
+403
+403
+403
+404
+404
+404
+404
+406
+406
+406
+406
+406
+406
+406
+406
+407
+407
+409
+409
+409
+409
+409
+409
+41
+41
+411
+411
+413
+413
+413
+413
+414
+414
+414
+414
+417
+417
+417
+417
+417
+417
+418
+418
+419
+419
+42
+42
+42
+42
+421
+421
+424
+424
+424
+424
+427
+427
+429
+429
+429
+429
+43
+43
+430
+430
+430
+430
+430
+430
+431
+431
+431
+431
+431
+431
+432
+432
+435
+435
+436
+436
+437
+437
+438
+438
+438
+438
+438
+438
+439
+439
+439
+439
+44
+44
+443
+443
+444
+444
+446
+446
+448
+448
+449
+449
+452
+452
+453
+453
+454
+454
+454
+454
+454
+454
+455
+455
+457
+457
+458
+458
+458
+458
+459
+459
+459
+459
+460
+460
+462
+462
+462
+462
+463
+463
+463
+463
+466
+466
+466
+466
+466
+466
+467
+467
+468
+468
+468
+468
+468
+468
+468
+468
+469
+469
+469
+469
+469
+469
+469
+469
+469
+469
+47
+47
+470
+470
+472
+472
+475
+475
+477
+477
+478
+478
+478
+478
+479
+479
+480
+480
+480
+480
+480
+480
+481
+481
+482
+482
+483
+483
+484
+484
+485
+485
+487
+487
+489
+489
+489
+489
+489
+489
+489
+489
+490
+490
+491
+491
+492
+492
+492
+492
+493
+493
+494
+494
+495
+495
+496
+496
+497
+497
+498
+498
+498
+498
+498
+498
+5
+5
+5
+5
+5
+5
+51
+51
+51
+51
+53
+53
+54
+54
+57
+57
+58
+58
+58
+58
+64
+64
+65
+65
+66
+66
+67
+67
+67
+67
+69
+69
+70
+70
+70
+70
+70
+70
+72
+72
+72
+72
+74
+74
+76
+76
+76
+76
+77
+77
+78
+78
+8
+8
+80
+80
+82
+82
+83
+83
+83
+83
+84
+84
+84
+84
+85
+85
+86
+86
+87
+87
+9
+9
+90
+90
+90
+90
+90
+90
+92
+92
+95
+95
+95
+95
+96
+96
+97
+97
+97
+97
+98
+98
+98
+98