Source Code Cross Referenced for JODBIndexingAgent.java in  » Database-DBMS » JODB » com » mobixess » jodb » core » index » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » JODB » com.mobixess.jodb.core.index 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:        Copyright (C) 2007  Mobixess Inc. http://www.java-objects-database.com
003:
004:        This file is part of the JODB (Java Objects Database) open source project.
005:
006:        JODB is free software; you can redistribute it and/or modify it under
007:        the terms of version 2 of the GNU General Public License as published
008:        by the Free Software Foundation.
009:
010:        JODB is distributed in the hope that it will be useful, but WITHOUT ANY
011:        WARRANTY; without even the implied warranty of MERCHANTABILITY or
012:        FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
013:        for more details.
014:
015:        You should have received a copy of the GNU General Public License along
016:        with this program; if not, write to the Free Software Foundation, Inc.,
017:        59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
018:         */
019:        package com.mobixess.jodb.core.index;
020:
021:        import java.io.IOException;
022:        import java.lang.reflect.Field;
023:        import java.nio.ByteBuffer;
024:        import java.util.ConcurrentModificationException;
025:        import java.util.WeakHashMap;
026:
027:        import com.mobixess.jodb.core.IllegalClassTypeException;
028:        import com.mobixess.jodb.core.JODBTransient;
029:        import com.mobixess.jodb.core.JodbIOException;
030:        import com.mobixess.jodb.core.agent.JODBAgent;
031:        import com.mobixess.jodb.core.io.JODBOperationContext;
032:        import com.mobixess.jodb.core.transaction.TransactionContainer;
033:        import com.mobixess.jodb.util.PrimitiveJavaTypesUtil;
034:        import com.mobixess.jodb.util.PrimitiveJavaTypesUtil.PRIMITIVES_ENUMERATION;
035:
036:        public class JODBIndexingAgent extends JODBAgent {
037:
038:            private final static int CHUNK_HOLDER_DEFAULT_CAPACITY = 1000;
039:            private final static int CHUNK_HOLDER_DEFAULT_INCREMENT = 500;
040:            private final static int CHUNK_CAPACITY = 1000;
041:            private final static double PREFERRED_CHUNK_LOAD_FACTOR = 0.75;
042:
043:            private final static boolean DEEP_SANITY_CHECK = false;
044:
045:            private int _fieldId;
046:            private int _fieldTypeEnumIndex;
047:            private int _classId;
048:            private int _dataElementSize;
049:            private long[][] _offsetArrays;
050:            private byte[][] _dataArrays;
051:            private int[] _totalIndexesWithinChunks;
052:            private int _totalChunks;
053:            private int _totalIndexes;
054:            @JODBTransient
055:            private boolean _activated;
056:            @JODBTransient
057:            private WeakHashMap<long[], ByteBuffer> _chunksWrappersCache;
058:            @JODBTransient
059:            private PRIMITIVES_ENUMERATION _fieldTypeEnum;
060:
061:            public JODBIndexingAgent() {
062:            }
063:
064:            /**
065:             * @param fieldId
066:             * @throws JodbIOException 
067:             */
068:            public JODBIndexingAgent(Field field, JODBOperationContext context)
069:                    throws IOException {
070:                super ();
071:                if (field == null || context == null) {
072:                    throw new NullPointerException();
073:                }
074:                _classId = context.getBase().getOrSetClassTypeSubstitutionID(
075:                        field.getDeclaringClass());
076:                _fieldId = context.getBase().getOrSetFieldSubstitutionID(field);
077:                _fieldTypeEnum = PrimitiveJavaTypesUtil.getEnumeratedType(field
078:                        .getType().getName());
079:                _fieldTypeEnumIndex = _fieldTypeEnum.ordinal();
080:                _totalIndexesWithinChunks = new int[CHUNK_HOLDER_DEFAULT_CAPACITY];
081:                _offsetArrays = new long[CHUNK_HOLDER_DEFAULT_CAPACITY][];
082:                _offsetArrays[0] = new long[CHUNK_CAPACITY];
083:                _totalChunks = 1;
084:                Class type = field.getType();
085:                if (type.isPrimitive()) {
086:                    try {
087:                        _dataElementSize = PrimitiveJavaTypesUtil
088:                                .getDataOutputWriteLen(type);
089:                        _dataArrays = new byte[CHUNK_HOLDER_DEFAULT_CAPACITY][];
090:                        _dataArrays[0] = new byte[CHUNK_CAPACITY
091:                                * _dataElementSize];
092:                    } catch (JodbIOException e) {
093:                        // TODO log
094:                        e.printStackTrace();
095:                    }
096:                }
097:                _activated = true;
098:            }
099:
100:            private synchronized void checkIfActivated(
101:                    JODBOperationContext context) throws IOException {
102:                if (_activated) {
103:                    return;
104:                }
105:                context.getSession().activate(this , Integer.MAX_VALUE);
106:                _activated = true;
107:            }
108:
109:            private PRIMITIVES_ENUMERATION getFieldTypeEnum() {
110:                if (_fieldTypeEnum == null) {
111:                    _fieldTypeEnum = PRIMITIVES_ENUMERATION.values()[_fieldTypeEnumIndex];
112:                }
113:                return _fieldTypeEnum;
114:            }
115:
116:            private void sanityCheck() {
117:                int indexesInChunks = 0;
118:                for (int i = 0; i < _totalChunks; i++) {
119:                    indexesInChunks += _totalIndexesWithinChunks[i];
120:                }
121:                if (indexesInChunks != _totalIndexes) {
122:                    throw new RuntimeException(
123:                            "Sanity check failed indexesInChunks!=_totalIndexes");
124:                }
125:
126:                for (int i = 0; i < _totalChunks; i++) {
127:                    for (int j = 0; j < _totalIndexesWithinChunks[i]; j++) {
128:                        int nextChunk = i, nextIndex = j + 1;
129:                        if (nextIndex == _totalIndexesWithinChunks[i]) {
130:                            nextChunk++;
131:                            nextIndex = 0;
132:                        }
133:                        checkOffsetNotExists(_offsetArrays[i][j], nextChunk,
134:                                nextIndex);
135:                    }
136:                }
137:                /* 
138:                 for (int i = 0; i < _totalChunks; i++) {
139:                     for (int j = 0; j < _totalIndexesWithinChunks[i]; j++) {
140:                         int nextChunk = i, nextIndex = j+1;
141:                         if(nextIndex == _totalIndexesWithinChunks[i]){
142:                             nextChunk++;
143:                             nextIndex = 0;
144:                         }
145:                         checkOffsetNotExists(_offsetArrays[i][j],nextChunk,nextIndex);
146:                     }
147:                 }
148:                 */
149:                for (int i = 0; i < _totalIndexes - 1; i++) {
150:                    ByteBuffer first = getValueForIndex(i, true);
151:                    ByteBuffer next = getValueForIndex(i + 1, true);
152:                    try {
153:                        int compareResult = PrimitiveJavaTypesUtil
154:                                .comparePrimitives(first, getFieldTypeEnum(),
155:                                        next);
156:                        if (compareResult > 0) {
157:                            throw new RuntimeException();
158:                        }
159:                    } catch (IOException e) {
160:                        // TODO Auto-generated catch block
161:                        e.printStackTrace();
162:                    }
163:                    //            if(first.compareTo(next)>0){
164:                    //                throw new RuntimeException();
165:                    //            }
166:                }
167:            }
168:
169:            private void checkOffsetNotExists(long offset, int startChunk,
170:                    int startOffsetWithinChunk) {
171:                for (int i = startChunk; i < _totalChunks; i++) {
172:                    for (int j = startOffsetWithinChunk; j < _totalIndexesWithinChunks[i]; j++) {
173:                        if (offset == _offsetArrays[i][j]) {
174:                            throw new RuntimeException();
175:                        }
176:                    }
177:                }
178:            }
179:
180:            public int getFieldId() {
181:                return _fieldId;
182:            }
183:
184:            public int getClassId() {
185:                return _classId;
186:            }
187:
188:            public synchronized void insertIndex(long offsetId,
189:                    ByteBuffer value, JODBOperationContext context)
190:                    throws IOException {
191:                //        if(DEEP_SANITY_CHECK){
192:                //            sanityCheck();
193:                //        }
194:                int insertionIndex = searchIndex(value);
195:                if (insertionIndex < 0) {
196:                    insertionIndex = -insertionIndex - 1;
197:                }
198:                long chunkIndexAndChunkStart = getChunkForIndex(insertionIndex);
199:                int chunkIndex = (int) ((chunkIndexAndChunkStart >> 32) & 0xFFFFFFFF);
200:                int chunkStart = (int) (chunkIndexAndChunkStart & 0xFFFFFFFF);
201:                if (chunkIndex == _totalChunks) {
202:                    insertChunk(chunkIndex, context);
203:                }
204:                int indexInChunk = insertionIndex - chunkStart;
205:                reserveSpace(chunkIndex, indexInChunk, context);
206:                _offsetArrays[chunkIndex][indexInChunk] = offsetId;
207:                if (value != null) {
208:                    value.get(_dataArrays[chunkIndex], indexInChunk
209:                            * _dataElementSize, _dataElementSize);
210:                }
211:                //        if(DEEP_SANITY_CHECK){
212:                //            sanityCheck();
213:                //        }
214:
215:            }
216:
217:            public synchronized boolean removeIndex(long objectId,
218:                    ByteBuffer value, JODBOperationContext context)
219:                    throws IOException {
220:                //        if(DEEP_SANITY_CHECK){
221:                //            sanityCheck();
222:                //        }
223:                long compositeIndex = searchIndex(objectId, value);
224:                if (compositeIndex == -1) {
225:                    if (DEEP_SANITY_CHECK) {
226:                        sanityCheck();
227:                    }
228:                    compositeIndex = searchIndex(objectId, value);
229:                    return false;
230:                }
231:                int chunkIndex = (int) ((compositeIndex >> 32) & 0xFFFFFFFF);
232:                int indexInChunk = (int) (compositeIndex & 0xFFFFFFFF);
233:                long[] offsetsChunk = _offsetArrays[chunkIndex];
234:                System.arraycopy(offsetsChunk, indexInChunk + 1, offsetsChunk,
235:                        indexInChunk, _totalIndexesWithinChunks[chunkIndex]
236:                                - indexInChunk - 1);
237:                byte[] dataChunks = _dataArrays[chunkIndex];
238:                System
239:                        .arraycopy(dataChunks, (indexInChunk + 1)
240:                                * _dataElementSize, dataChunks, indexInChunk
241:                                * _dataElementSize,
242:                                (_totalIndexesWithinChunks[chunkIndex]
243:                                        - indexInChunk - 1)
244:                                        * _dataElementSize);
245:                _totalIndexesWithinChunks[chunkIndex]--;
246:                _totalIndexes--;
247:                //        if(DEEP_SANITY_CHECK){
248:                //            sanityCheck();
249:                //        }
250:                return true;
251:            }
252:
253:            private void reserveSpace(int chunkIndex, int indexInChunk,
254:                    JODBOperationContext context) {
255:                long[] currentOffsetsChunk = _offsetArrays[chunkIndex];
256:                int chunkLen = _offsetArrays[chunkIndex].length;
257:                if (_totalIndexesWithinChunks[chunkIndex] == chunkLen) {
258:                    //move indexes to next chunk or split
259:                    int indexesToMove = Math.min(
260:                            (int) (chunkLen * PREFERRED_CHUNK_LOAD_FACTOR),
261:                            chunkLen - indexInChunk);
262:                    if (chunkIndex == _totalChunks - 1
263:                            || (_offsetArrays[chunkIndex + 1].length - _totalIndexesWithinChunks[chunkIndex + 1]) <= indexesToMove) {
264:                        insertChunk(chunkIndex + 1, context);
265:                        indexesToMove = Math.min((int) (chunkLen * 0.5),
266:                                chunkLen - indexInChunk);
267:                    }
268:                    long[] nextOffsetsChunk = _offsetArrays[chunkIndex + 1];
269:                    //make sure next chunk have space
270:                    System.arraycopy(nextOffsetsChunk, 0, nextOffsetsChunk,
271:                            indexesToMove,
272:                            _totalIndexesWithinChunks[chunkIndex + 1]);
273:                    if (_dataArrays != null) {
274:                        byte[] nexDataArrayChunk = _dataArrays[chunkIndex + 1];
275:                        System.arraycopy(nexDataArrayChunk, 0,
276:                                nexDataArrayChunk, indexesToMove
277:                                        * _dataElementSize,
278:                                _totalIndexesWithinChunks[chunkIndex + 1]
279:                                        * _dataElementSize);
280:                    }
281:                    //move data
282:                    int srcIndex = _totalIndexesWithinChunks[chunkIndex]
283:                            - indexesToMove;
284:                    System.arraycopy(currentOffsetsChunk, srcIndex,
285:                            nextOffsetsChunk, 0, indexesToMove);
286:                    if (_dataArrays != null) {
287:                        byte[] nexDataArrayChunk = _dataArrays[chunkIndex + 1];
288:                        byte[] currentDataArrayChunk = _dataArrays[chunkIndex];
289:                        System.arraycopy(currentDataArrayChunk, srcIndex
290:                                * _dataElementSize, nexDataArrayChunk, 0,
291:                                indexesToMove * _dataElementSize);
292:                    }
293:                    _totalIndexesWithinChunks[chunkIndex] = srcIndex;//new chunk length
294:                    _totalIndexesWithinChunks[chunkIndex + 1] = _totalIndexesWithinChunks[chunkIndex + 1]
295:                            + indexesToMove;
296:                }
297:                //space is guaranteed from here  
298:                System.arraycopy(currentOffsetsChunk, indexInChunk,
299:                        currentOffsetsChunk, indexInChunk + 1,
300:                        _totalIndexesWithinChunks[chunkIndex] - indexInChunk);
301:                if (_dataArrays != null) {
302:                    byte[] currentDataArrayChunk = _dataArrays[chunkIndex];
303:                    System
304:                            .arraycopy(
305:                                    currentDataArrayChunk,
306:                                    indexInChunk * _dataElementSize,
307:                                    currentDataArrayChunk,
308:                                    (indexInChunk + 1) * _dataElementSize,
309:                                    (_totalIndexesWithinChunks[chunkIndex] - indexInChunk)
310:                                            * _dataElementSize);
311:                }
312:                _totalIndexesWithinChunks[chunkIndex]++;
313:                _totalIndexes++;
314:            }
315:
316:            /**
317:             * 
318:             * @param index
319:             * @return -1 means need chunk append
320:             */
321:            public final long getChunkForIndex(int index) {
322:                int chunkIndex = -1;
323:                int totalInPreviousChunks = 0;
324:                int currentChunkStart = 0;
325:                do {
326:                    chunkIndex++;
327:                    currentChunkStart = totalInPreviousChunks;
328:                    totalInPreviousChunks += _totalIndexesWithinChunks[chunkIndex];
329:                } while (totalInPreviousChunks < index + 1
330:                        && chunkIndex < _totalChunks - 1);
331:                if (totalInPreviousChunks < index + 1
332:                        && _totalIndexesWithinChunks[chunkIndex] == _offsetArrays[chunkIndex].length) {
333:                    currentChunkStart = totalInPreviousChunks;
334:                    chunkIndex++;
335:                }
336:                return (long) chunkIndex << 32 | (long) currentChunkStart;
337:            }
338:
339:            private ByteBuffer getValueForIndex(int index) {
340:                return getValueForIndex(index, false);
341:            }
342:
343:            private ByteBuffer getValueForIndex(int index,
344:                    boolean newChunkWrapper) {
345:                long compositeIndex = getChunkForIndex(index);
346:                int chunkIndex = (int) ((compositeIndex >> 32) & 0xFFFFFFFF);
347:                int chunkStart = (int) (compositeIndex & 0xFFFFFFFF);
348:                int indexInChunk = index - chunkStart;
349:                return getValueForIndex(chunkIndex, indexInChunk,
350:                        newChunkWrapper);
351:            }
352:
353:            private ByteBuffer getValueForIndex(int chunkIndex,
354:                    int offsetIndexInChunk) {
355:                return getValueForIndex(chunkIndex, offsetIndexInChunk, false);
356:            }
357:
358:            private ByteBuffer getValueForIndex(int chunkIndex,
359:                    int offsetIndexInChunk, boolean newByteBuffer) {
360:                ByteBuffer byteBuffer;
361:                if (!newByteBuffer) {
362:                    byteBuffer = getWrapperForChunk(chunkIndex);
363:                } else {
364:                    byteBuffer = ByteBuffer.wrap(_dataArrays[chunkIndex]);
365:                }
366:                getValueForIndex(chunkIndex, offsetIndexInChunk, byteBuffer);
367:                return byteBuffer;
368:            }
369:
370:            private void getValueForIndex(int chunkIndex,
371:                    int offsetIndexInChunk, ByteBuffer chunkWrapper) {
372:                int indexInChunk = offsetIndexInChunk * _dataElementSize;
373:                chunkWrapper.limit(indexInChunk + _dataElementSize);
374:                chunkWrapper.position(indexInChunk);
375:            }
376:
377:            private ByteBuffer getWrapperForChunk(int chunkIndex) {
378:                if (_chunksWrappersCache == null) {
379:                    _chunksWrappersCache = new WeakHashMap<long[], ByteBuffer>();
380:                }
381:                ByteBuffer result = _chunksWrappersCache
382:                        .get(_offsetArrays[chunkIndex]);
383:                if (result == null) {
384:                    result = ByteBuffer.wrap(_dataArrays[chunkIndex]);
385:                    _chunksWrappersCache.put(_offsetArrays[chunkIndex], result);
386:                }
387:                return result;
388:            }
389:
390:            private int linearValueSearch(ByteBuffer valueKey) {
391:                for (int i = 0; i < _totalIndexes; i++) {
392:                    ByteBuffer array_key = getValueForIndex(i);
393:                    if (valueKey.equals(array_key)) {
394:                        return i;
395:                    }
396:                }
397:                return -1;
398:            }
399:
400:            public int linearIdSearch(long id) {
401:                int index = 0;
402:                for (int i = 0; i < _totalChunks; i++) {
403:                    for (int j = 0; j < _totalIndexesWithinChunks[i]; j++) {
404:                        if (id == _offsetArrays[i][j]) {
405:                            return index;
406:                        }
407:                        index++;
408:                    }
409:                }
410:                return -1;
411:            }
412:
413:            /**
414:             * 
415:             * @param objectId
416:             * @param valueKey 
417:             * @return "chunk index" << 32 | "index in chunk"
418:             * @throws IOException 
419:             */
420:            private long searchIndex(long objectId, ByteBuffer valueKey)
421:                    throws IOException {
422:                int index = binarySearch(valueKey);
423:                //        if(objectId == 45001){
424:                //            index = linearValueSearch(valueKey);
425:                //            System.err.println("linear ID search "+linearIdSearch(objectId));
426:                //        }
427:                long compositeIndex = getChunkForIndex(index);
428:                int chunkIndexForward, chunkIndexBackward;
429:                chunkIndexForward = chunkIndexBackward = (int) ((compositeIndex >> 32) & 0xFFFFFFFF);
430:                int chunkStartForward, chunkStartBackward;
431:                chunkStartForward = chunkStartBackward = (int) (compositeIndex & 0xFFFFFFFF);
432:                int indexInChunkBackward = index - chunkStartBackward;
433:                int indexInChunkForward = indexInChunkBackward + 1;
434:                boolean continueBackward = true;
435:
436:                while (continueBackward) {
437:                    if (_offsetArrays[chunkIndexBackward][indexInChunkBackward] == objectId) {
438:                        return (long) chunkIndexBackward << 32
439:                                | indexInChunkBackward;
440:                    }
441:                    indexInChunkBackward--;
442:                    if (indexInChunkBackward < 0) {
443:                        chunkStartBackward -= _totalIndexesWithinChunks[chunkIndexBackward];//move chunk start to previous chunk start
444:                        chunkIndexBackward--;
445:                        if (chunkIndexBackward < 0) {
446:                            break;
447:                        }
448:                        indexInChunkBackward = _totalIndexesWithinChunks[chunkIndexBackward] - 1;
449:                    }
450:                    ByteBuffer nextValue = getValueForIndex(chunkIndexBackward,
451:                            indexInChunkBackward);
452:                    continueBackward = valueKey.equals(nextValue);
453:                }
454:
455:                boolean continueForward = true;
456:
457:                while (continueForward) {
458:                    if (indexInChunkForward >= _totalIndexesWithinChunks[chunkIndexForward]) {
459:                        chunkStartForward += _totalIndexesWithinChunks[chunkIndexForward];//move chunk end to next chunk start
460:                        chunkIndexForward++;
461:                        if (chunkIndexForward >= _totalChunks) {
462:                            break;
463:                        }
464:                        indexInChunkForward = 0;
465:                    }
466:                    if (_offsetArrays[chunkIndexForward][indexInChunkForward] == objectId) {
467:                        return (long) chunkIndexForward << 32
468:                                | indexInChunkForward;
469:                    }
470:                    ByteBuffer nextValue = getValueForIndex(chunkIndexForward,
471:                            indexInChunkForward);
472:                    continueForward = valueKey.equals(nextValue);
473:                    indexInChunkForward++;
474:                }
475:                return -1;
476:            }
477:
478:            public int searchIndex(ByteBuffer key) throws IOException {
479:                return binarySearch(key);
480:            }
481:
482:            public int binarySearch(ByteBuffer key) throws IOException {
483:                int fromIndex = 0, toIndex = _totalIndexes;
484:                int low = fromIndex;
485:                int high = toIndex - 1;
486:                while (low <= high) {
487:                    int mid = (low + high) >> 1;
488:                    ByteBuffer array_key = getValueForIndex(mid);
489:                    int result = -PrimitiveJavaTypesUtil.comparePrimitives(
490:                            array_key, array_key.position(),
491:                            getFieldTypeEnum(), key); //compareTo(key, array_key);//key.compareTo(array_key);// c.compare( key, array_key );
492:                    if (result < 0) {
493:                        high = mid - 1;
494:                    } else if (result > 0) {
495:                        low = mid + 1;
496:                    } else {
497:                        return mid;
498:                    }
499:                }
500:
501:                return -(low + 1);
502:            }
503:
504:            /**
505:             * Compares this buffer to another.
506:             *
507:             * <p> Two byte buffers are compared by comparing their sequences of
508:             * remaining elements lexicographically, without regard to the starting
509:             * position of each sequence within its corresponding buffer.
510:             *
511:             * <p> A byte buffer is not comparable to any other type of object.
512:             *
513:             * @return  A negative integer, zero, or a positive integer as this buffer
514:             *      is less than, equal to, or greater than the given buffer
515:             * @throws IOException 
516:             */
517:            public int compareTo(ByteBuffer this Key, ByteBuffer that)
518:                    throws IOException {
519:                return PrimitiveJavaTypesUtil.comparePrimitives(this Key, 0,
520:                        getFieldTypeEnum(), that);
521:                /*int n = thisKey.position() + Math.min(thisKey.remaining(), that.remaining());
522:                for (int i = thisKey.position(), j = that.position(); i < n; i++, j++) {
523:                    byte v1 = thisKey.get(i);
524:                    byte v2 = that.get(j);
525:                    if (v1 == v2)
526:                    continue;
527:                    if ((v1 != v1) && (v2 != v2))   // For float and double
528:                    continue;
529:                    if (v1 < v2)
530:                    return -1;
531:                    return +1;
532:                }
533:                return thisKey.remaining() - that.remaining();*/
534:            }
535:
536:            private synchronized void insertChunk(int index,
537:                    JODBOperationContext context) {
538:                TransactionContainer transactionContainer = context != null ? context
539:                        .getTransactionContainer()
540:                        : null;
541:
542:                _offsetArrays = JODBIndexingRootAgent
543:                        .ensurePersistentArrayCapacity(_offsetArrays,
544:                                _totalChunks + 1, transactionContainer,
545:                                CHUNK_HOLDER_DEFAULT_CAPACITY);
546:                if (index != _totalChunks) {
547:                    System.arraycopy(_offsetArrays, index, _offsetArrays,
548:                            index + 1, _totalChunks - index);
549:                    System.arraycopy(_totalIndexesWithinChunks, index,
550:                            _totalIndexesWithinChunks, index + 1, _totalChunks
551:                                    - index);
552:                }
553:                _offsetArrays[index] = new long[CHUNK_CAPACITY];
554:                if (transactionContainer != null) {//make sure the new array is registered in transaction container
555:                    try {
556:                        transactionContainer.set(_offsetArrays,
557:                                Integer.MAX_VALUE);
558:                    } catch (Exception e) {
559:                        e.printStackTrace();
560:                    }
561:                }
562:                _totalIndexesWithinChunks[index] = 0;
563:                if (_dataArrays != null) {
564:                    _dataArrays = JODBIndexingRootAgent
565:                            .ensurePersistentArrayCapacity(_dataArrays,
566:                                    _totalChunks + 1, transactionContainer,
567:                                    CHUNK_HOLDER_DEFAULT_CAPACITY);
568:                    if (index != _totalChunks) {
569:                        System.arraycopy(_dataArrays, index, _dataArrays,
570:                                index + 1, _totalChunks - index);
571:                    }
572:                    _dataArrays[index] = new byte[CHUNK_CAPACITY
573:                            * _dataElementSize];
574:                    if (transactionContainer != null) {//make sure the new array is registered in transaction container
575:                        try {
576:                            transactionContainer.set(_dataArrays,
577:                                    Integer.MAX_VALUE);
578:                        } catch (Exception e) {
579:                            e.printStackTrace();
580:                        }
581:                    }
582:                }
583:                _totalChunks++;
584:            }
585:
586:            public IndexDataIterator getIndexIterator(boolean isForwardIterator) {
587:                return isForwardIterator ? new ForwardIndexIteratorImpl()
588:                        : new BackwardIndexIteratorImpl();
589:            }
590:
591:            class ForwardIndexIteratorImpl implements  IndexDataIterator {
592:
593:                int _initialTotalIndexes;
594:                int _indexesLeft;
595:                int _chunkOffset;
596:                int _offsetInChunk;
597:
598:                public ForwardIndexIteratorImpl() {
599:                    _initialTotalIndexes = _indexesLeft = _totalIndexes;
600:                    _chunkOffset = 0;
601:                    _offsetInChunk = -1;
602:                }
603:
604:                public boolean hasNext() {
605:                    return _indexesLeft > 0;
606:                }
607:
608:                public int length() {
609:                    return _initialTotalIndexes;
610:                }
611:
612:                public long next(ByteBuffer result) {
613:                    if (_indexesLeft <= 0) {
614:                        throw new IllegalStateException();
615:                    }
616:                    if (_initialTotalIndexes != _totalIndexes) {
617:                        throw new ConcurrentModificationException();
618:                    }
619:                    _offsetInChunk++;
620:                    while (_offsetInChunk >= _totalIndexesWithinChunks[_chunkOffset]) {
621:                        _chunkOffset++;
622:                        _offsetInChunk = 0;
623:                    }
624:                    _indexesLeft--;
625:                    if (result != null) {
626:                        byte[] src = _dataArrays[_chunkOffset];
627:                        result.put(src, _offsetInChunk * _dataElementSize,
628:                                _dataElementSize);
629:                    }
630:                    return _offsetArrays[_chunkOffset][_offsetInChunk];
631:                }
632:
633:                public long next() {
634:                    return next(null);
635:                }
636:
637:            }
638:
639:            class BackwardIndexIteratorImpl implements  IndexDataIterator {
640:
641:                int _initialTotalIndexes;
642:                int _indexesLeft;
643:                int _chunkOffset;
644:                int _offsetInChunk;
645:
646:                public BackwardIndexIteratorImpl() {
647:                    _initialTotalIndexes = _indexesLeft = _totalIndexes;
648:                    _chunkOffset = _totalChunks - 1;
649:                    _offsetInChunk = _totalIndexesWithinChunks[_chunkOffset];
650:                }
651:
652:                public boolean hasNext() {
653:                    return _indexesLeft > 0;
654:                }
655:
656:                public int length() {
657:                    return _initialTotalIndexes;
658:                }
659:
660:                public long next(ByteBuffer result) {
661:                    if (_indexesLeft <= 0) {
662:                        throw new IllegalStateException();
663:                    }
664:                    if (_initialTotalIndexes != _totalIndexes) {
665:                        throw new ConcurrentModificationException();
666:                    }
667:                    _offsetInChunk--;
668:                    while (_offsetInChunk < 0
669:                            || _totalIndexesWithinChunks[_chunkOffset] <= 0) {
670:                        _chunkOffset--;
671:                        _offsetInChunk = _totalIndexesWithinChunks[_chunkOffset] - 1;
672:                    }
673:                    _indexesLeft--;
674:                    if (result != null) {
675:                        byte[] src = _dataArrays[_chunkOffset];
676:                        result.put(src, _offsetInChunk * _dataElementSize,
677:                                _dataElementSize);
678:                    }
679:                    return _offsetArrays[_chunkOffset][_offsetInChunk];
680:                }
681:
682:                public long next() {
683:                    return next(null);
684:                }
685:
686:            }
687:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.