]> review.fuel-infra Code Review - packages/trusty/mysql-wsrep-5.6.git/blob
28d24ac621e9ba5870a58ef8fe5c4f3d13ccdbf6
[packages/trusty/mysql-wsrep-5.6.git] /
1 /*
2  *  Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; version 2 of the License.
7  *
8  *  This program is distributed in the hope that it will be useful,
9  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  *  GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License
14  *  along with this program; if not, write to the Free Software
15  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
16  */
17
18 package com.mysql.clusterj.tie;
19
20 import java.nio.ByteBuffer;
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import com.mysql.clusterj.core.store.Column;
25 import com.mysql.clusterj.core.store.PartitionKey;
26 import com.mysql.clusterj.core.util.I18NHelper;
27 import com.mysql.clusterj.core.util.Logger;
28 import com.mysql.clusterj.core.util.LoggerFactoryService;
29 import com.mysql.clusterj.tie.DbImpl.BufferManager;
30 import com.mysql.ndbjtie.ndbapi.NdbOperation;
31 import com.mysql.ndbjtie.ndbapi.NdbTransaction;
32
33 /**
34  * This class manages the startTransaction operation based on partition keys.
35  */
36 class PartitionKeyImpl implements PartitionKey {
37
38     /** My message translator */
39     static final I18NHelper local = I18NHelper
40             .getInstance(PartitionKeyImpl.class);
41
42     /** My logger */
43     static final Logger logger = LoggerFactoryService.getFactory()
44             .getInstance(PartitionKeyImpl.class);
45
46     private static PartitionKeyImpl theInstance = new PartitionKeyImpl();
47
48     /** The partition key part builders */
49     private List<KeyPartBuilder> keyPartBuilders = new ArrayList<KeyPartBuilder>();
50
51     /** The partition key parts */
52     private List<KeyPart> keyParts = new ArrayList<KeyPart>();
53
54     /** The table name */
55     private String tableName = null;
56
57     /** The partition id */
58     private int partitionId;
59
60     /** Add an int key to the partition key.
61      * The partition key will actually be constructed when needed, at enlist time.
62      */
63     public void addIntKey(final Column storeColumn, final int key) {
64         keyPartBuilders.add(new KeyPartBuilder() {
65             public void addKeyPart(BufferManager bufferManager) {
66                 ByteBuffer buffer = Utility.convertValue(storeColumn, key);
67                 KeyPart keyPart = new KeyPart(buffer, buffer.limit());
68                 keyParts.add(keyPart);
69             }
70         });
71     }
72
73     /** Add a long key to the partition key.
74      * The partition key will actually be constructed when needed, at enlist time.
75      */
76     public void addLongKey(final Column storeColumn, final long key) {
77         keyPartBuilders.add(new KeyPartBuilder() {
78             public void addKeyPart(BufferManager bufferManager) {
79                 ByteBuffer buffer = Utility.convertValue(storeColumn, key);
80                 KeyPart keyPart = new KeyPart(buffer, buffer.limit());
81                 keyParts.add(keyPart);
82             }
83         });
84     }
85
86     /** Add a String key to the partition key.
87      * The partition key will actually be constructed when needed, at enlist time.
88      * This is done so that the buffer manager can be used to efficiently create
89      * the encoded string key. The buffer manager is not know at the time this method
90      * is called.
91      */
92     public void addStringKey(final Column storeColumn, final String string) {
93         keyPartBuilders.add(new KeyPartBuilder() {
94             public void addKeyPart(BufferManager bufferManager) {
95                 ByteBuffer buffer = Utility.encode(string, storeColumn, bufferManager);
96                 // allocate a new buffer because the shared buffer might be overwritten by another key field
97                 ByteBuffer copy = ByteBuffer.allocateDirect(buffer.limit() - buffer.position());
98                 copy.put(buffer);
99                 copy.flip();
100                 KeyPart keyPart = new KeyPart(copy, copy.limit());
101                 keyParts.add(keyPart);
102             }
103         });
104     }
105
106     /** Add a byte array key to the partition key.
107      * The partition key will actually be constructed when needed, at enlist time.
108      */
109     public void addBytesKey(final Column storeColumn, final byte[] key) {
110         keyPartBuilders.add(new KeyPartBuilder() {
111             public void addKeyPart(BufferManager bufferManager) {
112                 ByteBuffer buffer = Utility.convertValue(storeColumn, key);
113                 KeyPart keyPart = new KeyPart(buffer, buffer.limit());
114                 keyParts.add(keyPart);
115             }
116         });
117     }
118
119     public void setTable(String tableName) {
120         this.tableName = tableName;
121     }
122
123     public void setPartitionId(int partitionId) {
124         this.partitionId = partitionId;
125     }
126
127     protected void handleError(int returnCode, NdbOperation ndbOperation) {
128         if (returnCode == 0) {
129             return;
130         } else {
131             Utility.throwError(returnCode, ndbOperation.getNdbError());
132         }
133     }
134
135     protected static void handleError(Object object, NdbOperation ndbOperation) {
136         if (object != null) {
137             return;
138         } else {
139             Utility.throwError(null, ndbOperation.getNdbError());
140         }
141     }
142
143     public NdbTransaction enlist(DbImpl db) {
144         BufferManager bufferManager = db.getBufferManager();
145         // construct the keyParts now that buffer manager is available
146         for (KeyPartBuilder keyPartBuilder: keyPartBuilders) {
147             keyPartBuilder.addKeyPart(bufferManager);
148         }
149         NdbTransaction result = null;
150         if (keyParts == null || keyParts.size() == 0) {
151             if (logger.isDebugEnabled()) logger.debug(
152                     "PartitionKeyImpl.enlist via partitionId with keyparts "
153                     + (keyParts==null?"null.":("size " + keyParts.size()))
154                     + " table: " + (tableName==null?"null":tableName)
155                     + " partition id: " + partitionId);
156             result = db.enlist(tableName, partitionId);
157         } else {
158             if (logger.isDebugEnabled()) logger.debug(
159                     "PartitionKeyImpl.enlist via keyParts with keyparts "
160                     + (keyParts==null?"null.":("size " + keyParts.size()))
161                     + " table: " + (tableName==null?"null":tableName));
162             result = db.enlist(tableName, keyParts);
163         }
164         return result;
165     }
166
167     /** Get a singleton instance of PartitionKeyImpl that doesn't name a specific table.
168      * 
169      * @return the instance
170      */
171     public static PartitionKeyImpl getInstance() {
172         return theInstance;
173     }
174
175     private static interface KeyPartBuilder {
176         public void addKeyPart(BufferManager bufferManager);
177     }
178
179 }