├── .gitignore ├── .travis.yml ├── CONTRIBUTORS ├── core ├── src │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── yandex │ │ │ └── yoctodb │ │ │ ├── util │ │ │ ├── mutable │ │ │ │ ├── impl │ │ │ │ │ ├── CachedArrayBitSetPoolTest.java │ │ │ │ │ ├── AllocatingArrayBitSetPoolTest.java │ │ │ │ │ ├── RejectingArrayBitSetPoolTest.java │ │ │ │ │ ├── ThreadLocalCachedArrayBitSetPoolTest.java │ │ │ │ │ ├── AscendingBitSetIndexToIndexMultiMapTest.java │ │ │ │ │ ├── VariableLengthByteArrayIndexedListTest.java │ │ │ │ │ ├── IntIndexToIndexMultiMapTest.java │ │ │ │ │ ├── IntIndexToIndexMapTest.java │ │ │ │ │ ├── FixedLengthByteArrayIndexedListTest.java │ │ │ │ │ ├── TrieByteArraySortedSetTest.java │ │ │ │ │ ├── BitSetIndexToIndexMultiMapTest.java │ │ │ │ │ └── VariableLengthByteArraySortedSetTest.java │ │ │ │ ├── stored │ │ │ │ │ ├── VariableLengthByteArrayIndexedListTest.java │ │ │ │ │ ├── V1StoredIndexTest.java │ │ │ │ │ ├── ManyUniqueValuesTest.java │ │ │ │ │ └── ManyNonUniqueValuesTest.java │ │ │ │ └── AbstractArrayBitSetPoolTestBench.java │ │ │ ├── common │ │ │ │ └── BufferIteratorTest.java │ │ │ ├── buf │ │ │ │ ├── BufferInputStreamTest.java │ │ │ │ └── ByteBufferWrapperTest.java │ │ │ ├── immutable │ │ │ │ ├── impl │ │ │ │ │ ├── IntIndexToIndexMapTest.java │ │ │ │ │ ├── FixedLengthByteArrayIndexedListTest.java │ │ │ │ │ ├── VariableLengthByteArrayIndexedListTest.java │ │ │ │ │ ├── VariableLengthByteArraySortedSetTest.java │ │ │ │ │ ├── FixedLengthByteArraySortedSetTest.java │ │ │ │ │ ├── FoldedByteArrayIndexedListTest.java │ │ │ │ │ └── IndexToIndexMultiMapReaderTest.java │ │ │ │ └── IntIndexToIndexMapTest.java │ │ │ └── MessageDigestOutputStreamWrapperTest.java │ │ │ ├── query │ │ │ └── simple │ │ │ │ ├── SimpleAscendingOrderTest.java │ │ │ │ ├── SimpleDescendingOrderTest.java │ │ │ │ └── SortingScoredDocumentIteratorTest.java │ │ │ ├── v1 │ │ │ ├── immutable │ │ │ │ ├── SortResultIteratorTest.java │ │ │ │ ├── FilterResultIteratorTest.java │ │ │ │ └── segment │ │ │ │ │ └── SegmentRegistryTest.java │ │ │ └── mutable │ │ │ │ ├── V1DocumentBuilderTest.java │ │ │ │ └── segment │ │ │ │ ├── V1FilterableIndexTest.java │ │ │ │ ├── V1StoredIndexTest.java │ │ │ │ └── V1FullIndexTest.java │ │ │ ├── StringProcessor.java │ │ │ ├── DoubleDatabaseProcessor.java │ │ │ └── StoredIndexWithEmptyTest.java │ └── main │ │ └── java │ │ └── com │ │ └── yandex │ │ └── yoctodb │ │ ├── v1 │ │ ├── immutable │ │ │ ├── segment │ │ │ │ ├── Segment.java │ │ │ │ ├── SegmentReader.java │ │ │ │ ├── Segments.java │ │ │ │ └── SegmentRegistry.java │ │ │ ├── QueryContext.java │ │ │ ├── SortResultIterator.java │ │ │ └── FilterResultIterator.java │ │ └── mutable │ │ │ └── segment │ │ │ ├── Freezable.java │ │ │ ├── IndexSegment.java │ │ │ ├── V1FullIndex.java │ │ │ └── V1SortableIndex.java │ │ ├── util │ │ ├── immutable │ │ │ ├── IndexToIndexMap.java │ │ │ ├── ByteArrayIndexedList.java │ │ │ ├── IndexToIndexMultiMap.java │ │ │ ├── IntToIntArray.java │ │ │ ├── impl │ │ │ │ ├── IndexToIndexMultiMapReader.java │ │ │ │ └── IntIndexToIndexMap.java │ │ │ └── ByteArraySortedSet.java │ │ ├── mutable │ │ │ ├── ArrayBitSet.java │ │ │ ├── IndexToIndexMultiMap.java │ │ │ ├── IndexToIndexMap.java │ │ │ ├── ByteArrayIndexedList.java │ │ │ ├── ArrayBitSetPool.java │ │ │ ├── impl │ │ │ │ ├── AllocatingArrayBitSetPool.java │ │ │ │ ├── RejectingArrayBitSetPool.java │ │ │ │ ├── AbstractByteArraySortedSet.java │ │ │ │ ├── CachedArrayBitSetPool.java │ │ │ │ ├── ThreadLocalCachedArrayBitSetPool.java │ │ │ │ ├── FixedLengthByteArrayIndexedList.java │ │ │ │ ├── IntIndexToIndexMap.java │ │ │ │ ├── FixedLengthByteArraySortedSet.java │ │ │ │ ├── AbstractCachedArrayBitSetPool.java │ │ │ │ ├── VariableLengthByteArraySortedSet.java │ │ │ │ ├── VariableLengthByteArrayIndexedList.java │ │ │ │ └── BitSetIndexToIndexMultiMap.java │ │ │ └── ByteArraySortedSet.java │ │ ├── OutputStreamWritableBuilder.java │ │ ├── OutputStreamWritable.java │ │ ├── common │ │ │ ├── TrieNodeMetadata.java │ │ │ └── BufferIterator.java │ │ ├── buf │ │ │ └── BufferInputStream.java │ │ ├── MessageDigestOutputStreamWrapper.java │ │ └── UnsignedByteArray.java │ │ ├── immutable │ │ ├── Database.java │ │ ├── IndexedDatabase.java │ │ ├── Index.java │ │ ├── SortableIndexProvider.java │ │ ├── FilterableIndexProvider.java │ │ ├── DatabaseReader.java │ │ ├── FilterableIndex.java │ │ ├── ExecutionEngine.java │ │ ├── StoredIndex.java │ │ └── SortableIndex.java │ │ ├── query │ │ ├── TermCondition.java │ │ ├── DocumentScore.java │ │ ├── OrderBy.java │ │ ├── Where.java │ │ ├── ScoredDocument.java │ │ ├── Select.java │ │ ├── DocumentProcessor.java │ │ ├── Order.java │ │ ├── simple │ │ │ ├── AbstractTermCondition.java │ │ │ ├── SimpleAscendingOrder.java │ │ │ ├── SimpleDescendingOrder.java │ │ │ ├── IdScoredDocument.java │ │ │ ├── SimpleNotCondition.java │ │ │ ├── SimpleOrCondition.java │ │ │ ├── SimpleScoredDocument.java │ │ │ ├── SimpleEqualityCondition.java │ │ │ ├── SimpleLessThanCondition.java │ │ │ ├── SimpleGreaterThanCondition.java │ │ │ ├── SimpleLessThanOrEqualsCondition.java │ │ │ ├── SimpleGreaterThanOrEqualsCondition.java │ │ │ ├── IdScoredDocumentIterator.java │ │ │ ├── SimpleDocumentMultiScore.java │ │ │ ├── SimpleMultiEqualityCondition.java │ │ │ └── SimpleRangeCondition.java │ │ ├── Condition.java │ │ └── Query.java │ │ ├── mutable │ │ └── DatabaseBuilder.java │ │ └── DatabaseFormat.java └── pom.xml ├── README.md └── benchmark └── src └── main └── java └── com └── yandex └── yoctodb └── util └── immutable └── ByteArraySortedSetBenchmarks.java /.gitignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | 3 | .DS_Store 4 | .idea 5 | atlassian-ide-plugin.xml 6 | target/ 7 | *.ipr 8 | *.iml 9 | *.iws 10 | *.orig 11 | 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | install: mvn install -DskipTests=true -Dgpg.skip=true 3 | jdk: 4 | - oraclejdk8 5 | - openjdk8 6 | after_success: 7 | - mvn clean test jacoco:report coveralls:report 8 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # Please keep the list sorted. 2 | 3 | Alexander Sergeev 4 | Andrey Korzinev 5 | Irina Kamalova 6 | Svyatoslav Demidov 7 | Vadim Tsesko 8 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/CachedArrayBitSetPoolTest.java: -------------------------------------------------------------------------------- 1 | package com.yandex.yoctodb.util.mutable.impl; 2 | 3 | import com.yandex.yoctodb.util.mutable.AbstractArrayBitSetPoolTestBench; 4 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 5 | 6 | /** 7 | * Unit tests for {@link CachedArrayBitSetPool} 8 | * 9 | * @author incubos 10 | */ 11 | public class CachedArrayBitSetPoolTest 12 | extends AbstractArrayBitSetPoolTestBench { 13 | @Override 14 | protected ArrayBitSetPool allocate() { 15 | return new CachedArrayBitSetPool(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/AllocatingArrayBitSetPoolTest.java: -------------------------------------------------------------------------------- 1 | package com.yandex.yoctodb.util.mutable.impl; 2 | 3 | import com.yandex.yoctodb.util.mutable.AbstractArrayBitSetPoolTestBench; 4 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 5 | 6 | /** 7 | * Unit tests for {@link AllocatingArrayBitSetPool} 8 | * 9 | * @author incubos 10 | */ 11 | public class AllocatingArrayBitSetPoolTest 12 | extends AbstractArrayBitSetPoolTestBench { 13 | @Override 14 | protected ArrayBitSetPool allocate() { 15 | return AllocatingArrayBitSetPool.INSTANCE; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/v1/immutable/segment/Segment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.immutable.segment; 12 | 13 | import net.jcip.annotations.Immutable; 14 | 15 | /** 16 | * Segment tag interface 17 | * 18 | * @author incubos 19 | */ 20 | @Immutable 21 | public interface Segment { 22 | } 23 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/immutable/IndexToIndexMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable; 12 | 13 | import net.jcip.annotations.Immutable; 14 | 15 | /** 16 | * @author svyatoslav 17 | */ 18 | @Immutable 19 | public interface IndexToIndexMap { 20 | int get(int key); 21 | int size(); 22 | } 23 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/immutable/Database.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.immutable; 12 | 13 | import net.jcip.annotations.Immutable; 14 | 15 | /** 16 | * An immutable database 17 | * 18 | * @author incubos 19 | */ 20 | @Immutable 21 | public interface Database extends DocumentProvider, ExecutionEngine { 22 | } 23 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/RejectingArrayBitSetPoolTest.java: -------------------------------------------------------------------------------- 1 | package com.yandex.yoctodb.util.mutable.impl; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * Unit tests for {@link RejectingArrayBitSetPool} 7 | * 8 | * @author incubos 9 | */ 10 | public class RejectingArrayBitSetPoolTest { 11 | @Test(expected = UnsupportedOperationException.class) 12 | public void rejectBorrow() { 13 | RejectingArrayBitSetPool.INSTANCE.borrowSet(1); 14 | } 15 | 16 | @Test(expected = UnsupportedOperationException.class) 17 | public void rejectReturn() { 18 | RejectingArrayBitSetPool.INSTANCE.returnSet(LongArrayBitSet.one(1)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/TermCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query; 12 | 13 | import net.jcip.annotations.Immutable; 14 | 15 | /** 16 | * Tag interface for primitive conditions to restrict query AST 17 | * 18 | * @author incubos 19 | */ 20 | @Immutable 21 | public interface TermCondition extends Condition { 22 | } 23 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/immutable/IndexedDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.immutable; 12 | 13 | /** 14 | * {@link Database} with support for indexed filtering and sorting 15 | * 16 | * @author incubos 17 | */ 18 | public interface IndexedDatabase 19 | extends Database, FilterableIndexProvider, SortableIndexProvider { 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/DocumentScore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query; 12 | 13 | import net.jcip.annotations.Immutable; 14 | 15 | /** 16 | * Comparable document score 17 | * 18 | * @author incubos 19 | */ 20 | @Immutable 21 | public interface DocumentScore> 22 | extends Comparable { 23 | } 24 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/immutable/Index.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.immutable; 12 | 13 | import net.jcip.annotations.Immutable; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | /** 17 | * Field index 18 | * 19 | * @author incubos 20 | */ 21 | @Immutable 22 | public interface Index { 23 | @NotNull 24 | String getFieldName(); 25 | } 26 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/ArrayBitSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable; 12 | 13 | import org.jetbrains.annotations.NotNull; 14 | 15 | /** 16 | * Array-based {@link BitSet} implementation 17 | * 18 | * @author incubos 19 | */ 20 | public interface ArrayBitSet extends BitSet { 21 | @NotNull 22 | long[] toArray(); 23 | } 24 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/IndexToIndexMultiMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | import com.yandex.yoctodb.util.OutputStreamWritable; 15 | 16 | /** 17 | * Integer to Integer multi map 18 | * 19 | * @author incubos 20 | */ 21 | @NotThreadSafe 22 | public interface IndexToIndexMultiMap extends OutputStreamWritable { 23 | } 24 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/immutable/SortableIndexProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.immutable; 12 | 13 | import org.jetbrains.annotations.NotNull; 14 | 15 | /** 16 | * Provides {@link SortableIndex}es 17 | * 18 | * @author incubos 19 | */ 20 | public interface SortableIndexProvider { 21 | @NotNull 22 | SortableIndex getSorter( 23 | @NotNull 24 | String fieldName); 25 | } 26 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/IndexToIndexMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | import com.yandex.yoctodb.util.OutputStreamWritable; 15 | 16 | /** 17 | * Map from index to index 18 | * 19 | * @author incubos 20 | */ 21 | @NotThreadSafe 22 | public interface IndexToIndexMap extends OutputStreamWritable { 23 | void put(int key, int value); 24 | } 25 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/OutputStreamWritableBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | /** 17 | * Builds {@link OutputStreamWritable} 18 | * 19 | * @author incubos 20 | */ 21 | @NotThreadSafe 22 | public interface OutputStreamWritableBuilder { 23 | @NotNull 24 | OutputStreamWritable buildWritable(); 25 | } 26 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/ByteArrayIndexedList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable; 12 | 13 | import com.yandex.yoctodb.util.OutputStreamWritable; 14 | import net.jcip.annotations.NotThreadSafe; 15 | 16 | /** 17 | * Indexed list of {@link com.yandex.yoctodb.util.UnsignedByteArray}s 18 | * 19 | * @author incubos 20 | */ 21 | @NotThreadSafe 22 | public interface ByteArrayIndexedList extends OutputStreamWritable { 23 | } 24 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/immutable/FilterableIndexProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.immutable; 12 | 13 | import org.jetbrains.annotations.NotNull; 14 | import org.jetbrains.annotations.Nullable; 15 | 16 | /** 17 | * Provides {@link FilterableIndex}es 18 | * 19 | * @author incubos 20 | */ 21 | public interface FilterableIndexProvider { 22 | @Nullable 23 | FilterableIndex getFilter( 24 | @NotNull 25 | String fieldName); 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/OrderBy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | /** 17 | * Order by clause 18 | * 19 | * @author incubos 20 | */ 21 | @NotThreadSafe 22 | public interface OrderBy extends Select { 23 | @NotNull 24 | OrderBy and( 25 | @NotNull 26 | Order order); 27 | 28 | @NotNull 29 | OrderBy clone(); 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/Where.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | /** 17 | * Filtering clause 18 | * 19 | * @author incubos 20 | */ 21 | @NotThreadSafe 22 | public interface Where extends Select { 23 | @NotNull 24 | Where and( 25 | @NotNull 26 | Condition condition); 27 | 28 | @NotNull 29 | Where clone(); 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/v1/immutable/segment/SegmentReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.immutable.segment; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import net.jcip.annotations.Immutable; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | /** 18 | * Reads segments 19 | * 20 | * @author incubos 21 | */ 22 | @Immutable 23 | interface SegmentReader { 24 | @NotNull 25 | Segment read( 26 | @NotNull 27 | Buffer buffer); 28 | } 29 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/common/BufferIteratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2018 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.common; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import org.junit.Test; 15 | 16 | import java.nio.ByteBuffer; 17 | import java.util.NoSuchElementException; 18 | 19 | public class BufferIteratorTest { 20 | @Test(expected = NoSuchElementException.class) 21 | public void invalidNext() { 22 | new BufferIterator(Buffer.from(ByteBuffer.allocate(0))).next(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/ScoredDocument.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query; 12 | 13 | import net.jcip.annotations.Immutable; 14 | import org.jetbrains.annotations.NotNull; 15 | import com.yandex.yoctodb.immutable.Database; 16 | 17 | /** 18 | * Scored document comparable by {@link DocumentScore} 19 | * 20 | * @author incubos 21 | */ 22 | @Immutable 23 | public interface ScoredDocument> 24 | extends Comparable { 25 | @NotNull 26 | Database getDatabase(); 27 | 28 | int getDocument(); 29 | } 30 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/OutputStreamWritable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util; 12 | 13 | import net.jcip.annotations.ThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | import java.io.IOException; 17 | import java.io.OutputStream; 18 | 19 | /** 20 | * Something writable to {@link OutputStream} 21 | * 22 | * @author incubos 23 | */ 24 | @ThreadSafe 25 | public interface OutputStreamWritable { 26 | long getSizeInBytes(); 27 | 28 | void writeTo( 29 | @NotNull 30 | OutputStream os) throws IOException; 31 | } 32 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/query/simple/SimpleAscendingOrderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import org.junit.Assert; 14 | import org.junit.Test; 15 | 16 | /** 17 | * Unit tests for {@link com.yandex.yoctodb.query.simple.SimpleAscendingOrder} 18 | * 19 | * @author incubos 20 | */ 21 | public class SimpleAscendingOrderTest { 22 | @Test 23 | public void nonDefaultToString() { 24 | Assert.assertTrue( 25 | new SimpleAscendingOrder("myField").toString() 26 | .contains("myField")); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/query/simple/SimpleDescendingOrderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import org.junit.Assert; 14 | import org.junit.Test; 15 | 16 | /** 17 | * Unit tests for {@link com.yandex.yoctodb.query.simple.SimpleDescendingOrder} 18 | * 19 | * @author incubos 20 | */ 21 | public class SimpleDescendingOrderTest { 22 | @Test 23 | public void nonDefaultToString() { 24 | Assert.assertTrue( 25 | new SimpleDescendingOrder("myField").toString() 26 | .contains("myField")); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/v1/mutable/segment/Freezable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.mutable.segment; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | 15 | /** 16 | * Something freezable 17 | * 18 | * @author incubos 19 | */ 20 | @NotThreadSafe 21 | public abstract class Freezable { 22 | private boolean frozen = false; 23 | 24 | public void freeze() { 25 | frozen = true; 26 | } 27 | 28 | public void checkNotFrozen() { 29 | if (frozen) { 30 | throw new IllegalStateException("Already frozen"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/ThreadLocalCachedArrayBitSetPoolTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.yandex.yoctodb.util.mutable.AbstractArrayBitSetPoolTestBench; 14 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 15 | 16 | /** 17 | * Unit tests for {@link ThreadLocalCachedArrayBitSetPool} 18 | * 19 | * @author incubos 20 | */ 21 | public class ThreadLocalCachedArrayBitSetPoolTest 22 | extends AbstractArrayBitSetPoolTestBench { 23 | @Override 24 | protected ArrayBitSetPool allocate() { 25 | return new ThreadLocalCachedArrayBitSetPool(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/v1/immutable/SortResultIteratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.immutable; 12 | 13 | import com.yandex.yoctodb.query.QueryBuilder; 14 | import org.junit.Test; 15 | 16 | import java.util.Collections; 17 | 18 | /** 19 | * Unit tests for {@link SortResultIterator} 20 | * 21 | * @author incubos 22 | */ 23 | public class SortResultIteratorTest { 24 | @Test(expected = UnsupportedOperationException.class) 25 | public void unsupportedRemove() { 26 | new SortResultIterator( 27 | QueryBuilder.select(), 28 | Collections.emptyIterator()).remove(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/mutable/DatabaseBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.mutable; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | import com.yandex.yoctodb.util.OutputStreamWritableBuilder; 16 | 17 | import java.io.OutputStream; 18 | 19 | /** 20 | * Builds a database of {@link DocumentBuilder}s serializable to 21 | * {@link OutputStream} 22 | * 23 | * @author incubos 24 | */ 25 | @NotThreadSafe 26 | public interface DatabaseBuilder extends OutputStreamWritableBuilder { 27 | @NotNull 28 | DatabaseBuilder merge( 29 | @NotNull 30 | DocumentBuilder document); 31 | } 32 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/Select.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | /** 17 | * Select query 18 | * 19 | * @author incubos 20 | */ 21 | @NotThreadSafe 22 | public interface Select extends Query { 23 | @NotNull 24 | Where where( 25 | @NotNull 26 | Condition condition); 27 | 28 | @NotNull 29 | OrderBy orderBy( 30 | @NotNull 31 | Order order); 32 | 33 | @NotNull 34 | Select skip(int skip); 35 | 36 | @NotNull 37 | Select limit(int limit); 38 | 39 | @NotNull 40 | Select clone(); 41 | } 42 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/ArrayBitSetPool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable; 12 | 13 | import net.jcip.annotations.ThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | /** 17 | * {@link BitSet} pool 18 | * 19 | * @author incubos 20 | */ 21 | @ThreadSafe 22 | public interface ArrayBitSetPool { 23 | /** 24 | * Borrow a zeroed {@link ArrayBitSet} instance. 25 | * 26 | * @param size size of {@link ArrayBitSet} 27 | * @return An instance of {@link ArrayBitSet} 28 | */ 29 | @NotNull 30 | ArrayBitSet borrowSet(int size); 31 | 32 | void returnSet( 33 | @NotNull 34 | ArrayBitSet set); 35 | } 36 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/AllocatingArrayBitSetPool.java: -------------------------------------------------------------------------------- 1 | package com.yandex.yoctodb.util.mutable.impl; 2 | 3 | import com.yandex.yoctodb.util.mutable.ArrayBitSet; 4 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 5 | import net.jcip.annotations.ThreadSafe; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Noncaching {@link ArrayBitSetPool} implementation 10 | * 11 | * @author incubos 12 | */ 13 | @ThreadSafe 14 | public final class AllocatingArrayBitSetPool implements ArrayBitSetPool { 15 | public static final ArrayBitSetPool INSTANCE = 16 | new AllocatingArrayBitSetPool(); 17 | 18 | private AllocatingArrayBitSetPool() { 19 | // Do nothing 20 | } 21 | 22 | @NotNull 23 | @Override 24 | public ArrayBitSet borrowSet(final int size) { 25 | return LongArrayBitSet.zero(size); 26 | } 27 | 28 | @Override 29 | public void returnSet( 30 | @NotNull 31 | final ArrayBitSet set) { 32 | // Do nothing 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/RejectingArrayBitSetPool.java: -------------------------------------------------------------------------------- 1 | package com.yandex.yoctodb.util.mutable.impl; 2 | 3 | import com.yandex.yoctodb.util.mutable.ArrayBitSet; 4 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 5 | import net.jcip.annotations.ThreadSafe; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Rejecting {@link ArrayBitSetPool} implementation 10 | * 11 | * @author incubos 12 | */ 13 | @ThreadSafe 14 | public final class RejectingArrayBitSetPool implements ArrayBitSetPool { 15 | public static final ArrayBitSetPool INSTANCE = 16 | new RejectingArrayBitSetPool(); 17 | 18 | private RejectingArrayBitSetPool() { 19 | // Do nothing 20 | } 21 | 22 | @NotNull 23 | @Override 24 | public ArrayBitSet borrowSet(final int size) { 25 | throw new UnsupportedOperationException(); 26 | } 27 | 28 | @Override 29 | public void returnSet( 30 | @NotNull 31 | final ArrayBitSet set) { 32 | throw new UnsupportedOperationException(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/v1/mutable/segment/IndexSegment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.mutable.segment; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | import com.yandex.yoctodb.util.UnsignedByteArray; 16 | import com.yandex.yoctodb.util.OutputStreamWritableBuilder; 17 | 18 | import java.util.Collection; 19 | 20 | /** 21 | * Mutable index segment 22 | * 23 | * @author incubos 24 | */ 25 | @NotThreadSafe 26 | public interface IndexSegment extends OutputStreamWritableBuilder { 27 | @NotNull 28 | IndexSegment addDocument( 29 | int documentId, 30 | @NotNull 31 | Collection values); 32 | 33 | void setDatabaseDocumentsCount(int documentsCount); 34 | } 35 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/immutable/ByteArrayIndexedList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import net.jcip.annotations.ThreadSafe; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | /** 18 | * Indexed list of {@link com.yandex.yoctodb.util.UnsignedByteArray}s 19 | * 20 | * @author incubos 21 | */ 22 | @ThreadSafe 23 | public interface ByteArrayIndexedList { 24 | @NotNull 25 | Buffer get(final int docId); 26 | 27 | long getLongUnsafe(final int docId); 28 | 29 | int getIntUnsafe(final int docId); 30 | 31 | short getShortUnsafe(final int docId); 32 | 33 | char getCharUnsafe(final int docId); 34 | 35 | byte getByteUnsafe(final int docId); 36 | 37 | int size(); 38 | } 39 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/AscendingBitSetIndexToIndexMultiMapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2018 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import org.junit.Test; 14 | 15 | import static java.util.Collections.*; 16 | import static org.junit.Assert.*; 17 | 18 | public class AscendingBitSetIndexToIndexMultiMapTest { 19 | @Test(expected = IllegalArgumentException.class) 20 | public void negativeDocumentCount() { 21 | new AscendingBitSetIndexToIndexMultiMap(singletonList(singletonList(1)), -1); 22 | } 23 | 24 | @Test 25 | public void tostring() { 26 | assertNotNull( 27 | new AscendingBitSetIndexToIndexMultiMap( 28 | singletonList(singletonList(1)), 29 | 0).toString()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/DocumentProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | import com.yandex.yoctodb.immutable.Database; 16 | 17 | /** 18 | * Processor of immutable database documents 19 | * 20 | * @author incubos 21 | */ 22 | @NotThreadSafe 23 | public interface DocumentProcessor { 24 | /** 25 | * Process the document payload 26 | * 27 | * @param document document id 28 | * @param database database to get document payload from 29 | * @return whether the processing should continue 30 | */ 31 | @SuppressWarnings("BooleanMethodIsAlwaysInverted") 32 | boolean process( 33 | int document, 34 | @NotNull 35 | Database database); 36 | } 37 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/v1/immutable/FilterResultIteratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.immutable; 12 | 13 | import com.yandex.yoctodb.immutable.IndexedDatabase; 14 | import com.yandex.yoctodb.query.QueryBuilder; 15 | import com.yandex.yoctodb.util.mutable.impl.ThreadLocalCachedArrayBitSetPool; 16 | import org.junit.Test; 17 | 18 | import java.util.Collections; 19 | 20 | /** 21 | * Unit tests for {@link FilterResultIterator} 22 | * 23 | * @author incubos 24 | */ 25 | public class FilterResultIteratorTest { 26 | @Test(expected = UnsupportedOperationException.class) 27 | public void unsupportedRemove() { 28 | new FilterResultIterator( 29 | QueryBuilder.select(), 30 | Collections.emptyIterator(), 31 | new ThreadLocalCachedArrayBitSetPool()).remove(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/Order.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query; 12 | 13 | import net.jcip.annotations.Immutable; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | /** 17 | * {@link OrderBy} order 18 | * 19 | * @author incubos 20 | */ 21 | @Immutable 22 | public interface Order { 23 | enum SortOrder { 24 | ASC { 25 | @Override 26 | public boolean isAscending() { 27 | return true; 28 | } 29 | }, 30 | DESC { 31 | @Override 32 | public boolean isAscending() { 33 | return false; 34 | } 35 | }; 36 | 37 | // To make orders exhaustive 38 | public abstract boolean isAscending(); 39 | } 40 | 41 | @NotNull 42 | String getFieldName(); 43 | 44 | @NotNull 45 | SortOrder getOrder(); 46 | } 47 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/v1/mutable/segment/V1FullIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.mutable.segment; 12 | 13 | import com.yandex.yoctodb.v1.V1DatabaseFormat; 14 | import net.jcip.annotations.NotThreadSafe; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | /** 18 | * Index supporting filtering and sorting by specific field 19 | * 20 | * @author incubos 21 | */ 22 | @NotThreadSafe 23 | public final class V1FullIndex extends AbstractV1FullIndex { 24 | public V1FullIndex( 25 | @NotNull 26 | final String fieldName, 27 | final boolean fixedLength) { 28 | super( 29 | fieldName, 30 | fixedLength, 31 | fixedLength ? 32 | V1DatabaseFormat.SegmentType.FIXED_LENGTH_FULL_INDEX : 33 | V1DatabaseFormat.SegmentType.VARIABLE_LENGTH_FULL_INDEX); 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/ByteArraySortedSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable; 12 | 13 | import com.yandex.yoctodb.util.OutputStreamWritable; 14 | import com.yandex.yoctodb.util.UnsignedByteArray; 15 | import net.jcip.annotations.NotThreadSafe; 16 | import org.jetbrains.annotations.NotNull; 17 | 18 | import java.util.NoSuchElementException; 19 | 20 | /** 21 | * {@link com.yandex.yoctodb.util.UnsignedByteArray} mutable sorted set with 22 | * basic operations 23 | * 24 | * @author incubos 25 | */ 26 | @NotThreadSafe 27 | public interface ByteArraySortedSet extends OutputStreamWritable { 28 | /** 29 | * Returns index of the element 30 | * 31 | * @param e element 32 | * @return index of the element or {@link NoSuchElementException} 33 | */ 34 | int indexOf( 35 | @NotNull 36 | UnsignedByteArray e) throws NoSuchElementException; 37 | } 38 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/v1/mutable/segment/V1SortableIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.mutable.segment; 12 | 13 | import com.yandex.yoctodb.v1.V1DatabaseFormat; 14 | import net.jcip.annotations.NotThreadSafe; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | /** 18 | * Index supporting sorting by specific field 19 | * 20 | * @author incubos 21 | */ 22 | @NotThreadSafe 23 | public final class V1SortableIndex extends AbstractV1FullIndex { 24 | public V1SortableIndex( 25 | @NotNull 26 | final String fieldName, 27 | final boolean fixedLength) { 28 | super( 29 | fieldName, 30 | fixedLength, 31 | fixedLength ? 32 | V1DatabaseFormat.SegmentType.FIXED_LENGTH_SORTABLE_INDEX : 33 | V1DatabaseFormat.SegmentType.VARIABLE_LENGTH_SORTABLE_INDEX); 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/AbstractTermCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.query.TermCondition; 14 | import net.jcip.annotations.Immutable; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | /** 18 | * Abstract term condition 19 | * 20 | * @author incubos 21 | */ 22 | @Immutable 23 | abstract class AbstractTermCondition implements TermCondition { 24 | @NotNull 25 | private final String fieldName; 26 | 27 | AbstractTermCondition( 28 | @NotNull 29 | final String fieldName) { 30 | this.fieldName = fieldName; 31 | } 32 | 33 | @NotNull 34 | String getFieldName() { 35 | return fieldName; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return this.getClass().getSimpleName() + 41 | "{fieldName='" + fieldName + '\'' + 42 | '}'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleAscendingOrder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import net.jcip.annotations.Immutable; 14 | import org.jetbrains.annotations.NotNull; 15 | import com.yandex.yoctodb.query.Order; 16 | 17 | /** 18 | * Ascending order 19 | * 20 | * @author incubos 21 | */ 22 | @Immutable 23 | public final class SimpleAscendingOrder implements Order { 24 | @NotNull 25 | private final String fieldName; 26 | 27 | public SimpleAscendingOrder( 28 | @NotNull 29 | final String fieldName) { 30 | this.fieldName = fieldName; 31 | } 32 | 33 | @Override 34 | @NotNull 35 | public String getFieldName() { 36 | return fieldName; 37 | } 38 | 39 | @NotNull 40 | @Override 41 | public SortOrder getOrder() { 42 | return SortOrder.ASC; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "SimpleAscendingOrder{" + 48 | "fieldName='" + fieldName + '\'' + 49 | '}'; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/AbstractByteArraySortedSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | import com.yandex.yoctodb.util.UnsignedByteArray; 16 | import com.yandex.yoctodb.util.mutable.ByteArraySortedSet; 17 | 18 | import java.util.*; 19 | 20 | /** 21 | * {@link ByteArraySortedSet} abstract implementation with common methods 22 | * 23 | * @author incubos 24 | */ 25 | @NotThreadSafe 26 | abstract class AbstractByteArraySortedSet 27 | implements ByteArraySortedSet { 28 | final SortedSet elements; 29 | 30 | AbstractByteArraySortedSet( 31 | final SortedSet elements) { 32 | this.elements = elements; 33 | } 34 | 35 | @Override 36 | public int indexOf( 37 | @NotNull 38 | final UnsignedByteArray e) { 39 | assert elements.contains(e) : "No such element"; 40 | 41 | return elements.headSet(e).size(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/CachedArrayBitSetPool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.yandex.yoctodb.util.mutable.ArrayBitSet; 14 | import net.jcip.annotations.ThreadSafe; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | import java.util.Deque; 18 | import java.util.concurrent.ConcurrentLinkedDeque; 19 | 20 | /** 21 | * LIFO cache of {@link ArrayBitSet}s 22 | * 23 | * @author incubos 24 | */ 25 | @ThreadSafe 26 | public final class CachedArrayBitSetPool extends AbstractCachedArrayBitSetPool { 27 | @NotNull 28 | private final Deque cache = new ConcurrentLinkedDeque<>(); 29 | 30 | public CachedArrayBitSetPool( 31 | final int sizeHint, 32 | final float loadFactor) { 33 | super(sizeHint, loadFactor); 34 | } 35 | 36 | public CachedArrayBitSetPool() { 37 | this(DEFAULT_SIZE_HINT, DEFAULT_LOAD_FACTOR); 38 | } 39 | 40 | @NotNull 41 | @Override 42 | protected Deque getCache() { 43 | return cache; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/StringProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb; 12 | 13 | import com.yandex.yoctodb.immutable.Database; 14 | import com.yandex.yoctodb.query.DocumentProcessor; 15 | import com.yandex.yoctodb.util.buf.Buffer; 16 | import org.jetbrains.annotations.NotNull; 17 | 18 | import java.util.List; 19 | 20 | /** 21 | * String processor collecting documents in {@link List} to be used in 22 | * unit tests 23 | * 24 | * @author incubos 25 | */ 26 | class StringProcessor implements DocumentProcessor { 27 | private final List results; 28 | 29 | public StringProcessor(final List results) { 30 | this.results = results; 31 | } 32 | 33 | @Override 34 | public boolean process( 35 | final int document, 36 | final @NotNull Database database) { 37 | final Buffer payload = database.getDocument(document); 38 | final byte[] buf = new byte[(int) payload.remaining()]; 39 | payload.get(buf); 40 | results.add(new String(buf)); 41 | return true; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleDescendingOrder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import net.jcip.annotations.Immutable; 14 | import org.jetbrains.annotations.NotNull; 15 | import com.yandex.yoctodb.query.Order; 16 | 17 | /** 18 | * Descending order 19 | * 20 | * @author incubos 21 | */ 22 | @Immutable 23 | public final class SimpleDescendingOrder implements Order { 24 | @NotNull 25 | private final String fieldName; 26 | 27 | public SimpleDescendingOrder( 28 | @NotNull 29 | final String fieldName) { 30 | this.fieldName = fieldName; 31 | } 32 | 33 | @Override 34 | @NotNull 35 | public String getFieldName() { 36 | return fieldName; 37 | } 38 | 39 | @NotNull 40 | @Override 41 | public SortOrder getOrder() { 42 | return SortOrder.DESC; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "SimpleDescendingOrder{" + 48 | "fieldName='" + fieldName + '\'' + 49 | '}'; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![yoctodb-core](https://maven-badges.herokuapp.com/maven-central/com.yandex.yoctodb/yoctodb-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.yandex.yoctodb/yoctodb-core) [![Build Status](https://travis-ci.org/yandex/yoctodb.svg?branch=master)](https://travis-ci.org/yandex/yoctodb) [![Coverage Status](https://coveralls.io/repos/github/yandex/yoctodb/badge.svg?branch=master)](https://coveralls.io/github/yandex/yoctodb?branch=master) [![Javadocs](http://www.javadoc.io/badge/com.yandex.yoctodb/yoctodb-core.svg)](http://www.javadoc.io/doc/com.yandex.yoctodb/yoctodb-core) 2 | 3 | # YoctoDB 4 | 5 | YoctoDB is an embedded database engine with the following major features: 6 | 7 | * Java 8 8 | * Depends on Guava only 9 | * Immutable after construction 10 | * Optionally partitioned 11 | * Space-efficient 12 | * Flat document-oriented 13 | * Indexed fields for filtering/sorting 14 | * Embedded 15 | * `mmap`'ed (`ByteBuffer`'ed) 16 | 17 | See [Project Wiki](https://github.com/yandex/yoctodb/wiki/Home): 18 | 19 | * [Getting Started Guide](https://github.com/yandex/yoctodb/wiki/GettingStarted) 20 | * [Motivation](https://github.com/yandex/yoctodb/wiki/Motivation) 21 | * [Design](https://github.com/yandex/yoctodb/wiki/Design) 22 | * [Internal Benchmarks](https://github.com/yandex/yoctodb/wiki/InternalBenchmarks) 23 | 24 | Contact us through [YoctoDB User Group](https://groups.google.com/forum/#!forum/yoctodb). 25 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/DatabaseFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb; 12 | 13 | import net.jcip.annotations.ThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | import com.yandex.yoctodb.immutable.DatabaseReader; 16 | import com.yandex.yoctodb.mutable.DatabaseBuilder; 17 | import com.yandex.yoctodb.mutable.DocumentBuilder; 18 | import com.yandex.yoctodb.v1.V1DatabaseFormat; 19 | 20 | /** 21 | * Provides facilities to build a database using current format 22 | * 23 | * @author incubos 24 | */ 25 | @ThreadSafe 26 | public abstract class DatabaseFormat { 27 | public final static byte[] MAGIC = { 28 | (byte) 0x40, 29 | (byte) 0xC7, 30 | (byte) 0x0D, 31 | (byte) 0xB1 32 | }; 33 | 34 | @NotNull 35 | public static DatabaseFormat getCurrent() { 36 | return V1DatabaseFormat.INSTANCE; 37 | } 38 | 39 | @NotNull 40 | public abstract DocumentBuilder newDocumentBuilder(); 41 | 42 | @NotNull 43 | public abstract DatabaseBuilder newDatabaseBuilder(); 44 | 45 | @NotNull 46 | public abstract DatabaseReader getDatabaseReader(); 47 | } 48 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/VariableLengthByteArrayIndexedListTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.yandex.yoctodb.util.UnsignedByteArray; 14 | import com.yandex.yoctodb.util.mutable.ByteArrayIndexedList; 15 | import org.junit.Test; 16 | 17 | import java.util.Collection; 18 | import java.util.LinkedList; 19 | 20 | import static com.yandex.yoctodb.util.UnsignedByteArrays.from; 21 | import static org.junit.Assert.assertTrue; 22 | 23 | /** 24 | * Unit tests for {@link VariableLengthByteArrayIndexedList} 25 | * 26 | * @author incubos 27 | */ 28 | public class VariableLengthByteArrayIndexedListTest { 29 | @Test 30 | public void string() { 31 | final Collection elements = new LinkedList<>(); 32 | final int size = 10; 33 | for (int i = 0; i < size; i++) 34 | elements.add(from(i)); 35 | final ByteArrayIndexedList set = 36 | new VariableLengthByteArrayIndexedList(elements); 37 | final String text = set.toString(); 38 | assertTrue(text.contains(Integer.toString(size))); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/buf/BufferInputStreamTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.buf; 12 | 13 | import org.junit.Test; 14 | 15 | import java.io.IOException; 16 | import java.io.InputStream; 17 | 18 | import static org.junit.Assert.assertArrayEquals; 19 | import static org.junit.Assert.assertEquals; 20 | 21 | /** 22 | * Tests for {@link com.yandex.yoctodb.util.buf.BufferInputStream} 23 | * 24 | * @author incubos 25 | */ 26 | public class BufferInputStreamTest { 27 | private static final byte[] DATA = {0, 1, 2, 3}; 28 | 29 | @Test 30 | public void readByte() throws IOException { 31 | final InputStream is = new BufferInputStream(Buffer.from(DATA)); 32 | 33 | for (final byte aDATA : DATA) assertEquals(aDATA, is.read()); 34 | 35 | assertEquals(-1, is.read()); 36 | } 37 | 38 | @Test 39 | public void readBuffer() throws IOException { 40 | final InputStream is = new BufferInputStream(Buffer.from(DATA)); 41 | final byte[] buf = new byte[DATA.length]; 42 | 43 | assertEquals(buf.length, is.read(buf)); 44 | 45 | assertArrayEquals(DATA, buf); 46 | 47 | assertEquals(-1, is.read(buf)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/immutable/IndexToIndexMultiMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable; 12 | 13 | import net.jcip.annotations.Immutable; 14 | import org.jetbrains.annotations.NotNull; 15 | import com.yandex.yoctodb.util.mutable.BitSet; 16 | 17 | import java.util.Iterator; 18 | 19 | /** 20 | * @author svyatoslav 21 | */ 22 | @Immutable 23 | public interface IndexToIndexMultiMap { 24 | boolean get( 25 | @NotNull 26 | BitSet dest, 27 | int index); 28 | 29 | boolean getFrom( 30 | @NotNull 31 | BitSet dest, 32 | int fromInclusive); 33 | 34 | boolean getTo( 35 | @NotNull 36 | BitSet dest, 37 | int toExclusive); 38 | 39 | boolean getBetween( 40 | @NotNull 41 | BitSet dest, 42 | int fromInclusive, 43 | int toExclusive); 44 | 45 | @NotNull 46 | Iterator ascending( 47 | @NotNull 48 | BitSet valueFilter); 49 | 50 | @NotNull 51 | Iterator descending( 52 | @NotNull 53 | BitSet valueFilter); 54 | 55 | int getKeysCount(); 56 | } 57 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/Condition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query; 12 | 13 | import com.yandex.yoctodb.immutable.FilterableIndexProvider; 14 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 15 | import com.yandex.yoctodb.util.mutable.BitSet; 16 | import net.jcip.annotations.Immutable; 17 | import org.jetbrains.annotations.NotNull; 18 | 19 | /** 20 | * {@link Where} condition 21 | * 22 | * @author incubos 23 | */ 24 | @Immutable 25 | public interface Condition { 26 | /** 27 | * Set bits for the documents satisfying condition and leave all the other 28 | * bits untouched. 29 | * 30 | * {@code false} return value is used for short-circuiting, so it is safe 31 | * to return {@code true}, but not otherwise. 32 | * 33 | * @param indexProvider index provider 34 | * @param to container of filtered documents 35 | * @param bitSetPool temporary bit set pool 36 | * @return if at least one bit was set 37 | */ 38 | boolean set( 39 | @NotNull 40 | FilterableIndexProvider indexProvider, 41 | @NotNull 42 | BitSet to, 43 | @NotNull 44 | ArrayBitSetPool bitSetPool); 45 | } 46 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/common/TrieNodeMetadata.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2018 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.common; 12 | 13 | public final class TrieNodeMetadata { 14 | public static final int PREFIX_FLAG = 0b0001; // there is a prefix that must be consumed 15 | public static final int VALUE_FLAG = 0b0010; // there is a value in this node 16 | 17 | public static final int EDGES_NONE = 0b0000; // there is no edges 18 | public static final int EDGES_SINGLE = 0b0100; // there is exactly one edge 19 | public static final int EDGES_BITSET = 0b1000; // there is multiple scattered edges 20 | public static final int EDGES_CONDENSED = 0b1100; // there is multiple continuous edges 21 | 22 | private static final int EDGES_MASK = 0b1100; 23 | 24 | static { 25 | new TrieNodeMetadata(); // for coverage 26 | } 27 | 28 | public static int edgeType(final int metadata) { 29 | return metadata & EDGES_MASK; 30 | } 31 | 32 | public static boolean hasPrefix(final int metadata) { 33 | return (metadata & PREFIX_FLAG) != 0; 34 | } 35 | 36 | public static boolean hasValue(final int metadata) { 37 | return (metadata & VALUE_FLAG) != 0; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/immutable/IntToIntArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable; 12 | 13 | import net.jcip.annotations.Immutable; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | /** 17 | * List of {@code int} values with {@code int} key 18 | * 19 | * @author incubos 20 | */ 21 | @Immutable 22 | public final class IntToIntArray { 23 | private final int key; 24 | @NotNull 25 | private final int[] values; 26 | private final int count; 27 | 28 | public IntToIntArray( 29 | final int key, 30 | @NotNull 31 | final int[] values, 32 | final int count) { 33 | assert key >= 0; 34 | assert count > 0; 35 | assert values.length >= count; 36 | 37 | this.key = key; 38 | this.values = values; 39 | this.count = count; 40 | } 41 | 42 | public int getKey() { 43 | return key; 44 | } 45 | 46 | /** 47 | * Only first {@link #getCount()} elements have non {@code null} values 48 | * 49 | * @return values 50 | */ 51 | @NotNull 52 | public int[] getValues() { 53 | return values; 54 | } 55 | 56 | public int getCount() { 57 | return count; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/buf/ByteBufferWrapperTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.buf; 12 | 13 | import org.junit.Test; 14 | 15 | import static org.junit.Assert.assertEquals; 16 | 17 | /** 18 | * Tests for {@link com.yandex.yoctodb.util.buf.ByteBufferWrapper} 19 | * 20 | * @author dimas 21 | */ 22 | public class ByteBufferWrapperTest extends BufferTest { 23 | @Override 24 | protected Buffer bufferOf(byte[] data) { 25 | return Buffer.from(data); 26 | } 27 | 28 | @Test 29 | public void testGetShort() { 30 | short data = 32765; 31 | byte[] bytes = new byte[]{ 32 | (byte) ((data >> 8) & 0xff), 33 | (byte) ((data) & 0xff) 34 | }; 35 | final Buffer buf = Buffer.from(bytes); 36 | short result = buf.getShort(); 37 | assertEquals(data, result); 38 | } 39 | 40 | @Test 41 | public void testGetShortWithIndex() { 42 | short data = 32765; 43 | byte[] bytes = new byte[]{ 44 | (byte) ((data >> 8) & 0xff), 45 | (byte) ((data) & 0xff) 46 | }; 47 | final Buffer buf = Buffer.from(bytes); 48 | short result = buf.getShort(0); 49 | assertEquals(data, result); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/v1/mutable/V1DocumentBuilderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.mutable; 12 | 13 | import com.yandex.yoctodb.mutable.DocumentBuilder; 14 | import org.junit.Test; 15 | 16 | /** 17 | * Unit tests for {@link V1DocumentBuilder} 18 | * 19 | * @author incubos 20 | */ 21 | public class V1DocumentBuilderTest { 22 | @Test(expected = IllegalArgumentException.class) 23 | public void differentIndexOptions() { 24 | new V1DocumentBuilder() 25 | .withField("k", "v1", DocumentBuilder.IndexOption.FILTERABLE) 26 | .withField("k", "v2", DocumentBuilder.IndexOption.SORTABLE); 27 | } 28 | 29 | @Test(expected = IllegalArgumentException.class) 30 | public void differentLength() { 31 | new V1DocumentBuilder() 32 | .withField("k", "0", DocumentBuilder.IndexOption.FULL) 33 | .withField("k", 0, DocumentBuilder.IndexOption.FULL); 34 | } 35 | 36 | @Test(expected = IllegalArgumentException.class) 37 | public void payloadStoredField() { 38 | new V1DocumentBuilder() 39 | .withField( 40 | DocumentBuilder.PAYLOAD, 41 | "0", 42 | DocumentBuilder.IndexOption.STORED); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/v1/mutable/segment/V1FilterableIndexTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.mutable.segment; 12 | 13 | import com.yandex.yoctodb.util.UnsignedByteArray; 14 | import org.junit.Test; 15 | 16 | import java.util.Collections; 17 | 18 | import static com.yandex.yoctodb.util.UnsignedByteArrays.from; 19 | 20 | /** 21 | * Unit tests for {@link V1FilterableIndex} 22 | * 23 | * @author incubos 24 | */ 25 | public class V1FilterableIndexTest { 26 | @Test 27 | public void addDocument() { 28 | new V1FilterableIndex("field", true) 29 | .addDocument( 30 | 0, 31 | Collections.singletonList(from(0))); 32 | } 33 | 34 | @Test(expected = IllegalArgumentException.class) 35 | public void wrongDocument() { 36 | new V1FilterableIndex("field", true) 37 | .addDocument( 38 | -1, 39 | Collections.singletonList(from(0))); 40 | } 41 | 42 | @Test(expected = IllegalArgumentException.class) 43 | public void emptyValues() { 44 | new V1FilterableIndex("field", true) 45 | .addDocument( 46 | 0, 47 | Collections.emptyList()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/DoubleDatabaseProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb; 12 | 13 | import com.yandex.yoctodb.immutable.Database; 14 | import com.yandex.yoctodb.query.DocumentProcessor; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | import java.util.List; 18 | 19 | public class DoubleDatabaseProcessor implements DocumentProcessor { 20 | private final @NotNull Database negative; 21 | @NotNull 22 | private final Database positive; 23 | private final @NotNull List docs; 24 | 25 | public DoubleDatabaseProcessor( 26 | @NotNull 27 | final Database negative, 28 | @NotNull 29 | final Database positive, 30 | @NotNull 31 | final List docs) { 32 | this.negative = negative; 33 | this.positive = positive; 34 | this.docs = docs; 35 | } 36 | 37 | @Override 38 | public boolean process( 39 | final int document, 40 | @NotNull 41 | final Database database) { 42 | assert database == negative || database == positive; 43 | 44 | if (database == negative) { 45 | docs.add(-document); 46 | } else { 47 | docs.add(document); 48 | } 49 | 50 | return true; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/ThreadLocalCachedArrayBitSetPool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.yandex.yoctodb.util.mutable.ArrayBitSet; 14 | import net.jcip.annotations.ThreadSafe; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | import java.util.ArrayDeque; 18 | import java.util.Deque; 19 | 20 | /** 21 | * {@link ThreadLocal}-based LIFO cache of {@link ArrayBitSet}s 22 | * 23 | * @author incubos 24 | */ 25 | @ThreadSafe 26 | public final class ThreadLocalCachedArrayBitSetPool 27 | extends AbstractCachedArrayBitSetPool { 28 | private static class Cache extends ThreadLocal> { 29 | @Override 30 | protected Deque initialValue() { 31 | return new ArrayDeque<>(); 32 | } 33 | } 34 | 35 | @NotNull 36 | private final ThreadLocal> cache = new Cache(); 37 | 38 | public ThreadLocalCachedArrayBitSetPool( 39 | final int sizeHint, 40 | final float loadFactor) { 41 | super(sizeHint, loadFactor); 42 | } 43 | 44 | public ThreadLocalCachedArrayBitSetPool() { 45 | this(DEFAULT_SIZE_HINT, DEFAULT_LOAD_FACTOR); 46 | } 47 | 48 | @Override 49 | protected Deque getCache() { 50 | return cache.get(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/IdScoredDocument.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import net.jcip.annotations.Immutable; 14 | import org.jetbrains.annotations.NotNull; 15 | import com.yandex.yoctodb.immutable.Database; 16 | import com.yandex.yoctodb.query.ScoredDocument; 17 | 18 | /** 19 | * {@link ScoredDocument} implementation based on document ID 20 | * 21 | * @author incubos 22 | */ 23 | @Immutable 24 | public final class IdScoredDocument 25 | implements ScoredDocument { 26 | @NotNull 27 | private final Database database; 28 | private final int id; 29 | 30 | public IdScoredDocument( 31 | @NotNull 32 | final Database database, 33 | final int id) { 34 | assert 0 <= id && id < database.getDocumentCount(); 35 | 36 | this.database = database; 37 | this.id = id; 38 | } 39 | 40 | @NotNull 41 | @Override 42 | public Database getDatabase() { 43 | return database; 44 | } 45 | 46 | @Override 47 | public int getDocument() { 48 | return id; 49 | } 50 | 51 | @Override 52 | public int compareTo( 53 | @NotNull 54 | final IdScoredDocument o) { 55 | throw new UnsupportedOperationException("Comparing is not supported"); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/immutable/impl/IndexToIndexMultiMapReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable.impl; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import com.yandex.yoctodb.util.immutable.IndexToIndexMultiMap; 15 | import com.yandex.yoctodb.v1.V1DatabaseFormat; 16 | 17 | /** 18 | * @author svyatoslav 19 | */ 20 | public final class IndexToIndexMultiMapReader { 21 | 22 | private IndexToIndexMultiMapReader() { 23 | // 24 | } 25 | 26 | // For test coverage 27 | static { 28 | new IndexToIndexMultiMapReader(); 29 | } 30 | 31 | public static IndexToIndexMultiMap from( 32 | final Buffer byteBuffer) { 33 | final int type = byteBuffer.getInt(); 34 | if (type == V1DatabaseFormat.MultiMapType.LIST_BASED.getCode()) { 35 | return IntIndexToIndexMultiMap.from(byteBuffer.slice()); 36 | } else if (type == V1DatabaseFormat.MultiMapType.LONG_ARRAY_BIT_SET_BASED.getCode()) { 37 | return BitSetIndexToIndexMultiMap.from(byteBuffer.slice()); 38 | } else if (type == V1DatabaseFormat.MultiMapType.ASCENDING_BIT_SET_BASED.getCode()) { 39 | return AscendingBitSetIndexToIndexMultiMap.from(byteBuffer.slice()); 40 | } else { 41 | throw new UnsupportedOperationException( 42 | "Unsupported IndexToIndexMultiMap type: " + type); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/IntIndexToIndexMultiMapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.google.common.collect.TreeMultimap; 14 | import com.yandex.yoctodb.util.mutable.IndexToIndexMultiMap; 15 | import org.junit.Test; 16 | 17 | import java.io.ByteArrayOutputStream; 18 | import java.io.IOException; 19 | 20 | import static java.util.Collections.singletonList; 21 | import static org.junit.Assert.assertTrue; 22 | 23 | /** 24 | * Unit tests for {@link IntIndexToIndexMultiMap} 25 | * 26 | * @author incubos 27 | */ 28 | public class IntIndexToIndexMultiMapTest { 29 | @Test(expected = AssertionError.class) 30 | public void negativeValue() throws IOException { 31 | new IntIndexToIndexMultiMap( 32 | singletonList(singletonList(-1))) 33 | .writeTo(new ByteArrayOutputStream()); 34 | } 35 | 36 | @Test 37 | public void string() { 38 | final TreeMultimap elements = TreeMultimap.create(); 39 | final int documents = 10; 40 | for (int i = 0; i < documents; i++) 41 | elements.put(i / 2, i); 42 | final IndexToIndexMultiMap set = 43 | new IntIndexToIndexMultiMap( 44 | elements.asMap().values()); 45 | final String text = set.toString(); 46 | assertTrue(text.contains(Integer.toString(documents / 2))); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/v1/immutable/QueryContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.immutable; 12 | 13 | import com.yandex.yoctodb.immutable.IndexedDatabase; 14 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 15 | import com.yandex.yoctodb.util.mutable.BitSet; 16 | import org.jetbrains.annotations.NotNull; 17 | 18 | /** 19 | * Pair of database and its document {@link BitSet} 20 | * 21 | * @author incubos 22 | */ 23 | final class QueryContext { 24 | @NotNull 25 | private final BitSet docs; 26 | @NotNull 27 | private final IndexedDatabase database; 28 | @NotNull 29 | private final ArrayBitSetPool bitSetPool; 30 | 31 | QueryContext( 32 | @NotNull 33 | final BitSet docs, 34 | @NotNull 35 | final IndexedDatabase database, 36 | @NotNull 37 | final ArrayBitSetPool bitSetPool) { 38 | assert !docs.isEmpty(); 39 | assert database.getDocumentCount() == docs.getSize(); 40 | 41 | this.docs = docs; 42 | this.database = database; 43 | this.bitSetPool = bitSetPool; 44 | } 45 | 46 | @NotNull 47 | public BitSet getDocs() { 48 | return docs; 49 | } 50 | 51 | @NotNull 52 | public IndexedDatabase getDatabase() { 53 | return database; 54 | } 55 | 56 | @NotNull 57 | public ArrayBitSetPool getBitSetPool() { 58 | return bitSetPool; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/v1/immutable/SortResultIterator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.immutable; 12 | 13 | import com.yandex.yoctodb.query.Query; 14 | import com.yandex.yoctodb.query.ScoredDocument; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | import java.util.Iterator; 18 | 19 | /** 20 | * Applies query sorting to each of the databases 21 | * 22 | * @author incubos 23 | */ 24 | class SortResultIterator 25 | implements Iterator>> { 26 | @NotNull 27 | private final Query query; 28 | @NotNull 29 | private final Iterator dbs; 30 | 31 | SortResultIterator( 32 | @NotNull 33 | final Query query, 34 | @NotNull 35 | final Iterator dbs) { 36 | this.query = query; 37 | this.dbs = dbs; 38 | } 39 | 40 | @Override 41 | public boolean hasNext() { 42 | return dbs.hasNext(); 43 | } 44 | 45 | @NotNull 46 | @Override 47 | public Iterator> next() { 48 | final QueryContext db = dbs.next(); 49 | return query.sortedUnlimited( 50 | db.getDocs(), 51 | db.getDatabase(), 52 | db.getBitSetPool()); 53 | } 54 | 55 | @Override 56 | public void remove() { 57 | throw new UnsupportedOperationException( 58 | "Removal is not supported"); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleNotCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.immutable.FilterableIndexProvider; 14 | import com.yandex.yoctodb.query.Condition; 15 | import com.yandex.yoctodb.util.mutable.ArrayBitSet; 16 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 17 | import com.yandex.yoctodb.util.mutable.BitSet; 18 | import net.jcip.annotations.Immutable; 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | /** 22 | * Condition negation 23 | * 24 | * @author incubos 25 | */ 26 | @Immutable 27 | public final class SimpleNotCondition implements Condition { 28 | @NotNull 29 | private final Condition delegate; 30 | 31 | public SimpleNotCondition( 32 | @NotNull 33 | final Condition delegate) { 34 | this.delegate = delegate; 35 | } 36 | 37 | @Override 38 | public boolean set( 39 | @NotNull 40 | final FilterableIndexProvider indexProvider, 41 | @NotNull 42 | final BitSet to, 43 | @NotNull 44 | final ArrayBitSetPool bitSetPool) { 45 | final ArrayBitSet result = bitSetPool.borrowSet(to.getSize()); 46 | try { 47 | delegate.set(indexProvider, result, bitSetPool); 48 | result.inverse(); 49 | return to.or(result); 50 | } finally { 51 | bitSetPool.returnSet(result); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/buf/BufferInputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.buf; 12 | 13 | import net.jcip.annotations.NotThreadSafe; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | import java.io.InputStream; 17 | 18 | /** 19 | * {@link java.io.InputStream} implementation wrapping {@link com.yandex.yoctodb.util.buf.Buffer} 20 | * 21 | * @author dimas 22 | * @author incubos 23 | */ 24 | @NotThreadSafe 25 | public final class BufferInputStream extends InputStream { 26 | @NotNull 27 | private final Buffer buf; 28 | 29 | public BufferInputStream( 30 | @NotNull 31 | final Buffer buf) { 32 | this.buf = buf; 33 | } 34 | 35 | public int read() { 36 | if (buf.hasRemaining()) { 37 | return buf.get() & 0xFF; 38 | } else { 39 | return -1; 40 | } 41 | } 42 | 43 | public int read( 44 | @NotNull 45 | final byte[] bytes, 46 | final int off, 47 | final int len) { 48 | if (buf.hasRemaining()) { 49 | final int remaining = 50 | buf.remaining() > Integer.MAX_VALUE ? 51 | Integer.MAX_VALUE : 52 | (int) buf.remaining(); 53 | final int toRead = Math.min(len, remaining); 54 | 55 | buf.get(bytes, off, toRead); 56 | 57 | return toRead; 58 | } else { 59 | return -1; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/immutable/impl/IntIndexToIndexMapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable.impl; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import com.yandex.yoctodb.util.immutable.IndexToIndexMap; 15 | import org.junit.Test; 16 | 17 | import java.io.ByteArrayOutputStream; 18 | import java.io.IOException; 19 | 20 | import static org.junit.Assert.assertEquals; 21 | import static org.junit.Assert.assertTrue; 22 | 23 | /** 24 | * Unit tests for {@link IntIndexToIndexMap} 25 | * 26 | * @author incubos 27 | */ 28 | public class IntIndexToIndexMapTest { 29 | private final int VALUES = 128; 30 | 31 | private IndexToIndexMap build() throws IOException { 32 | final com.yandex.yoctodb.util.mutable.IndexToIndexMap mutable = 33 | new com.yandex.yoctodb.util.mutable.impl.IntIndexToIndexMap(); 34 | for (int i = 0; i < VALUES; i++) { 35 | mutable.put(i, i * 2); 36 | } 37 | 38 | final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 39 | mutable.writeTo(baos); 40 | 41 | final Buffer buf = Buffer.from(baos.toByteArray()); 42 | 43 | final IndexToIndexMap result = 44 | IntIndexToIndexMap.from(buf); 45 | 46 | assertEquals(VALUES, result.size()); 47 | 48 | return result; 49 | } 50 | 51 | @Test 52 | public void string() throws IOException { 53 | assertTrue(build().toString().contains(Integer.toString(VALUES))); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleOrCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.immutable.FilterableIndexProvider; 14 | import com.yandex.yoctodb.query.Condition; 15 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 16 | import com.yandex.yoctodb.util.mutable.BitSet; 17 | import net.jcip.annotations.Immutable; 18 | import org.jetbrains.annotations.NotNull; 19 | 20 | import java.util.ArrayList; 21 | import java.util.Collection; 22 | 23 | /** 24 | * {@code OR} condition 25 | * 26 | * @author incubos 27 | */ 28 | @Immutable 29 | public final class SimpleOrCondition implements Condition { 30 | @NotNull 31 | private final Iterable clauses; 32 | 33 | public SimpleOrCondition( 34 | @NotNull 35 | final Collection conditions) { 36 | if (conditions.isEmpty()) 37 | throw new IllegalArgumentException("No conditions"); 38 | 39 | this.clauses = new ArrayList<>(conditions); 40 | } 41 | 42 | @Override 43 | public boolean set( 44 | @NotNull 45 | final FilterableIndexProvider indexProvider, 46 | @NotNull 47 | final BitSet to, 48 | @NotNull 49 | final ArrayBitSetPool bitSetPool) { 50 | boolean notEmpty = false; 51 | for (Condition clause : clauses) 52 | if (clause.set(indexProvider, to, bitSetPool)) 53 | notEmpty = true; 54 | 55 | return notEmpty; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleScoredDocument.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import net.jcip.annotations.Immutable; 14 | import org.jetbrains.annotations.NotNull; 15 | import com.yandex.yoctodb.immutable.Database; 16 | import com.yandex.yoctodb.query.ScoredDocument; 17 | 18 | /** 19 | * {@link ScoredDocument} implementation for simple queries 20 | * 21 | * @author incubos 22 | */ 23 | @Immutable 24 | final class SimpleScoredDocument 25 | implements ScoredDocument { 26 | @NotNull 27 | private final Database database; 28 | @NotNull 29 | private final SimpleDocumentMultiScore score; 30 | private final int document; 31 | 32 | SimpleScoredDocument( 33 | @NotNull 34 | final Database database, 35 | @NotNull 36 | final SimpleDocumentMultiScore score, 37 | final int document) { 38 | assert 0 <= document && document < database.getDocumentCount(); 39 | 40 | this.database = database; 41 | this.score = score; 42 | this.document = document; 43 | } 44 | 45 | @NotNull 46 | @Override 47 | public Database getDatabase() { 48 | return database; 49 | } 50 | 51 | @Override 52 | public int getDocument() { 53 | return document; 54 | } 55 | 56 | @Override 57 | public int compareTo( 58 | @NotNull 59 | final SimpleScoredDocument o) { 60 | return score.compareTo(o.score); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/immutable/DatabaseReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.immutable; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 15 | import com.yandex.yoctodb.util.mutable.impl.AllocatingArrayBitSetPool; 16 | import net.jcip.annotations.ThreadSafe; 17 | import org.jetbrains.annotations.NotNull; 18 | 19 | import java.util.Collection; 20 | 21 | /** 22 | * Builds immutable {@link Database} from file or {@link Buffer} 23 | * 24 | * @author incubos 25 | */ 26 | @ThreadSafe 27 | public abstract class DatabaseReader { 28 | @NotNull 29 | public IndexedDatabase from( 30 | @NotNull 31 | final Buffer buffer) { 32 | return from(buffer, AllocatingArrayBitSetPool.INSTANCE, true); 33 | } 34 | 35 | @NotNull 36 | public abstract IndexedDatabase from( 37 | @NotNull 38 | Buffer b, 39 | @NotNull 40 | ArrayBitSetPool bitSetPool, 41 | boolean checksum); 42 | 43 | @NotNull 44 | public abstract Database composite( 45 | @NotNull 46 | Collection databases, 47 | @NotNull 48 | ArrayBitSetPool bitSetPool); 49 | 50 | @NotNull 51 | public Database composite( 52 | @NotNull 53 | final Collection databases) { 54 | return composite( 55 | databases, 56 | AllocatingArrayBitSetPool.INSTANCE); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/v1/immutable/segment/Segments.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.immutable.segment; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | /** 17 | * Utility methods for segments 18 | * 19 | * @author incubos 20 | */ 21 | final class Segments { 22 | private Segments() { 23 | // 24 | } 25 | 26 | // For test coverage 27 | static { 28 | new Segments(); 29 | } 30 | 31 | /** 32 | * Reads {@code long} segment size, extracts the slice and advances 33 | * {@code from} buffer 34 | * 35 | * @param from buffer to extract segment slice from 36 | * @return segment slice 37 | */ 38 | @NotNull 39 | static Buffer extract( 40 | @NotNull 41 | final Buffer from) { 42 | final long size = from.getLong(); 43 | final Buffer result = from.slice(size); 44 | from.advance(size); 45 | return result; 46 | } 47 | 48 | /** 49 | * Reads {@code int} string size, extracts the string and advances 50 | * {@code from} buffer 51 | * 52 | * @param from buffer to extract the string from 53 | * @return extracted string 54 | */ 55 | @NotNull 56 | static String extractString( 57 | @NotNull 58 | final Buffer from) { 59 | final int size = from.getInt(); 60 | final byte[] buffer = new byte[size]; 61 | from.get(buffer); 62 | 63 | return new String(buffer); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/stored/VariableLengthByteArrayIndexedListTest.java: -------------------------------------------------------------------------------- 1 | package com.yandex.yoctodb.util.mutable.stored; 2 | 3 | import com.yandex.yoctodb.util.UnsignedByteArray; 4 | import com.yandex.yoctodb.util.UnsignedByteArrays; 5 | import com.yandex.yoctodb.util.mutable.impl.VariableLengthByteArrayIndexedList; 6 | import org.junit.Test; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Collection; 10 | import java.util.HashSet; 11 | 12 | /** 13 | * {@link com.yandex.yoctodb.util.immutable.ByteArrayIndexedList} with fixed size 14 | * elements 15 | * 16 | * @author irenkamalova 17 | */ 18 | public class VariableLengthByteArrayIndexedListTest { 19 | 20 | @Test 21 | public void buildV1StoredIndex() { 22 | final Collection elements = initElements(); 23 | VariableLengthByteArrayIndexedList indexedList = 24 | new VariableLengthByteArrayIndexedList(elements); 25 | 26 | assert indexedList.getSizeInBytes() == getSizeInBytes(elements); 27 | } 28 | 29 | private Collection initElements() { 30 | Collection elements = new ArrayList<>(); 31 | elements.add(UnsignedByteArrays.from("NEW")); 32 | elements.add(UnsignedByteArrays.from("USED")); 33 | return elements; 34 | } 35 | 36 | public long getSizeInBytes(Collection elements) { 37 | Collection uniqueElements = new HashSet<>(); 38 | 39 | long elemSum = 0; 40 | for (UnsignedByteArray elem : elements) { 41 | if (uniqueElements.add(elem)) { 42 | elemSum = elemSum + elem.length(); 43 | } 44 | } 45 | return 4L + // Element count 46 | 8L * (elements.size() + 1L) + // Element offsets 47 | elemSum; // Element array size 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/immutable/IntIndexToIndexMapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import org.junit.Assert; 15 | import org.junit.Test; 16 | import com.yandex.yoctodb.util.immutable.impl.IntIndexToIndexMap; 17 | 18 | import java.io.ByteArrayOutputStream; 19 | import java.io.IOException; 20 | 21 | /** 22 | * @author svyatoslav 23 | */ 24 | public class IntIndexToIndexMapTest { 25 | @Test 26 | public void simpleTest() throws IOException { 27 | for (int counter = 1; counter < 1024; counter++) { 28 | final Buffer buf = prepareData(counter); 29 | final IndexToIndexMap map = IntIndexToIndexMap.from(buf); 30 | Assert.assertEquals(counter, map.size()); 31 | for (int i = 0; i < counter; i++) { 32 | Assert.assertEquals(counter - i, map.get(i)); 33 | } 34 | } 35 | } 36 | 37 | private Buffer prepareData(final int size) throws IOException { 38 | final com.yandex.yoctodb.util.mutable.IndexToIndexMap indexToIndexMap = 39 | new com.yandex.yoctodb.util.mutable.impl.IntIndexToIndexMap(); 40 | for (int i = 0; i < size; i++) { 41 | indexToIndexMap.put(i, size - i); 42 | } 43 | 44 | final ByteArrayOutputStream os = new ByteArrayOutputStream(); 45 | indexToIndexMap.writeTo(os); 46 | Assert.assertEquals(os.size(), indexToIndexMap.getSizeInBytes()); 47 | return Buffer.from(os.toByteArray()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/v1/mutable/segment/V1StoredIndexTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.mutable.segment; 12 | 13 | import com.yandex.yoctodb.util.UnsignedByteArray; 14 | import org.junit.Test; 15 | 16 | import java.util.Arrays; 17 | import java.util.Collections; 18 | 19 | import static com.yandex.yoctodb.util.UnsignedByteArrays.from; 20 | 21 | /** 22 | * Unit tests for {@link V1StoredIndex} 23 | * 24 | * @author incubos 25 | */ 26 | public class V1StoredIndexTest { 27 | @Test 28 | public void addDocument() { 29 | new V1StoredIndex("field") 30 | .addDocument( 31 | 0, 32 | Collections.singletonList(from(0))); 33 | } 34 | 35 | @Test(expected = IllegalArgumentException.class) 36 | public void wrongDocument() { 37 | new V1StoredIndex("field") 38 | .addDocument( 39 | -1, 40 | Collections.singletonList(from(0))); 41 | } 42 | 43 | @Test(expected = IllegalArgumentException.class) 44 | public void emptyValues() { 45 | new V1StoredIndex("field") 46 | .addDocument( 47 | 0, 48 | Collections.emptyList()); 49 | } 50 | 51 | @Test(expected = IllegalArgumentException.class) 52 | public void multipleValues() { 53 | new V1StoredIndex("field") 54 | .addDocument( 55 | 0, 56 | Arrays.asList(from(0), from(1))); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/IntIndexToIndexMapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.yandex.yoctodb.util.mutable.IndexToIndexMap; 14 | import org.junit.Test; 15 | 16 | import java.io.ByteArrayOutputStream; 17 | import java.io.IOException; 18 | 19 | import static org.junit.Assert.assertTrue; 20 | 21 | /** 22 | * Unit tests for {@link IntIndexToIndexMap} 23 | * 24 | * @author incubos 25 | */ 26 | public class IntIndexToIndexMapTest { 27 | @Test(expected = IllegalArgumentException.class) 28 | public void negativeKey() { 29 | new IntIndexToIndexMap().put(-1, 0); 30 | } 31 | 32 | @Test(expected = IllegalArgumentException.class) 33 | public void negativeValue() { 34 | new IntIndexToIndexMap().put(0, -1); 35 | } 36 | 37 | @Test(expected = IllegalStateException.class) 38 | public void nonContinuous() throws IOException { 39 | final IndexToIndexMap idx = new IntIndexToIndexMap(); 40 | idx.put(0, 0); 41 | idx.put(2, 0); 42 | idx.writeTo(new ByteArrayOutputStream()); 43 | } 44 | 45 | @Test(expected = IllegalArgumentException.class) 46 | public void overwrite() { 47 | final IndexToIndexMap idx = new IntIndexToIndexMap(); 48 | idx.put(0, 0); 49 | idx.put(0, 0); 50 | } 51 | 52 | @Test 53 | public void string() { 54 | final IndexToIndexMap idx = new IntIndexToIndexMap(); 55 | idx.put(0, 0); 56 | idx.put(1, 0); 57 | assertTrue(idx.toString().contains("2")); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleEqualityCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.immutable.FilterableIndex; 14 | import com.yandex.yoctodb.immutable.FilterableIndexProvider; 15 | import com.yandex.yoctodb.util.UnsignedByteArray; 16 | import com.yandex.yoctodb.util.buf.Buffer; 17 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 18 | import com.yandex.yoctodb.util.mutable.BitSet; 19 | import net.jcip.annotations.Immutable; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | /** 23 | * Equality condition 24 | * 25 | * @author incubos 26 | */ 27 | @Immutable 28 | public final class SimpleEqualityCondition extends AbstractTermCondition { 29 | @NotNull 30 | private final Buffer value; 31 | 32 | public SimpleEqualityCondition( 33 | @NotNull 34 | final String fieldName, 35 | @NotNull 36 | final UnsignedByteArray value) { 37 | super(fieldName); 38 | 39 | if (value.length() == 0) 40 | throw new IllegalArgumentException("Empty value"); 41 | 42 | this.value = value.toByteBuffer(); 43 | } 44 | 45 | @Override 46 | public boolean set( 47 | @NotNull 48 | final FilterableIndexProvider indexProvider, 49 | @NotNull 50 | final BitSet to, 51 | @NotNull 52 | final ArrayBitSetPool bitSetPool) { 53 | final FilterableIndex index = indexProvider.getFilter(getFieldName()); 54 | return index != null && index.eq(to, value); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleLessThanCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.immutable.FilterableIndex; 14 | import com.yandex.yoctodb.immutable.FilterableIndexProvider; 15 | import com.yandex.yoctodb.util.UnsignedByteArray; 16 | import com.yandex.yoctodb.util.buf.Buffer; 17 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 18 | import com.yandex.yoctodb.util.mutable.BitSet; 19 | import net.jcip.annotations.Immutable; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | /** 23 | * Less than condition 24 | * 25 | * @author incubos 26 | */ 27 | @Immutable 28 | public final class SimpleLessThanCondition extends AbstractTermCondition { 29 | @NotNull 30 | private final Buffer value; 31 | 32 | public SimpleLessThanCondition( 33 | @NotNull 34 | final String fieldName, 35 | @NotNull 36 | final UnsignedByteArray value) { 37 | super(fieldName); 38 | 39 | if (value.length() == 0) 40 | throw new IllegalArgumentException("Empty value"); 41 | 42 | this.value = value.toByteBuffer(); 43 | } 44 | 45 | @Override 46 | public boolean set( 47 | @NotNull 48 | final FilterableIndexProvider indexProvider, 49 | @NotNull 50 | final BitSet to, 51 | @NotNull 52 | final ArrayBitSetPool bitSetPool) { 53 | final FilterableIndex index = indexProvider.getFilter(getFieldName()); 54 | return index != null && index.lessThan(to, value, false); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/immutable/FilterableIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.immutable; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import net.jcip.annotations.Immutable; 15 | import org.jetbrains.annotations.NotNull; 16 | import com.yandex.yoctodb.util.mutable.BitSet; 17 | 18 | /** 19 | * Index filtering documents. 20 | * 21 | * The contract of each comparison method is: 22 | * Set to one bits in {@code dest} for conforming documents and 23 | * leave the other bits untouched. 24 | * 25 | * Each method returns {@code boolean} result stating if any bit was set. 26 | * 27 | * @author incubos 28 | */ 29 | @Immutable 30 | public interface FilterableIndex extends Index { 31 | boolean eq( 32 | @NotNull 33 | BitSet dest, 34 | @NotNull 35 | Buffer value); 36 | 37 | boolean in( 38 | @NotNull 39 | BitSet dest, 40 | @NotNull 41 | Buffer... value); 42 | 43 | boolean lessThan( 44 | @NotNull 45 | BitSet dest, 46 | @NotNull 47 | Buffer value, 48 | boolean orEquals); 49 | 50 | boolean greaterThan( 51 | @NotNull 52 | BitSet dest, 53 | @NotNull 54 | Buffer value, 55 | boolean orEquals); 56 | 57 | boolean between( 58 | @NotNull 59 | BitSet dest, 60 | @NotNull 61 | Buffer from, 62 | boolean fromInclusive, 63 | @NotNull 64 | Buffer to, 65 | boolean toInclusive); 66 | } 67 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleGreaterThanCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.immutable.FilterableIndex; 14 | import com.yandex.yoctodb.immutable.FilterableIndexProvider; 15 | import com.yandex.yoctodb.util.UnsignedByteArray; 16 | import com.yandex.yoctodb.util.buf.Buffer; 17 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 18 | import com.yandex.yoctodb.util.mutable.BitSet; 19 | import net.jcip.annotations.Immutable; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | /** 23 | * Greater than condition 24 | * 25 | * @author incubos 26 | */ 27 | @Immutable 28 | public final class SimpleGreaterThanCondition extends AbstractTermCondition { 29 | @NotNull 30 | private final Buffer value; 31 | 32 | public SimpleGreaterThanCondition( 33 | @NotNull 34 | final String fieldName, 35 | @NotNull 36 | final UnsignedByteArray value) { 37 | super(fieldName); 38 | 39 | if (value.length() == 0) 40 | throw new IllegalArgumentException("Empty value"); 41 | 42 | this.value = value.toByteBuffer(); 43 | } 44 | 45 | @Override 46 | public boolean set( 47 | @NotNull 48 | final FilterableIndexProvider indexProvider, 49 | @NotNull 50 | final BitSet to, 51 | @NotNull 52 | final ArrayBitSetPool bitSetPool) { 53 | final FilterableIndex index = indexProvider.getFilter(getFieldName()); 54 | return index != null && index.greaterThan(to, value, false); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/FixedLengthByteArrayIndexedListTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.google.common.primitives.Ints; 14 | import com.yandex.yoctodb.util.UnsignedByteArray; 15 | import com.yandex.yoctodb.util.mutable.ByteArrayIndexedList; 16 | import org.junit.Test; 17 | 18 | import java.io.ByteArrayOutputStream; 19 | import java.io.IOException; 20 | import java.util.Collection; 21 | import java.util.LinkedList; 22 | 23 | import static com.yandex.yoctodb.util.UnsignedByteArrays.from; 24 | import static java.util.Arrays.asList; 25 | import static org.junit.Assert.assertTrue; 26 | 27 | /** 28 | * Unit tests for {@link FixedLengthByteArrayIndexedList} 29 | * 30 | * @author incubos 31 | */ 32 | public class FixedLengthByteArrayIndexedListTest { 33 | @Test(expected = AssertionError.class) 34 | public void expectFixed() throws IOException { 35 | new FixedLengthByteArrayIndexedList(asList(from(1), from(1L))) 36 | .writeTo(new ByteArrayOutputStream()); 37 | } 38 | 39 | @Test 40 | public void string() { 41 | final Collection elements = 42 | new LinkedList<>(); 43 | final int size = 10; 44 | for (int i = 0; i < size; i++) 45 | elements.add(from(i)); 46 | final ByteArrayIndexedList set = 47 | new FixedLengthByteArrayIndexedList(elements); 48 | final String text = set.toString(); 49 | assertTrue(text.contains(Integer.toString(size))); 50 | assertTrue(text.contains(Integer.toString(Ints.BYTES))); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/TrieByteArraySortedSetTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2018 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.yandex.yoctodb.util.UnsignedByteArray; 14 | import com.yandex.yoctodb.util.UnsignedByteArrays; 15 | import org.junit.Test; 16 | 17 | import java.util.*; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | 21 | /** 22 | * Unit tests for {@code TrieByteArraySortedSet} 23 | * 24 | * @author Andrey Korzinev (ya-goodfella@yandex.com) 25 | */ 26 | public class TrieByteArraySortedSetTest { 27 | private static final TrieByteArraySortedSet tbs; 28 | 29 | static { 30 | List lst = Arrays.asList("a", "as", "ass", "assignment", "car", "card", "care", "careful", "carl", "cars", "cat"); 31 | 32 | SortedSet set = new TreeSet<>(); 33 | for (String str : lst) { 34 | set.add(UnsignedByteArrays.from(str)); 35 | } 36 | 37 | tbs = new TrieByteArraySortedSet(set); 38 | } 39 | 40 | @Test 41 | public void indexOf() { 42 | assertEquals(3, tbs.indexOf(UnsignedByteArrays.from("assignment"))); 43 | } 44 | 45 | @Test(expected = NoSuchElementException.class) 46 | public void invalidIndexOf() { 47 | tbs.indexOf(UnsignedByteArrays.from("z")); 48 | } 49 | 50 | @Test(expected = NoSuchElementException.class) 51 | public void invalidIndexOf2() { 52 | tbs.indexOf(UnsignedByteArrays.from("assignm")); 53 | } 54 | 55 | @Test(expected = NoSuchElementException.class) 56 | public void invalidIndexOf3() { 57 | tbs.indexOf(UnsignedByteArrays.from("ca")); 58 | } 59 | } -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleLessThanOrEqualsCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.immutable.FilterableIndexProvider; 14 | import com.yandex.yoctodb.util.buf.Buffer; 15 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 16 | import net.jcip.annotations.Immutable; 17 | import org.jetbrains.annotations.NotNull; 18 | import com.yandex.yoctodb.immutable.FilterableIndex; 19 | import com.yandex.yoctodb.util.UnsignedByteArray; 20 | import com.yandex.yoctodb.util.mutable.BitSet; 21 | 22 | /** 23 | * Less than or equals condition 24 | * 25 | * @author incubos 26 | */ 27 | @Immutable 28 | public final class SimpleLessThanOrEqualsCondition 29 | extends AbstractTermCondition { 30 | @NotNull 31 | private final Buffer value; 32 | 33 | public SimpleLessThanOrEqualsCondition( 34 | @NotNull 35 | final String fieldName, 36 | @NotNull 37 | final UnsignedByteArray value) { 38 | super(fieldName); 39 | 40 | if (value.length() == 0) 41 | throw new IllegalArgumentException("Empty value"); 42 | 43 | this.value = value.toByteBuffer(); 44 | } 45 | 46 | @Override 47 | public boolean set( 48 | @NotNull 49 | final FilterableIndexProvider indexProvider, 50 | @NotNull 51 | final BitSet to, 52 | @NotNull 53 | final ArrayBitSetPool bitSetPool) { 54 | final FilterableIndex index = indexProvider.getFilter(getFieldName()); 55 | return index != null && index.lessThan(to, value, true); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/immutable/ExecutionEngine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.immutable; 12 | 13 | import com.yandex.yoctodb.query.DocumentProcessor; 14 | import com.yandex.yoctodb.query.Query; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | /** 18 | * Provides means to query {@link Database} 19 | * 20 | * @author incubos 21 | */ 22 | public interface ExecutionEngine { 23 | /** 24 | * Execute {@code query} and apply {@code processor} to the documents found 25 | * 26 | * @param query query to be executed 27 | * @param processor document processor 28 | */ 29 | void execute( 30 | @NotNull 31 | Query query, 32 | @NotNull 33 | DocumentProcessor processor); 34 | 35 | /** 36 | * The same as {@link #execute(Query, DocumentProcessor)} 37 | * but also returns count of unlimited documents (filtered documents 38 | * without {@code skip} and {@code limit}) 39 | * 40 | * @param query query to be executed 41 | * @param processor document processor 42 | * @return count of unlimited documents 43 | */ 44 | int executeAndUnlimitedCount( 45 | @NotNull 46 | Query query, 47 | @NotNull 48 | DocumentProcessor processor); 49 | 50 | /** 51 | * The same as {@link #execute(Query, DocumentProcessor)}, but only 52 | * counts the documents satisfying the query 53 | * 54 | * @param query query to be executed 55 | * @return count of documents satisfying the query 56 | */ 57 | int count( 58 | @NotNull 59 | Query query); 60 | } 61 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleGreaterThanOrEqualsCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.immutable.FilterableIndex; 14 | import com.yandex.yoctodb.immutable.FilterableIndexProvider; 15 | import com.yandex.yoctodb.util.UnsignedByteArray; 16 | import com.yandex.yoctodb.util.buf.Buffer; 17 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 18 | import com.yandex.yoctodb.util.mutable.BitSet; 19 | import net.jcip.annotations.Immutable; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | /** 23 | * Greater than or equals condition 24 | * 25 | * @author incubos 26 | */ 27 | @Immutable 28 | public final class SimpleGreaterThanOrEqualsCondition 29 | extends AbstractTermCondition { 30 | @NotNull 31 | private final Buffer value; 32 | 33 | public SimpleGreaterThanOrEqualsCondition( 34 | @NotNull 35 | final String fieldName, 36 | @NotNull 37 | final UnsignedByteArray value) { 38 | super(fieldName); 39 | 40 | if (value.length() == 0) 41 | throw new IllegalArgumentException("Empty value"); 42 | 43 | this.value = value.toByteBuffer(); 44 | } 45 | 46 | @Override 47 | public boolean set( 48 | @NotNull 49 | final FilterableIndexProvider indexProvider, 50 | @NotNull 51 | final BitSet to, 52 | @NotNull 53 | final ArrayBitSetPool bitSetPool) { 54 | final FilterableIndex index = indexProvider.getFilter(getFieldName()); 55 | return index != null && index.greaterThan(to, value, true); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/immutable/StoredIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.immutable; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import net.jcip.annotations.Immutable; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | /** 18 | * Index storing field values 19 | * 20 | * @author incubos 21 | */ 22 | @Immutable 23 | public interface StoredIndex extends Index { 24 | /** 25 | * Get stored value by document ID 26 | * 27 | * @param document document ID 28 | * @return stored value 29 | */ 30 | @NotNull 31 | Buffer getStoredValue(int document); 32 | 33 | /** 34 | * Get stored value as long by document ID 35 | * 36 | * @param document document ID 37 | * @return stored value as long 38 | */ 39 | long getLongValue(int document); 40 | 41 | /** 42 | * Get stored value as int by document ID 43 | * 44 | * @param document document ID 45 | * @return stored value as int 46 | */ 47 | int getIntValue(int document); 48 | 49 | /** 50 | * Get stored value as short by document ID 51 | * 52 | * @param document document ID 53 | * @return stored value as short 54 | */ 55 | short getShortValue(int document); 56 | 57 | /** 58 | * Get stored value as char by document ID 59 | * 60 | * @param document document ID 61 | * @return stored value as char 62 | */ 63 | char getCharValue(int document); 64 | 65 | /** 66 | * Get stored value as byte by document ID 67 | * 68 | * @param document document ID 69 | * @return stored value as byte 70 | */ 71 | byte getByteValue(int document); 72 | } 73 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/IdScoredDocumentIterator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import org.jetbrains.annotations.NotNull; 14 | import com.yandex.yoctodb.immutable.Database; 15 | import com.yandex.yoctodb.util.mutable.BitSet; 16 | 17 | import java.util.Iterator; 18 | import java.util.NoSuchElementException; 19 | 20 | /** 21 | * {@link Iterator} implementation mapping document IDs to {@link 22 | * IdScoredDocument}s 23 | * 24 | * @author incubos 25 | */ 26 | final class IdScoredDocumentIterator 27 | implements Iterator { 28 | @NotNull 29 | private final Database database; 30 | @NotNull 31 | private final BitSet docs; 32 | private int currentDoc; 33 | 34 | IdScoredDocumentIterator( 35 | @NotNull 36 | final Database database, 37 | @NotNull 38 | final BitSet docs) { 39 | assert docs.getSize() == database.getDocumentCount(); 40 | 41 | this.database = database; 42 | this.docs = docs; 43 | this.currentDoc = docs.nextSetBit(0); 44 | } 45 | 46 | @Override 47 | public boolean hasNext() { 48 | return currentDoc >= 0; 49 | } 50 | 51 | @Override 52 | public IdScoredDocument next() { 53 | if (!hasNext()) 54 | throw new NoSuchElementException(); 55 | 56 | final int id = currentDoc; 57 | currentDoc = docs.nextSetBit(currentDoc + 1); 58 | 59 | return new IdScoredDocument(database, id); 60 | } 61 | 62 | @Override 63 | public void remove() { 64 | throw new UnsupportedOperationException("Removal is not supported"); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/MessageDigestOutputStreamWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util; 12 | 13 | import org.jetbrains.annotations.NotNull; 14 | 15 | import java.io.IOException; 16 | import java.io.OutputStream; 17 | import java.security.MessageDigest; 18 | 19 | /** 20 | * Wraps {@link OutputStream} and updates {@link MessageDigest} accordingly 21 | * 22 | * @author incubos 23 | */ 24 | public final class MessageDigestOutputStreamWrapper extends OutputStream { 25 | @NotNull 26 | private final OutputStream delegate; 27 | @NotNull 28 | private final MessageDigest digest; 29 | 30 | public MessageDigestOutputStreamWrapper( 31 | @NotNull 32 | final OutputStream delegate, 33 | @NotNull 34 | final MessageDigest digest) { 35 | this.delegate = delegate; 36 | this.digest = digest; 37 | } 38 | 39 | @NotNull 40 | public byte[] digest() { 41 | return digest.digest(); 42 | } 43 | 44 | @Override 45 | public void write(final int b) throws IOException { 46 | digest.update((byte) b); 47 | delegate.write(b); 48 | } 49 | 50 | @Override 51 | public void write( 52 | @NotNull 53 | final byte[] b, 54 | final int off, 55 | final int len) 56 | throws IOException { 57 | digest.update(b, off, len); 58 | delegate.write(b, off, len); 59 | } 60 | 61 | @Override 62 | public void flush() throws IOException { 63 | delegate.flush(); 64 | } 65 | 66 | @Override 67 | public void close() throws IOException { 68 | delegate.close(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/v1/mutable/segment/V1FullIndexTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.mutable.segment; 12 | 13 | import com.yandex.yoctodb.util.UnsignedByteArray; 14 | import org.junit.Test; 15 | 16 | import java.util.Collections; 17 | 18 | import static com.yandex.yoctodb.util.UnsignedByteArrays.from; 19 | 20 | /** 21 | * Unit tests for {@link V1FullIndex} 22 | * 23 | * @author incubos 24 | */ 25 | public class V1FullIndexTest { 26 | @Test 27 | public void addDocument() { 28 | new V1FullIndex("field", true) 29 | .addDocument( 30 | 0, 31 | Collections.singletonList(from(0))); 32 | } 33 | 34 | @Test(expected = IllegalArgumentException.class) 35 | public void negativeDocument() { 36 | new V1FullIndex("field", true) 37 | .addDocument( 38 | -1, 39 | Collections.singletonList(from(0))); 40 | } 41 | 42 | @Test(expected = IllegalArgumentException.class) 43 | public void inconsequentDocuments() { 44 | new V1FullIndex("field", true) 45 | .addDocument( 46 | 0, 47 | Collections.singletonList(from(0))) 48 | .addDocument( 49 | 2, 50 | Collections.singletonList(from(2))); 51 | } 52 | 53 | @Test(expected = IllegalArgumentException.class) 54 | public void emptyValues() { 55 | new V1FullIndex("field", true) 56 | .addDocument( 57 | 0, 58 | Collections.emptyList()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/immutable/SortableIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.immutable; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import net.jcip.annotations.Immutable; 15 | import org.jetbrains.annotations.NotNull; 16 | import com.yandex.yoctodb.util.immutable.IntToIntArray; 17 | import com.yandex.yoctodb.util.mutable.BitSet; 18 | 19 | import java.util.Iterator; 20 | 21 | /** 22 | * Index sorting documents 23 | * 24 | * @author incubos 25 | */ 26 | @Immutable 27 | public interface SortableIndex extends StoredIndex { 28 | /** 29 | * Get {@code document} sort value index 30 | * 31 | * @param document document 32 | * @return index of sort value 33 | */ 34 | int getSortValueIndex(int document); 35 | 36 | /** 37 | * Get sort value by index 38 | * 39 | * @param index sort value index 40 | * @return sort value 41 | */ 42 | @NotNull 43 | Buffer getSortValue(int index); 44 | 45 | /** 46 | * Get ascending iterator for {@link IntToIntArray} values mapping 47 | * sort value index to possibly multiple documents 48 | * 49 | * @param docs bit set for filtered document 50 | * @return ascending iterator 51 | */ 52 | @NotNull 53 | Iterator ascending( 54 | @NotNull 55 | BitSet docs); 56 | 57 | /** 58 | * Same as {@link #ascending(com.yandex.yoctodb.util.mutable.BitSet)} 59 | * 60 | * @param docs bit set for filtered document 61 | * @return descending iterator 62 | */ 63 | @NotNull 64 | Iterator descending( 65 | @NotNull 66 | BitSet docs); 67 | } 68 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/immutable/impl/IntIndexToIndexMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable.impl; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import net.jcip.annotations.Immutable; 15 | import org.jetbrains.annotations.NotNull; 16 | import com.yandex.yoctodb.util.immutable.IndexToIndexMap; 17 | 18 | /** 19 | * @author svyatoslav 20 | */ 21 | @Immutable 22 | public class IntIndexToIndexMap implements IndexToIndexMap { 23 | @NotNull 24 | private final Buffer elements; 25 | private final int elementCount; 26 | 27 | private IntIndexToIndexMap( 28 | final int elementCount, 29 | @NotNull 30 | final Buffer elements) { 31 | assert elementCount >= 0 : "Negative element count"; 32 | 33 | this.elementCount = elementCount; 34 | this.elements = elements; 35 | } 36 | 37 | @NotNull 38 | public static IndexToIndexMap from( 39 | @NotNull 40 | final Buffer buf) { 41 | final int elementsCount = buf.getInt(); 42 | final Buffer elements = buf.slice(); 43 | 44 | return new IntIndexToIndexMap( 45 | elementsCount, 46 | elements.slice()); 47 | } 48 | 49 | @Override 50 | public int get(final int key) { 51 | assert 0 <= key && key < elementCount; 52 | 53 | return elements.getInt(((long) key) << 2); 54 | } 55 | 56 | @Override 57 | public int size() { 58 | return elementCount; 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return "IntIndexToIndexMap{" + 64 | "elementCount=" + elementCount + 65 | '}'; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/Query.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query; 12 | 13 | import com.yandex.yoctodb.immutable.IndexedDatabase; 14 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 15 | import net.jcip.annotations.NotThreadSafe; 16 | import org.jetbrains.annotations.NotNull; 17 | import org.jetbrains.annotations.Nullable; 18 | import com.yandex.yoctodb.immutable.Database; 19 | import com.yandex.yoctodb.util.mutable.BitSet; 20 | 21 | import java.util.Iterator; 22 | 23 | /** 24 | * Query to be run against {@link Database} 25 | * 26 | * @author incubos 27 | */ 28 | @NotThreadSafe 29 | public interface Query { 30 | /** 31 | * Calculate filtering result not taking into account skip/limit 32 | * 33 | * @param database database 34 | * @param bitSetPool {@link BitSet} factory 35 | * @return read-only filtering result or {@code null} if empty 36 | */ 37 | @Nullable 38 | BitSet filteredUnlimited( 39 | @NotNull 40 | IndexedDatabase database, 41 | @NotNull 42 | ArrayBitSetPool bitSetPool); 43 | 44 | /** 45 | * Return sorted results not taking into account skip/limit 46 | * 47 | * @param docs docs to leave 48 | * @param database database 49 | * @param bitSetPool {@link BitSet} factory 50 | * @return sorted results 51 | */ 52 | @NotNull 53 | Iterator> sortedUnlimited( 54 | @NotNull 55 | BitSet docs, 56 | @NotNull 57 | IndexedDatabase database, 58 | @NotNull 59 | ArrayBitSetPool bitSetPool); 60 | 61 | int getSkip(); 62 | 63 | int getLimit(); 64 | 65 | boolean hasSorting(); 66 | } 67 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/v1/immutable/segment/SegmentRegistryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.immutable.segment; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import org.jetbrains.annotations.NotNull; 15 | import org.junit.Test; 16 | 17 | import java.util.NoSuchElementException; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | 21 | /** 22 | * Unit tests for {@link SegmentRegistry} 23 | * 24 | * @author incubos 25 | */ 26 | public class SegmentRegistryTest { 27 | private final Segment PROBE = 28 | new Segment() { 29 | }; 30 | 31 | private final SegmentReader DUMMY = 32 | new SegmentReader() { 33 | @NotNull 34 | @Override 35 | public Segment read( 36 | @NotNull 37 | final Buffer buffer) { 38 | return PROBE; 39 | } 40 | }; 41 | 42 | @Test(expected = NoSuchElementException.class) 43 | public void notExisting() { 44 | final int ID = -1; 45 | SegmentRegistry.read(ID, Buffer.from(new byte[]{})); 46 | } 47 | 48 | @Test 49 | public void register() { 50 | final int ID = -1; 51 | SegmentRegistry.register(ID, DUMMY); 52 | } 53 | 54 | @Test 55 | public void registerAndReturn() { 56 | final int ID = -2; 57 | SegmentRegistry.register(ID, DUMMY); 58 | assertEquals( 59 | PROBE, 60 | SegmentRegistry.read(ID, Buffer.from(new byte[]{}))); 61 | } 62 | 63 | @Test(expected = IllegalArgumentException.class) 64 | public void registerExisting() { 65 | final int ID = -3; 66 | SegmentRegistry.register(ID, DUMMY); 67 | SegmentRegistry.register(ID, DUMMY); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/immutable/impl/FixedLengthByteArrayIndexedListTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable.impl; 12 | 13 | import com.yandex.yoctodb.util.UnsignedByteArray; 14 | import com.yandex.yoctodb.util.buf.Buffer; 15 | import com.yandex.yoctodb.util.immutable.ByteArrayIndexedList; 16 | import org.junit.Test; 17 | 18 | import java.io.ByteArrayOutputStream; 19 | import java.io.IOException; 20 | import java.util.Collection; 21 | import java.util.LinkedList; 22 | 23 | import static com.yandex.yoctodb.util.UnsignedByteArrays.from; 24 | import static org.junit.Assert.assertEquals; 25 | import static org.junit.Assert.assertTrue; 26 | 27 | /** 28 | * Unit tests for {@link FixedLengthByteArrayIndexedList} 29 | * 30 | * @author incubos 31 | */ 32 | public class FixedLengthByteArrayIndexedListTest { 33 | private final int VALUES = 128; 34 | 35 | private ByteArrayIndexedList build() throws IOException { 36 | final Collection elements = 37 | new LinkedList<>(); 38 | for (long i = 0L; i < VALUES; i++) { 39 | elements.add(from(i)); 40 | } 41 | 42 | final com.yandex.yoctodb.util.mutable.ByteArrayIndexedList mutable = 43 | new com.yandex.yoctodb.util.mutable.impl.FixedLengthByteArrayIndexedList(elements); 44 | 45 | final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 46 | mutable.writeTo(baos); 47 | 48 | final Buffer buf = Buffer.from(baos.toByteArray()); 49 | 50 | final ByteArrayIndexedList result = 51 | FixedLengthByteArrayIndexedList.from(buf); 52 | 53 | assertEquals(VALUES, result.size()); 54 | 55 | return result; 56 | } 57 | 58 | @Test 59 | public void string() throws IOException { 60 | assertTrue(build().toString().contains(Integer.toString(VALUES))); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleDocumentMultiScore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import net.jcip.annotations.Immutable; 15 | import org.jetbrains.annotations.NotNull; 16 | import com.yandex.yoctodb.query.DocumentScore; 17 | import com.yandex.yoctodb.query.Order; 18 | import com.yandex.yoctodb.util.UnsignedByteArrays; 19 | 20 | import java.util.Arrays; 21 | 22 | /** 23 | * Document score based on sort fields {@link Buffer}s 24 | * 25 | * @author incubos 26 | */ 27 | @Immutable 28 | final class SimpleDocumentMultiScore 29 | implements DocumentScore { 30 | @NotNull 31 | private final Order.SortOrder[] orders; 32 | @NotNull 33 | private final Buffer[] values; 34 | 35 | SimpleDocumentMultiScore( 36 | @NotNull 37 | final Order.SortOrder[] orders, 38 | @NotNull 39 | final Buffer[] values) { 40 | assert values.length == orders.length; 41 | 42 | this.orders = orders; 43 | this.values = values; 44 | } 45 | 46 | @Override 47 | public int compareTo( 48 | @NotNull 49 | final SimpleDocumentMultiScore o) { 50 | assert Arrays.equals(orders, o.orders); 51 | assert values.length == o.values.length; 52 | 53 | for (int i = 0; i < values.length; i++) { 54 | final int result = 55 | UnsignedByteArrays.compare( 56 | values[i], 57 | o.values[i]); 58 | if (result != 0) { 59 | switch (orders[i]) { 60 | case ASC: 61 | return result; 62 | case DESC: 63 | return -result; 64 | } 65 | } 66 | } 67 | 68 | return 0; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/immutable/impl/VariableLengthByteArrayIndexedListTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable.impl; 12 | 13 | import com.yandex.yoctodb.util.UnsignedByteArray; 14 | import com.yandex.yoctodb.util.buf.Buffer; 15 | import com.yandex.yoctodb.util.immutable.ByteArrayIndexedList; 16 | import org.junit.Test; 17 | 18 | import java.io.ByteArrayOutputStream; 19 | import java.io.IOException; 20 | import java.util.Collection; 21 | import java.util.LinkedList; 22 | 23 | import static com.yandex.yoctodb.util.UnsignedByteArrays.from; 24 | import static org.junit.Assert.assertEquals; 25 | import static org.junit.Assert.assertTrue; 26 | 27 | /** 28 | * Unit tests for {@link VariableLengthByteArrayIndexedList} 29 | * 30 | * @author incubos 31 | */ 32 | public class VariableLengthByteArrayIndexedListTest { 33 | private final int VALUES = 128; 34 | 35 | private ByteArrayIndexedList build() throws IOException { 36 | final Collection elements = new LinkedList<>(); 37 | for (int i = 0; i < VALUES; i++) { 38 | if (i % 2 == 0) 39 | elements.add(from(i)); 40 | else 41 | elements.add(from((long) i)); 42 | } 43 | final com.yandex.yoctodb.util.mutable.ByteArrayIndexedList mutable = 44 | new com.yandex.yoctodb.util.mutable.impl.VariableLengthByteArrayIndexedList(elements); 45 | 46 | final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 47 | mutable.writeTo(baos); 48 | 49 | final Buffer buf = Buffer.from(baos.toByteArray()); 50 | 51 | final ByteArrayIndexedList result = 52 | VariableLengthByteArrayIndexedList.from(buf); 53 | 54 | assertEquals(VALUES, result.size()); 55 | 56 | return result; 57 | } 58 | 59 | @Test 60 | public void string() throws IOException { 61 | assertTrue(build().toString().contains(Integer.toString(VALUES))); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/stored/V1StoredIndexTest.java: -------------------------------------------------------------------------------- 1 | package com.yandex.yoctodb.util.mutable.stored; 2 | 3 | import com.yandex.yoctodb.util.OutputStreamWritable; 4 | import com.yandex.yoctodb.util.UnsignedByteArray; 5 | import com.yandex.yoctodb.util.UnsignedByteArrays; 6 | import com.yandex.yoctodb.util.mutable.impl.VariableLengthByteArrayIndexedList; 7 | import com.yandex.yoctodb.v1.mutable.segment.V1StoredIndex; 8 | import org.junit.Test; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collections; 12 | import java.util.List; 13 | import java.util.Map; 14 | import java.util.TreeMap; 15 | 16 | /** 17 | * {@link com.yandex.yoctodb.util.immutable.ByteArrayIndexedList} with fixed size 18 | * elements 19 | * 20 | * @author irenkamalova 21 | */ 22 | public class V1StoredIndexTest { 23 | 24 | @Test 25 | public void buildV1StoredIndex() { 26 | final String fieldName = "testFiledName"; 27 | V1StoredIndex index = new V1StoredIndex(fieldName); 28 | final Map data = initData(); 29 | List elements = new ArrayList<>(data.size()); 30 | for(Map.Entry entry : data.entrySet()) { 31 | index.addDocument(entry.getKey(), Collections.singletonList(entry.getValue())); 32 | elements.add(entry.getValue()); 33 | } 34 | VariableLengthByteArrayIndexedList indexedList = 35 | new VariableLengthByteArrayIndexedList(elements); 36 | 37 | index.setDatabaseDocumentsCount(data.size()); 38 | OutputStreamWritable outputStreamWritable = index.buildWritable(); 39 | 40 | assert (outputStreamWritable.getSizeInBytes() == getSizeInBytes(fieldName, indexedList)); 41 | } 42 | 43 | private Map initData() { 44 | Map data = new TreeMap<>(); 45 | data.put(0, UnsignedByteArrays.from("NEW")); 46 | data.put(1, UnsignedByteArrays.from("USED")); 47 | return data; 48 | } 49 | 50 | private long getSizeInBytes(String fieldName, VariableLengthByteArrayIndexedList valueIndex) { 51 | return 4L + // Field name 52 | (long) fieldName.length() + 53 | 8 + // Values 54 | valueIndex.getSizeInBytes(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleMultiEqualityCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.immutable.FilterableIndex; 14 | import com.yandex.yoctodb.immutable.FilterableIndexProvider; 15 | import com.yandex.yoctodb.util.UnsignedByteArray; 16 | import com.yandex.yoctodb.util.buf.Buffer; 17 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 18 | import com.yandex.yoctodb.util.mutable.BitSet; 19 | import net.jcip.annotations.Immutable; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | import java.util.Arrays; 23 | 24 | /** 25 | * {@code in} condition 26 | * 27 | * @author incubos 28 | */ 29 | @Immutable 30 | public final class SimpleMultiEqualityCondition 31 | extends AbstractTermCondition { 32 | @NotNull 33 | private final Buffer[] values; 34 | 35 | public SimpleMultiEqualityCondition( 36 | @NotNull 37 | final String fieldName, 38 | @NotNull 39 | final UnsignedByteArray... values) { 40 | super(fieldName); 41 | 42 | if (values.length == 0) 43 | throw new IllegalArgumentException("Empty value array"); 44 | 45 | final UnsignedByteArray[] sorted = values.clone(); 46 | Arrays.sort(sorted); 47 | 48 | this.values = new Buffer[sorted.length]; 49 | for (int i = 0; i < sorted.length; i++) { 50 | if (sorted[i].isEmpty()) 51 | throw new IllegalArgumentException("Empty value"); 52 | 53 | this.values[i] = sorted[i].toByteBuffer(); 54 | } 55 | } 56 | 57 | @Override 58 | public boolean set( 59 | @NotNull 60 | final FilterableIndexProvider indexProvider, 61 | @NotNull 62 | final BitSet to, 63 | @NotNull 64 | final ArrayBitSetPool bitSetPool) { 65 | final FilterableIndex index = indexProvider.getFilter(getFieldName()); 66 | return index != null && index.in(to, values); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/v1/immutable/FilterResultIterator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.immutable; 12 | 13 | import com.yandex.yoctodb.immutable.IndexedDatabase; 14 | import com.yandex.yoctodb.query.Query; 15 | import com.yandex.yoctodb.query.ScoredDocument; 16 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 17 | import com.yandex.yoctodb.util.mutable.BitSet; 18 | import org.jetbrains.annotations.NotNull; 19 | 20 | import java.util.Collections; 21 | import java.util.Iterator; 22 | 23 | /** 24 | * Applies query filtering to each of the databases 25 | * 26 | * @author incubos 27 | */ 28 | class FilterResultIterator 29 | implements Iterator>> { 30 | @NotNull 31 | private final Query query; 32 | @NotNull 33 | private final Iterator databases; 34 | @NotNull 35 | private final ArrayBitSetPool bitSetPool; 36 | 37 | FilterResultIterator( 38 | @NotNull 39 | final Query query, 40 | @NotNull 41 | final Iterator databases, 42 | @NotNull 43 | final ArrayBitSetPool bitSetPool) { 44 | this.query = query; 45 | this.databases = databases; 46 | this.bitSetPool = bitSetPool; 47 | } 48 | 49 | @Override 50 | public boolean hasNext() { 51 | return databases.hasNext(); 52 | } 53 | 54 | @NotNull 55 | @Override 56 | public Iterator> next() { 57 | final IndexedDatabase db = databases.next(); 58 | final BitSet docs = query.filteredUnlimited(db, bitSetPool); 59 | if (docs == null) { 60 | return Collections.emptyIterator(); 61 | } else { 62 | return query.sortedUnlimited(docs, db, bitSetPool); 63 | } 64 | } 65 | 66 | @Override 67 | public void remove() { 68 | throw new UnsupportedOperationException( 69 | "Removal is not supported"); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/stored/ManyUniqueValuesTest.java: -------------------------------------------------------------------------------- 1 | package com.yandex.yoctodb.util.mutable.stored; 2 | 3 | import com.yandex.yoctodb.DatabaseFormat; 4 | import com.yandex.yoctodb.immutable.Database; 5 | import com.yandex.yoctodb.mutable.DatabaseBuilder; 6 | import com.yandex.yoctodb.mutable.DocumentBuilder; 7 | import com.yandex.yoctodb.util.UnsignedByteArrays; 8 | import com.yandex.yoctodb.util.buf.Buffer; 9 | import org.junit.Test; 10 | 11 | import java.io.ByteArrayOutputStream; 12 | import java.io.IOException; 13 | 14 | import static com.yandex.yoctodb.mutable.DocumentBuilder.IndexOption.STORED; 15 | import static org.junit.Assert.assertEquals; 16 | 17 | /** 18 | * {@link com.yandex.yoctodb.util.immutable.ByteArrayIndexedList} with fixed size 19 | * elements 20 | * 21 | * @author irenkamalova 22 | */ 23 | public class ManyUniqueValuesTest { 24 | private String fieldName = "test"; 25 | @Test 26 | public void values100() throws IOException { 27 | testDB(100); 28 | } 29 | 30 | @Test 31 | public void values300() throws IOException { 32 | testDB(300); 33 | } 34 | 35 | @Test 36 | public void values70000() throws IOException { 37 | testDB(70000); 38 | } 39 | 40 | private void testDB(final int size) throws IOException { 41 | final DatabaseBuilder dbBuilder = 42 | DatabaseFormat.getCurrent().newDatabaseBuilder(); 43 | for (int i = 0; i < size; i++) { 44 | dbBuilder.merge(buildTestDocument(Integer.toString((i)))); 45 | } 46 | final ByteArrayOutputStream os = new ByteArrayOutputStream(); 47 | dbBuilder.buildWritable().writeTo(os); 48 | 49 | final Database db = 50 | DatabaseFormat.getCurrent() 51 | .getDatabaseReader() 52 | .from(Buffer.from(os.toByteArray())); 53 | 54 | for (int i = 0; i < 100; i++) { 55 | assertEquals(Integer.toString((i)), 56 | UnsignedByteArrays.toString( 57 | UnsignedByteArrays.from(db.getFieldValue(i, fieldName)))); 58 | } 59 | } 60 | 61 | private DocumentBuilder buildTestDocument(String value) { 62 | return DatabaseFormat.getCurrent().newDocumentBuilder() 63 | .withField(fieldName, value, STORED); 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/v1/immutable/segment/SegmentRegistry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.v1.immutable.segment; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import net.jcip.annotations.ThreadSafe; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | import java.util.NoSuchElementException; 18 | import java.util.concurrent.ConcurrentHashMap; 19 | import java.util.concurrent.ConcurrentMap; 20 | 21 | /** 22 | * Provides means to register segment readers and build segments 23 | * 24 | * @author incubos 25 | */ 26 | @ThreadSafe 27 | public final class SegmentRegistry { 28 | private SegmentRegistry() { 29 | // Can't construct 30 | } 31 | 32 | // For test coverage 33 | static { 34 | new SegmentRegistry(); 35 | } 36 | 37 | // Segment readers 38 | private final static ConcurrentMap readers = 39 | new ConcurrentHashMap<>(); 40 | 41 | public static void register( 42 | final int type, 43 | @NotNull 44 | final SegmentReader reader) { 45 | final SegmentReader previous = readers.putIfAbsent(type, reader); 46 | if (previous != null) { 47 | throw new IllegalArgumentException( 48 | "Duplicate segment readers with type " + type); 49 | } 50 | } 51 | 52 | @NotNull 53 | public static Segment read( 54 | final int type, 55 | @NotNull 56 | final Buffer buffer) { 57 | final SegmentReader reader = readers.get(type); 58 | if (reader == null) { 59 | throw new NoSuchElementException( 60 | "No segment reader with type " + type); 61 | } 62 | 63 | return reader.read(buffer); 64 | } 65 | 66 | static { 67 | // Register readers for default segments 68 | V1FilterableIndex.registerReader(); 69 | V1SortableIndex.registerReader(); 70 | V1FullIndex.registerReader(); 71 | V1StoredIndex.registerReader(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/immutable/impl/VariableLengthByteArraySortedSetTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable.impl; 12 | 13 | import com.yandex.yoctodb.util.UnsignedByteArray; 14 | import com.yandex.yoctodb.util.buf.Buffer; 15 | import com.yandex.yoctodb.util.immutable.ByteArraySortedSet; 16 | import org.junit.Test; 17 | 18 | import java.io.ByteArrayOutputStream; 19 | import java.io.IOException; 20 | import java.util.SortedSet; 21 | import java.util.TreeSet; 22 | 23 | import static com.yandex.yoctodb.util.UnsignedByteArrays.from; 24 | import static org.junit.Assert.assertEquals; 25 | import static org.junit.Assert.assertTrue; 26 | 27 | /** 28 | * Unit tests for {@link VariableLengthByteArraySortedSet} 29 | * 30 | * @author incubos 31 | */ 32 | public class VariableLengthByteArraySortedSetTest { 33 | private final int VALUES = 128; 34 | 35 | private ByteArraySortedSet build() throws IOException { 36 | final SortedSet elements = 37 | new TreeSet<>(); 38 | for (int i = 0; i < VALUES; i++) { 39 | if (i % 2 == 0) 40 | elements.add(from(i / 2)); 41 | else 42 | elements.add(from(i / 2L)); 43 | } 44 | final com.yandex.yoctodb.util.mutable.ByteArraySortedSet mutable = 45 | new com.yandex.yoctodb.util.mutable.impl.VariableLengthByteArraySortedSet( 46 | elements); 47 | 48 | final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 49 | mutable.writeTo(baos); 50 | 51 | final Buffer buf = Buffer.from(baos.toByteArray()); 52 | 53 | final ByteArraySortedSet result = 54 | VariableLengthByteArraySortedSet.from(buf); 55 | 56 | assertEquals(VALUES, result.size()); 57 | 58 | return result; 59 | } 60 | 61 | @Test 62 | public void string() throws IOException { 63 | final String text = build().toString(); 64 | assertTrue(text.contains(Integer.toString(VALUES))); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/immutable/impl/FixedLengthByteArraySortedSetTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable.impl; 12 | 13 | import com.google.common.primitives.Longs; 14 | import com.yandex.yoctodb.util.UnsignedByteArray; 15 | import com.yandex.yoctodb.util.buf.Buffer; 16 | import com.yandex.yoctodb.util.immutable.ByteArraySortedSet; 17 | import org.junit.Test; 18 | 19 | import java.io.ByteArrayOutputStream; 20 | import java.io.IOException; 21 | import java.util.SortedSet; 22 | import java.util.TreeSet; 23 | 24 | import static com.yandex.yoctodb.util.UnsignedByteArrays.from; 25 | import static org.junit.Assert.assertEquals; 26 | import static org.junit.Assert.assertTrue; 27 | 28 | /** 29 | * Unit tests for {@link FixedLengthByteArraySortedSet} 30 | * 31 | * @author incubos 32 | */ 33 | public class FixedLengthByteArraySortedSetTest { 34 | private final int VALUES = 128; 35 | 36 | private ByteArraySortedSet build() throws IOException { 37 | final SortedSet elements = 38 | new TreeSet<>(); 39 | for (long i = 0L; i < VALUES; i++) { 40 | elements.add(from(i / 2)); 41 | } 42 | final com.yandex.yoctodb.util.mutable.ByteArraySortedSet mutable = 43 | new com.yandex.yoctodb.util.mutable.impl.FixedLengthByteArraySortedSet( 44 | elements); 45 | 46 | final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 47 | mutable.writeTo(baos); 48 | 49 | final Buffer buf = Buffer.from(baos.toByteArray()); 50 | 51 | final ByteArraySortedSet result = 52 | FixedLengthByteArraySortedSet.from(buf); 53 | 54 | assertEquals(VALUES / 2, result.size()); 55 | 56 | return result; 57 | } 58 | 59 | @Test 60 | public void string() throws IOException { 61 | final String text = build().toString(); 62 | assertTrue(text.contains(Integer.toString(VALUES / 2))); 63 | assertTrue(text.contains(Integer.toString(Longs.BYTES))); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/immutable/ByteArraySortedSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import net.jcip.annotations.Immutable; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | /** 18 | * {@link com.yandex.yoctodb.util.UnsignedByteArray} immutable sorted set with basic operations 19 | * 20 | * @author incubos 21 | */ 22 | @Immutable 23 | public interface ByteArraySortedSet { 24 | int size(); 25 | 26 | @NotNull 27 | Buffer get(int i); 28 | 29 | long getLongUnsafe(int i); 30 | 31 | int getIntUnsafe(int i); 32 | 33 | short getShortUnsafe(int i); 34 | 35 | char getCharUnsafe(int i); 36 | 37 | byte getByteUnsafe(int i); 38 | 39 | /** 40 | * Get index of the element 41 | * 42 | * @param e the element to lookup 43 | * 44 | * @return index of the element or -1 45 | */ 46 | int indexOf( 47 | @NotNull 48 | Buffer e); 49 | 50 | /** 51 | * Index of element greater than {@code e} taking into account {@code 52 | * orEquals} parameter {@code upToIndexInclusive} 53 | * 54 | * @param e element to compare to 55 | * @param orEquals inclusive flag 56 | * @param upToIndexInclusive right bound (inclusive) 57 | * 58 | * @return index of the first element or -1 59 | */ 60 | int indexOfGreaterThan( 61 | @NotNull 62 | Buffer e, 63 | boolean orEquals, 64 | int upToIndexInclusive); 65 | 66 | /** 67 | * Index of element less than {@code e} taking into account {@code orEquals} 68 | * parameter {@code fromIndexInclusive} 69 | * 70 | * @param e element to compare to 71 | * @param orEquals inclusive flag 72 | * @param fromIndexInclusive left bound (inclusive) 73 | * 74 | * @return index of the first element or -1 75 | */ 76 | int indexOfLessThan( 77 | @NotNull 78 | Buffer e, 79 | boolean orEquals, 80 | int fromIndexInclusive); 81 | } 82 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/FixedLengthByteArrayIndexedList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.google.common.primitives.Ints; 14 | import com.yandex.yoctodb.util.OutputStreamWritable; 15 | import com.yandex.yoctodb.util.UnsignedByteArray; 16 | import com.yandex.yoctodb.util.mutable.ByteArrayIndexedList; 17 | import net.jcip.annotations.NotThreadSafe; 18 | import org.jetbrains.annotations.NotNull; 19 | 20 | import java.io.IOException; 21 | import java.io.OutputStream; 22 | import java.util.Collection; 23 | 24 | /** 25 | * {@link ByteArrayIndexedList} with fixed size elements 26 | * 27 | * @author incubos 28 | */ 29 | @NotThreadSafe 30 | public final class FixedLengthByteArrayIndexedList 31 | implements ByteArrayIndexedList { 32 | @NotNull 33 | private final Collection elements; 34 | 35 | private int elementSize = -1; 36 | 37 | public FixedLengthByteArrayIndexedList( 38 | @NotNull 39 | final Collection elements) { 40 | assert !elements.isEmpty(); 41 | 42 | this.elements = elements; 43 | this.elementSize = elements.iterator().next().length(); 44 | } 45 | 46 | @Override 47 | public long getSizeInBytes() { 48 | return 4L + // Element size 49 | 4L + // Element count 50 | ((long) elementSize) * elements.size(); 51 | } 52 | 53 | @Override 54 | public void writeTo( 55 | @NotNull 56 | final OutputStream os) throws IOException { 57 | // Element size 58 | os.write(Ints.toByteArray(elementSize)); 59 | 60 | // Element count 61 | os.write(Ints.toByteArray(elements.size())); 62 | 63 | // Elements 64 | for (OutputStreamWritable e : elements) { 65 | assert e.getSizeInBytes() == elementSize : "Wrong size"; 66 | e.writeTo(os); 67 | } 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "FixedLengthByteArrayIndexedList{" + 73 | "elementsCount=" + elements.size() + 74 | ", elementSize=" + elementSize + 75 | '}'; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/IntIndexToIndexMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.google.common.primitives.Ints; 14 | import com.yandex.yoctodb.util.mutable.IndexToIndexMap; 15 | import net.jcip.annotations.NotThreadSafe; 16 | import org.jetbrains.annotations.NotNull; 17 | 18 | import java.io.IOException; 19 | import java.io.OutputStream; 20 | import java.util.Map; 21 | import java.util.TreeMap; 22 | 23 | /** 24 | * {@link IndexToIndexMap} implementation based on {@link Integer}s 25 | * 26 | * @author incubos 27 | */ 28 | @NotThreadSafe 29 | public final class IntIndexToIndexMap implements IndexToIndexMap { 30 | private final Map elements = 31 | new TreeMap<>(); 32 | 33 | @Override 34 | public void put(final int key, final int value) { 35 | if (key < 0) 36 | throw new IllegalArgumentException("Negative key"); 37 | if (value < 0) 38 | throw new IllegalArgumentException("Negative value"); 39 | 40 | final Integer previous = elements.put(key, value); 41 | 42 | if (previous != null) 43 | throw new IllegalArgumentException( 44 | "Key <" + key + "> was already bound to <" + previous + 45 | ">"); 46 | } 47 | 48 | @Override 49 | public long getSizeInBytes() { 50 | return 4L + 4L * elements.size(); 51 | } 52 | 53 | @Override 54 | public void writeTo( 55 | @NotNull 56 | final OutputStream os) throws IOException { 57 | // Elements count 58 | os.write(Ints.toByteArray(elements.size())); 59 | 60 | // Values 61 | int index = 0; 62 | for (Map.Entry entry : elements.entrySet()) { 63 | if (entry.getKey() != index) { 64 | throw new IllegalStateException("Indexes are not continuous"); 65 | } 66 | 67 | os.write(Ints.toByteArray(entry.getValue())); 68 | 69 | index++; 70 | } 71 | } 72 | 73 | @Override 74 | public String toString() { 75 | return "IntIndexToIndexMap{" + 76 | "elements=" + elements.size() + 77 | '}'; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/FixedLengthByteArraySortedSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.google.common.primitives.Ints; 14 | import com.yandex.yoctodb.util.UnsignedByteArray; 15 | import com.yandex.yoctodb.util.mutable.ByteArraySortedSet; 16 | import net.jcip.annotations.NotThreadSafe; 17 | import org.jetbrains.annotations.NotNull; 18 | 19 | import java.io.IOException; 20 | import java.io.OutputStream; 21 | import java.util.SortedSet; 22 | 23 | /** 24 | * {@link ByteArraySortedSet} with fixed size elements 25 | * 26 | * @author incubos 27 | */ 28 | @NotThreadSafe 29 | public final class FixedLengthByteArraySortedSet 30 | extends AbstractByteArraySortedSet { 31 | public FixedLengthByteArraySortedSet( 32 | final SortedSet elements) { 33 | super(elements); 34 | 35 | if (elements.isEmpty()) 36 | throw new IllegalArgumentException("Empty set"); 37 | } 38 | 39 | @Override 40 | public long getSizeInBytes() { 41 | return 4L + // Element size 42 | 4L + // Element count 43 | elements.first().getSizeInBytes() * elements.size(); 44 | } 45 | 46 | @Override 47 | public void writeTo( 48 | @NotNull 49 | final OutputStream os) throws IOException { 50 | assert elements.first().getSizeInBytes() <= Integer.MAX_VALUE; 51 | 52 | // Element size 53 | os.write(Ints.toByteArray((int) elements.first().getSizeInBytes())); 54 | 55 | // Element count 56 | os.write(Ints.toByteArray(elements.size())); 57 | 58 | // Elements 59 | long elementSize = -1; 60 | for (UnsignedByteArray e : elements) { 61 | if (elementSize == -1) 62 | elementSize = e.getSizeInBytes(); 63 | 64 | assert elementSize == e.getSizeInBytes() : "Variable size"; 65 | 66 | e.writeTo(os); 67 | } 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "FixedLengthByteArraySortedSet{" + 73 | "elementsCount=" + elements.size() + 74 | ", elementSize=" + elements.first().getSizeInBytes() + 75 | '}'; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/AbstractCachedArrayBitSetPool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.yandex.yoctodb.util.mutable.ArrayBitSet; 14 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 15 | import net.jcip.annotations.ThreadSafe; 16 | import org.jetbrains.annotations.NotNull; 17 | 18 | import java.util.Deque; 19 | 20 | /** 21 | * Abstract LIFO {@link Deque}-based cache of {@link ArrayBitSet}s 22 | * 23 | * @author incubos 24 | */ 25 | @ThreadSafe 26 | abstract class AbstractCachedArrayBitSetPool implements ArrayBitSetPool { 27 | static final int DEFAULT_SIZE_HINT = 1; 28 | static final float DEFAULT_LOAD_FACTOR = 0.75f; 29 | 30 | private final int minSize; 31 | private final float loadFactor; 32 | 33 | private static int sizeToAllocate(final int bits, final float loadFactor) { 34 | return (int) (LongArrayBitSet.arraySize(bits) / loadFactor); 35 | } 36 | 37 | AbstractCachedArrayBitSetPool( 38 | final int sizeHint, 39 | final float loadFactor) { 40 | assert sizeHint > 0; 41 | assert 0.0f < loadFactor && loadFactor <= 1.0f; 42 | 43 | this.minSize = sizeToAllocate(sizeHint, loadFactor); 44 | this.loadFactor = loadFactor; 45 | } 46 | 47 | @NotNull 48 | private long[] allocate(final int size) { 49 | final int actualSize = 50 | Math.max(sizeToAllocate(size, loadFactor), minSize); 51 | return new long[actualSize]; 52 | } 53 | 54 | protected abstract Deque getCache(); 55 | 56 | @NotNull 57 | @Override 58 | public final ArrayBitSet borrowSet(final int size) { 59 | assert size > 0; 60 | 61 | final long[] cached = getCache().poll(); 62 | if (cached == null) 63 | return LongArrayBitSet.zero(size, allocate(size)); 64 | else if (cached.length < LongArrayBitSet.arraySize(size)) 65 | return LongArrayBitSet.zero(size, allocate(size)); 66 | else 67 | return LongArrayBitSet.zero(size, cached); 68 | } 69 | 70 | @Override 71 | public final void returnSet( 72 | @NotNull 73 | final ArrayBitSet set) { 74 | getCache().addFirst(set.toArray()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /benchmark/src/main/java/com/yandex/yoctodb/util/immutable/ByteArraySortedSetBenchmarks.java: -------------------------------------------------------------------------------- 1 | package com.yandex.yoctodb.util.immutable; 2 | 3 | import com.yandex.yoctodb.util.buf.Buffer; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.openjdk.jmh.annotations.Benchmark; 6 | import org.openjdk.jmh.infra.Blackhole; 7 | 8 | import java.util.Collection; 9 | 10 | import static com.yandex.yoctodb.util.immutable.ByteArraySortedSetBenchmarkData.*; 11 | 12 | /** 13 | * Benchmarks for {@link ByteArraySortedSet} implementations 14 | * 15 | * @author incubos 16 | */ 17 | public class ByteArraySortedSetBenchmarks { 18 | private long measure(@NotNull final ByteArraySortedSet set, @NotNull final Collection queries) { 19 | long res = 0; 20 | for (Buffer b : queries) 21 | res += set.indexOf(b); 22 | return res; 23 | } 24 | 25 | @Benchmark 26 | public void random_8bytes_64K_fixed(final Blackhole bh) { 27 | bh.consume(measure(RANDOM_8B_64K.fixedIndex(), RANDOM_8B_64K.queries())); 28 | } 29 | 30 | @Benchmark 31 | public void random_8bytes_64K_variable(final Blackhole bh) { 32 | bh.consume(measure(RANDOM_8B_64K.variableIndex(), RANDOM_8B_64K.queries())); 33 | } 34 | 35 | @Benchmark 36 | public void random_8bytes_64K_trie(final Blackhole bh) { 37 | bh.consume(measure(RANDOM_8B_64K.trieIndex(), RANDOM_8B_64K.queries())); 38 | } 39 | 40 | @Benchmark 41 | public void random_prefixed_string_100K_fixed(final Blackhole bh) { 42 | bh.consume(measure(RANDOM_STRING_WITH_PREFIX_25B_100K.fixedIndex(), RANDOM_STRING_WITH_PREFIX_25B_100K.queries())); 43 | } 44 | 45 | @Benchmark 46 | public void random_prefixed_string_100K_variable(final Blackhole bh) { 47 | bh.consume(measure(RANDOM_STRING_WITH_PREFIX_25B_100K.variableIndex(), RANDOM_STRING_WITH_PREFIX_25B_100K.queries())); 48 | } 49 | 50 | @Benchmark 51 | public void random_prefixed_string_100K_trie(final Blackhole bh) { 52 | bh.consume(measure(RANDOM_STRING_WITH_PREFIX_25B_100K.trieIndex(), RANDOM_STRING_WITH_PREFIX_25B_100K.queries())); 53 | } 54 | 55 | @Benchmark 56 | public void price_fixed(final Blackhole bh) { 57 | bh.consume(measure(PRICES_4B.fixedIndex(), PRICES_4B.queries())); 58 | } 59 | 60 | @Benchmark 61 | public void price_variable(final Blackhole bh) { 62 | bh.consume(measure(PRICES_4B.variableIndex(), PRICES_4B.queries())); 63 | } 64 | 65 | @Benchmark 66 | public void price_trie(final Blackhole bh) { 67 | bh.consume(measure(PRICES_4B.trieIndex(), PRICES_4B.queries())); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/query/simple/SimpleRangeCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.immutable.FilterableIndex; 14 | import com.yandex.yoctodb.immutable.FilterableIndexProvider; 15 | import com.yandex.yoctodb.util.UnsignedByteArray; 16 | import com.yandex.yoctodb.util.buf.Buffer; 17 | import com.yandex.yoctodb.util.mutable.ArrayBitSetPool; 18 | import com.yandex.yoctodb.util.mutable.BitSet; 19 | import net.jcip.annotations.Immutable; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | /** 23 | * Range condition 24 | * 25 | * @author incubos 26 | */ 27 | @Immutable 28 | public final class SimpleRangeCondition extends AbstractTermCondition { 29 | @NotNull 30 | private final Buffer from; 31 | private final boolean fromInclusive; 32 | @NotNull 33 | private final Buffer to; 34 | private final boolean toInclusive; 35 | 36 | public SimpleRangeCondition( 37 | @NotNull 38 | final String fieldName, 39 | @NotNull 40 | final UnsignedByteArray from, 41 | final boolean fromInclusive, 42 | @NotNull 43 | final UnsignedByteArray to, 44 | final boolean toInclusive) { 45 | super(fieldName); 46 | 47 | if (from.length() == 0) 48 | throw new IllegalArgumentException("Empty from value"); 49 | if (to.length() == 0) 50 | throw new IllegalArgumentException("Empty to value"); 51 | if (!(from.compareTo(to) < 0 || 52 | from.equals(to) && fromInclusive && toInclusive)) 53 | throw new IllegalArgumentException("Empty range"); 54 | 55 | this.from = from.toByteBuffer(); 56 | this.fromInclusive = fromInclusive; 57 | this.to = to.toByteBuffer(); 58 | this.toInclusive = toInclusive; 59 | } 60 | 61 | @Override 62 | public boolean set( 63 | @NotNull 64 | final FilterableIndexProvider indexProvider, 65 | @NotNull 66 | final BitSet dest, 67 | @NotNull 68 | final ArrayBitSetPool bitSetPool) { 69 | final FilterableIndex index = indexProvider.getFilter(getFieldName()); 70 | return index != null && 71 | index.between(dest, from, fromInclusive, to, toInclusive); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | yoctodb-core 5 | 0.1-SNAPSHOT 6 | jar 7 | 8 | YoctoDB core 9 | Embedded immutable database core module 10 | https://github.com/yandex/yoctodb 11 | 12 | 13 | Mozilla Public License Version 2.0 14 | http://mozilla.org/MPL/2.0/ 15 | repo 16 | 17 | 18 | 19 | https://github.com/yandex/yoctodb 20 | scm:git:git@github.com:yandex/yoctodb.git 21 | scm:git:git@github.com:yandex/yoctodb.git 22 | 23 | 24 | 25 | incubos 26 | Vadim Tsesko 27 | incubos@yandex.com 28 | 29 | 30 | svyatoslav 31 | Svyatoslav Demidov 32 | demidov.svyatoslav@yandex.com 33 | 34 | 35 | 36 | 37 | ../pom.xml 38 | com.yandex.yoctodb 39 | yoctodb-parent 40 | 0.1-SNAPSHOT 41 | 42 | 43 | 44 | 45 | com.google.guava 46 | guava 47 | 48 | 49 | 50 | 51 | org.jetbrains 52 | annotations-java5 53 | 54 | 55 | net.jcip 56 | jcip-annotations 57 | 58 | 59 | 60 | 61 | junit 62 | junit 63 | test 64 | 65 | 66 | org.mockito 67 | mockito-core 68 | test 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/BitSetIndexToIndexMultiMapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.google.common.collect.TreeMultimap; 14 | import com.yandex.yoctodb.util.mutable.IndexToIndexMultiMap; 15 | import org.junit.Test; 16 | 17 | import java.io.ByteArrayOutputStream; 18 | import java.io.IOException; 19 | import java.util.Collection; 20 | import java.util.Collections; 21 | 22 | import static java.util.Collections.singletonList; 23 | import static org.junit.Assert.assertTrue; 24 | 25 | /** 26 | * Unit tests for {@link BitSetIndexToIndexMultiMap} 27 | * 28 | * @author incubos 29 | */ 30 | public class BitSetIndexToIndexMultiMapTest { 31 | @Test(expected = IllegalArgumentException.class) 32 | public void negativeDocuments() { 33 | new BitSetIndexToIndexMultiMap( 34 | Collections.>emptyList(), 35 | -1); 36 | } 37 | 38 | @Test(expected = AssertionError.class) 39 | public void wrongDocument() throws IOException { 40 | new BitSetIndexToIndexMultiMap( 41 | singletonList(singletonList(1)), 42 | 1) 43 | .writeTo(new ByteArrayOutputStream()); 44 | } 45 | 46 | @Test(expected = IllegalArgumentException.class) 47 | public void negativeValue() throws IOException { 48 | new BitSetIndexToIndexMultiMap( 49 | singletonList(singletonList(1)), 50 | -1) 51 | .writeTo(new ByteArrayOutputStream()); 52 | } 53 | 54 | @Test 55 | public void string() { 56 | final TreeMultimap elements = TreeMultimap.create(); 57 | final int documents = 10; 58 | for (int i = 0; i < documents; i++) 59 | elements.put(i / 2, i); 60 | final IndexToIndexMultiMap set = 61 | new BitSetIndexToIndexMultiMap( 62 | elements.asMap().values(), 63 | documents); 64 | final String text = set.toString(); 65 | assertTrue(text.contains(Integer.toString(documents / 2))); 66 | assertTrue(text.contains(Integer.toString(documents))); 67 | set.getSizeInBytes(); 68 | assertTrue(text.contains(Integer.toString(documents / 2))); 69 | assertTrue(text.contains(Integer.toString(documents))); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/VariableLengthByteArraySortedSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.google.common.primitives.Ints; 14 | import com.google.common.primitives.Longs; 15 | import com.yandex.yoctodb.util.OutputStreamWritable; 16 | import com.yandex.yoctodb.util.UnsignedByteArray; 17 | import com.yandex.yoctodb.util.mutable.ByteArraySortedSet; 18 | import net.jcip.annotations.NotThreadSafe; 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | import java.io.IOException; 22 | import java.io.OutputStream; 23 | import java.util.SortedSet; 24 | 25 | /** 26 | * {@link ByteArraySortedSet} with variable sized elements 27 | * 28 | * @author incubos 29 | */ 30 | @NotThreadSafe 31 | public final class VariableLengthByteArraySortedSet 32 | extends AbstractByteArraySortedSet { 33 | private final long sizeInBytes; 34 | 35 | public VariableLengthByteArraySortedSet( 36 | @NotNull 37 | final SortedSet elements) { 38 | super(elements); 39 | 40 | long elementSize = 0; 41 | for (OutputStreamWritable e : elements) 42 | elementSize += e.getSizeInBytes(); 43 | 44 | this.sizeInBytes = 45 | 4L + // Element count 46 | 8L * (elements.size() + 1) + // Element offsets 47 | elementSize; // Element array size 48 | } 49 | 50 | @Override 51 | public long getSizeInBytes() { 52 | return sizeInBytes; 53 | } 54 | 55 | @Override 56 | public void writeTo( 57 | @NotNull 58 | final OutputStream os) throws IOException { 59 | // Element count 60 | os.write(Ints.toByteArray(elements.size())); 61 | 62 | // Element offsets 63 | long elementOffset = 0; 64 | for (OutputStreamWritable e : elements) { 65 | os.write(Longs.toByteArray(elementOffset)); 66 | elementOffset += e.getSizeInBytes(); 67 | } 68 | os.write(Longs.toByteArray(elementOffset)); 69 | 70 | // Elements 71 | for (OutputStreamWritable e : elements) 72 | e.writeTo(os); 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return "VariableLengthByteArraySortedSet{" + 78 | "elementsCount=" + elements.size() + 79 | '}'; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/query/simple/SortingScoredDocumentIteratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.query.simple; 12 | 13 | import com.yandex.yoctodb.DatabaseFormat; 14 | import com.yandex.yoctodb.mutable.DatabaseBuilder; 15 | import com.yandex.yoctodb.util.buf.Buffer; 16 | import com.yandex.yoctodb.util.mutable.impl.ReadOnlyOneBitSet; 17 | import com.yandex.yoctodb.v1.immutable.V1Database; 18 | import org.junit.Test; 19 | 20 | import java.io.ByteArrayOutputStream; 21 | import java.io.IOException; 22 | import java.util.Collections; 23 | 24 | import static com.yandex.yoctodb.mutable.DocumentBuilder.IndexOption.FULL; 25 | import static com.yandex.yoctodb.query.QueryBuilder.asc; 26 | 27 | /** 28 | * Unit tests for {@link com.yandex.yoctodb.query.simple.SortingScoredDocumentIterator} 29 | * 30 | * @author incubos 31 | */ 32 | public class SortingScoredDocumentIteratorTest { 33 | private final DatabaseFormat FORMAT = DatabaseFormat.getCurrent(); 34 | 35 | @Test(expected = UnsupportedOperationException.class) 36 | public void unsupportedRemove() throws IOException { 37 | final DatabaseBuilder dbBuilder = FORMAT.newDatabaseBuilder(); 38 | 39 | // Document 1 40 | dbBuilder.merge( 41 | FORMAT.newDocumentBuilder() 42 | .withField("text", "doc1234", FULL) 43 | .withField("int", 1, FULL) 44 | .withPayload("payload1".getBytes())); 45 | 46 | // Document 2 47 | dbBuilder.merge( 48 | FORMAT.newDocumentBuilder() 49 | .withField("text", "doc2", FULL) 50 | .withField("int", 2, FULL) 51 | .withPayload("payload2".getBytes())); 52 | 53 | final ByteArrayOutputStream os = new ByteArrayOutputStream(); 54 | dbBuilder.buildWritable().writeTo(os); 55 | 56 | final V1Database db = (V1Database) DatabaseFormat.getCurrent() 57 | .getDatabaseReader() 58 | .from(Buffer.from(os.toByteArray())); 59 | 60 | final SortingScoredDocumentIterator iterator = 61 | new SortingScoredDocumentIterator( 62 | db, 63 | new ReadOnlyOneBitSet(db.getDocumentCount()), 64 | Collections.singletonList(asc("text"))); 65 | 66 | iterator.remove(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/immutable/impl/FoldedByteArrayIndexedListTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable.impl; 12 | 13 | import com.yandex.yoctodb.util.UnsignedByteArray; 14 | import com.yandex.yoctodb.util.buf.Buffer; 15 | import com.yandex.yoctodb.util.immutable.ByteArrayIndexedList; 16 | import org.junit.Test; 17 | 18 | import java.io.ByteArrayOutputStream; 19 | import java.io.IOException; 20 | import java.util.Collection; 21 | import java.util.LinkedList; 22 | 23 | import static com.yandex.yoctodb.util.UnsignedByteArrays.from; 24 | import static org.junit.Assert.assertEquals; 25 | import static org.junit.Assert.assertTrue; 26 | 27 | /** 28 | * {@link com.yandex.yoctodb.util.immutable.ByteArrayIndexedList} with fixed size 29 | * elements 30 | * 31 | * @author irenkamalova 32 | */ 33 | public class FoldedByteArrayIndexedListTest { 34 | 35 | private ByteArrayIndexedList build(int size) throws IOException { 36 | final Collection elements = new LinkedList<>(); 37 | for (int i = 0; i < 50; i++) { 38 | if (i % 2 == 0) 39 | elements.add(from(i)); 40 | else 41 | elements.add(from(i % 3 == 0 ? 1L : (long) i)); 42 | } 43 | for (int i = 50; i < size; i++) { 44 | elements.add(from(i)); 45 | } 46 | 47 | final com.yandex.yoctodb.util.mutable.ByteArrayIndexedList mutable = 48 | new com.yandex.yoctodb.util.mutable.impl.VariableLengthByteArrayIndexedList(elements); 49 | 50 | final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 51 | mutable.writeTo(baos); 52 | 53 | final Buffer buf = Buffer.from(baos.toByteArray()); 54 | 55 | final ByteArrayIndexedList result = 56 | FoldedByteArrayIndexedList.from(buf); 57 | 58 | assertEquals(size, result.size()); 59 | 60 | return result; 61 | } 62 | 63 | @Test 64 | public void testBytesFolding() throws IOException { 65 | assertTrue(build(100).toString().contains(Integer.toString(100))); 66 | } 67 | 68 | @Test 69 | public void testShortFolding() throws IOException { 70 | assertTrue(build(1000).toString().contains(Integer.toString(1000))); 71 | } 72 | 73 | @Test 74 | public void testIntegerFolding() throws IOException { 75 | assertTrue(build(70000).toString().contains(Integer.toString(70000))); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/stored/ManyNonUniqueValuesTest.java: -------------------------------------------------------------------------------- 1 | package com.yandex.yoctodb.util.mutable.stored; 2 | 3 | import com.yandex.yoctodb.DatabaseFormat; 4 | import com.yandex.yoctodb.immutable.Database; 5 | import com.yandex.yoctodb.mutable.DatabaseBuilder; 6 | import com.yandex.yoctodb.mutable.DocumentBuilder; 7 | import com.yandex.yoctodb.util.UnsignedByteArrays; 8 | import com.yandex.yoctodb.util.buf.Buffer; 9 | import org.junit.Test; 10 | 11 | import java.io.ByteArrayOutputStream; 12 | import java.io.IOException; 13 | 14 | import static com.yandex.yoctodb.mutable.DocumentBuilder.IndexOption.STORED; 15 | import static org.junit.Assert.assertEquals; 16 | 17 | /** 18 | * {@link com.yandex.yoctodb.util.immutable.ByteArrayIndexedList} with fixed size 19 | * elements 20 | * 21 | * @author irenkamalova 22 | */ 23 | public class ManyNonUniqueValuesTest { 24 | private String fieldName = "test"; 25 | @Test 26 | public void oneByte() throws IOException { 27 | testDB(100); 28 | } 29 | @Test 30 | public void twoByte() throws IOException { 31 | testDB(300); 32 | } 33 | 34 | @Test 35 | public void fourByte() throws IOException { 36 | testDB(70000); 37 | } 38 | 39 | private void testDB(final int size) throws IOException { 40 | final DatabaseBuilder dbBuilder = 41 | DatabaseFormat.getCurrent().newDatabaseBuilder(); 42 | // init first 10 elements by the same values 43 | for (int i = 0; i < 10; i++) { 44 | dbBuilder.merge(buildTestDocument(Integer.toString((0)))); 45 | } 46 | for (int i = 10; i < size; i++) { 47 | dbBuilder.merge(buildTestDocument(Integer.toString((i)))); 48 | } 49 | final ByteArrayOutputStream os = new ByteArrayOutputStream(); 50 | dbBuilder.buildWritable().writeTo(os); 51 | 52 | final Database db = 53 | DatabaseFormat.getCurrent() 54 | .getDatabaseReader() 55 | .from(Buffer.from(os.toByteArray())); 56 | for (int i = 0; i < 10; i++) { 57 | assertEquals(Integer.toString((0)), 58 | UnsignedByteArrays.toString( 59 | UnsignedByteArrays.from(db.getFieldValue(i, fieldName)))); 60 | } 61 | for (int i = 10; i < 100; i++) { 62 | assertEquals(Integer.toString((i)), 63 | UnsignedByteArrays.toString( 64 | UnsignedByteArrays.from(db.getFieldValue(i, fieldName)))); 65 | } 66 | } 67 | 68 | private DocumentBuilder buildTestDocument(String value) { 69 | return DatabaseFormat.getCurrent().newDocumentBuilder() 70 | .withField(fieldName, value, STORED); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/VariableLengthByteArrayIndexedList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.google.common.primitives.Ints; 14 | import com.google.common.primitives.Longs; 15 | import com.yandex.yoctodb.util.OutputStreamWritable; 16 | import com.yandex.yoctodb.util.UnsignedByteArray; 17 | import com.yandex.yoctodb.util.mutable.ByteArrayIndexedList; 18 | import net.jcip.annotations.NotThreadSafe; 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | import java.io.IOException; 22 | import java.io.OutputStream; 23 | import java.util.Collection; 24 | 25 | /** 26 | * {@link ByteArrayIndexedList} with variable sized elements 27 | * 28 | * @author incubos 29 | */ 30 | @NotThreadSafe 31 | public final class VariableLengthByteArrayIndexedList 32 | implements ByteArrayIndexedList { 33 | @NotNull 34 | private final Collection elements; 35 | private final long elementSize; 36 | 37 | public VariableLengthByteArrayIndexedList( 38 | @NotNull 39 | final Collection elements) { 40 | this.elements = elements; 41 | long elementSize = 0; 42 | for (UnsignedByteArray element : elements) { 43 | elementSize += element.length(); 44 | } 45 | this.elementSize = elementSize; 46 | } 47 | 48 | @Override 49 | public long getSizeInBytes() { 50 | return 4L + // Element count 51 | 8L * (elements.size() + 1L) + // Element offsets 52 | elementSize; // Element array size 53 | } 54 | 55 | @Override 56 | public void writeTo( 57 | @NotNull 58 | final OutputStream os) throws IOException { 59 | // Element count 60 | os.write(Ints.toByteArray(elements.size())); 61 | 62 | // Element offsets 63 | long elementOffset = 0; 64 | for (OutputStreamWritable e : elements) { 65 | os.write(Longs.toByteArray(elementOffset)); 66 | elementOffset += e.getSizeInBytes(); 67 | } 68 | os.write(Longs.toByteArray(elementOffset)); 69 | 70 | // Elements 71 | for (OutputStreamWritable e : elements) 72 | e.writeTo(os); 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return "VariableLengthByteArrayIndexedList{" + 78 | "elementsCount=" + elements.size() + 79 | '}'; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/common/BufferIterator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2018 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.common; 12 | 13 | import com.yandex.yoctodb.util.buf.Buffer; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | import java.nio.ByteBuffer; 17 | import java.util.Collection; 18 | import java.util.NoSuchElementException; 19 | 20 | public final class BufferIterator { 21 | @NotNull 22 | private final Buffer buffer; 23 | private final long limit; 24 | private long position; 25 | 26 | public BufferIterator(@NotNull Buffer buffer) { 27 | this.buffer = buffer; 28 | this.position = buffer.position(); 29 | this.limit = this.position + buffer.remaining(); 30 | } 31 | 32 | public BufferIterator(@NotNull Buffer buffer, long offset, long size) { 33 | this.buffer = buffer; 34 | this.position = offset; 35 | this.limit = Math.min(buffer.limit(), offset + size); 36 | } 37 | 38 | public final boolean hasNext() { 39 | return position < limit; 40 | } 41 | 42 | public final int next() { 43 | if (hasNext()) { 44 | return Byte.toUnsignedInt(buffer.get(position++)); 45 | } else { 46 | throw new NoSuchElementException("Empty iterator"); 47 | } 48 | } 49 | 50 | /** 51 | * Strips equal bytes of this iterator by {@code prefix} iterator. 52 | * 53 | * @param prefix iterator that contains prefix 54 | * @return {@code 0} if this iterator was equal to prefix or larger in length, 55 | * negative value if it was shorter or lexicographically smaller than {@code prefix} 56 | * positive value if it was lexicographically larger than {@code prefix} 57 | */ 58 | public final int compareToPrefix(@NotNull BufferIterator prefix) { 59 | while (this.hasNext() && prefix.hasNext()) { 60 | int result = Integer.compare(this.next(), prefix.next()); 61 | if (result != 0) { 62 | return result; 63 | } 64 | } 65 | 66 | return prefix.hasNext() ? -1 : 0; 67 | } 68 | 69 | public static BufferIterator wrapCopy(@NotNull final Collection bytes) { 70 | final ByteBuffer allocated = ByteBuffer.allocate(bytes.size()); 71 | for (Byte b : bytes) { 72 | allocated.put(b); 73 | } 74 | allocated.rewind(); 75 | 76 | final Buffer buf = Buffer.from(allocated); 77 | return new BufferIterator(buf); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/AbstractArrayBitSetPoolTestBench.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable; 12 | 13 | import org.junit.Test; 14 | 15 | import static org.junit.Assert.assertEquals; 16 | 17 | /** 18 | * Unit tests for any {@link ArrayBitSetPool} implementation 19 | * 20 | * @author incubos 21 | */ 22 | public abstract class AbstractArrayBitSetPoolTestBench { 23 | protected abstract ArrayBitSetPool allocate(); 24 | 25 | @Test 26 | public void borrowOne() { 27 | final ArrayBitSetPool pool = allocate(); 28 | final ArrayBitSet set = pool.borrowSet(1); 29 | assertEquals(1, set.getSize()); 30 | assertEquals(0, set.cardinality()); 31 | } 32 | 33 | @Test 34 | public void borrowTwo() { 35 | final ArrayBitSetPool pool = allocate(); 36 | 37 | final ArrayBitSet set1 = pool.borrowSet(1); 38 | assertEquals(1, set1.getSize()); 39 | assertEquals(0, set1.cardinality()); 40 | 41 | final ArrayBitSet set2 = pool.borrowSet(1); 42 | assertEquals(1, set2.getSize()); 43 | assertEquals(0, set2.cardinality()); 44 | 45 | set1.set(); 46 | assertEquals(1, set1.cardinality()); 47 | assertEquals(0, set2.cardinality()); 48 | set2.clear(); 49 | assertEquals(1, set1.cardinality()); 50 | assertEquals(0, set2.cardinality()); 51 | } 52 | 53 | @Test 54 | public void smallAndBig() { 55 | final ArrayBitSetPool pool = allocate(); 56 | 57 | final ArrayBitSet set1 = pool.borrowSet(1); 58 | assertEquals(1, set1.getSize()); 59 | assertEquals(0, set1.cardinality()); 60 | 61 | set1.set(); 62 | assertEquals(1, set1.cardinality()); 63 | pool.returnSet(set1); 64 | 65 | final ArrayBitSet set2 = pool.borrowSet(1024); 66 | assertEquals(1024, set2.getSize()); 67 | assertEquals(0, set2.cardinality()); 68 | } 69 | 70 | @Test 71 | public void bigAndSmall() { 72 | final ArrayBitSetPool pool = allocate(); 73 | 74 | final ArrayBitSet set1 = pool.borrowSet(1024); 75 | assertEquals(1024, set1.getSize()); 76 | assertEquals(0, set1.cardinality()); 77 | 78 | set1.set(); 79 | assertEquals(1024, set1.cardinality()); 80 | pool.returnSet(set1); 81 | 82 | final ArrayBitSet set2 = pool.borrowSet(1); 83 | assertEquals(1, set2.getSize()); 84 | assertEquals(0, set2.cardinality()); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/MessageDigestOutputStreamWrapperTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util; 12 | 13 | import com.google.common.io.ByteStreams; 14 | import com.yandex.yoctodb.v1.V1DatabaseFormat; 15 | import org.junit.Test; 16 | 17 | import java.io.IOException; 18 | import java.security.MessageDigest; 19 | import java.security.NoSuchAlgorithmException; 20 | import java.util.Arrays; 21 | 22 | import static org.junit.Assert.assertTrue; 23 | 24 | /** 25 | * Unit tests for {@link MessageDigestOutputStreamWrapper} 26 | * 27 | * @author incubos 28 | */ 29 | public class MessageDigestOutputStreamWrapperTest { 30 | private static final MessageDigest md; 31 | 32 | static { 33 | try { 34 | md = MessageDigest.getInstance( 35 | V1DatabaseFormat.getMessageDigestAlgorithm()); 36 | } catch (NoSuchAlgorithmException e) { 37 | throw new RuntimeException(e); 38 | } 39 | } 40 | 41 | @Test 42 | public void byteDigest() throws IOException { 43 | final MessageDigestOutputStreamWrapper w1 = 44 | new MessageDigestOutputStreamWrapper( 45 | ByteStreams.nullOutputStream(), 46 | md); 47 | final byte v1 = 42; 48 | w1.write(v1); 49 | w1.flush(); 50 | w1.close(); 51 | final byte[] d1 = w1.digest(); 52 | 53 | final MessageDigestOutputStreamWrapper w2 = 54 | new MessageDigestOutputStreamWrapper( 55 | ByteStreams.nullOutputStream(), 56 | md); 57 | final byte v2 = 43; 58 | w2.write(v2); 59 | w2.flush(); 60 | w2.close(); 61 | final byte[] d2 = w2.digest(); 62 | 63 | assertTrue(!Arrays.equals(d1, d2)); 64 | } 65 | 66 | @Test 67 | public void bufDigest() throws IOException { 68 | final MessageDigestOutputStreamWrapper w1 = 69 | new MessageDigestOutputStreamWrapper( 70 | ByteStreams.nullOutputStream(), 71 | md); 72 | final byte[] v1 = "v1".getBytes(); 73 | w1.write(v1); 74 | w1.flush(); 75 | w1.close(); 76 | final byte[] d1 = w1.digest(); 77 | 78 | final MessageDigestOutputStreamWrapper w2 = 79 | new MessageDigestOutputStreamWrapper( 80 | ByteStreams.nullOutputStream(), 81 | md); 82 | final byte[] v2 = "v2".getBytes(); 83 | w2.write(v2); 84 | w2.flush(); 85 | w2.close(); 86 | final byte[] d2 = w2.digest(); 87 | 88 | assertTrue(!Arrays.equals(d1, d2)); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/StoredIndexWithEmptyTest.java: -------------------------------------------------------------------------------- 1 | package com.yandex.yoctodb; 2 | 3 | import com.yandex.yoctodb.immutable.Database; 4 | import com.yandex.yoctodb.mutable.DatabaseBuilder; 5 | import com.yandex.yoctodb.util.UnsignedByteArray; 6 | import com.yandex.yoctodb.util.UnsignedByteArrays; 7 | import com.yandex.yoctodb.util.buf.Buffer; 8 | import org.junit.Test; 9 | 10 | import java.io.ByteArrayOutputStream; 11 | import java.io.IOException; 12 | 13 | import static com.yandex.yoctodb.mutable.DocumentBuilder.IndexOption.STORED; 14 | import static org.junit.Assert.assertEquals; 15 | 16 | /** 17 | * {@link com.yandex.yoctodb.util.immutable.ByteArrayIndexedList} with fixed size 18 | * elements 19 | * 20 | * @author irenkamalova 21 | */ 22 | public class StoredIndexWithEmptyTest { 23 | 24 | @Test 25 | public void buildDatabase() throws IOException { 26 | final DatabaseBuilder dbBuilder = 27 | DatabaseFormat.getCurrent().newDatabaseBuilder(); 28 | 29 | // Document 1, docId = 0 30 | dbBuilder.merge( 31 | DatabaseFormat 32 | .getCurrent() 33 | .newDocumentBuilder() 34 | .withField("state", "NEW", STORED)); 35 | 36 | // for docId = 1 there is no value for field state: 37 | dbBuilder.merge( 38 | DatabaseFormat 39 | .getCurrent() 40 | .newDocumentBuilder() 41 | .withField("region", "1", STORED)); 42 | 43 | // for docId = 2 44 | dbBuilder.merge( 45 | DatabaseFormat 46 | .getCurrent() 47 | .newDocumentBuilder() 48 | .withField("state", "N", STORED)); 49 | 50 | dbBuilder.merge( 51 | DatabaseFormat 52 | .getCurrent() 53 | .newDocumentBuilder() 54 | .withField("region", "2", STORED)); 55 | 56 | dbBuilder.merge( 57 | DatabaseFormat 58 | .getCurrent() 59 | .newDocumentBuilder() 60 | .withField("state", "USED", STORED)); 61 | 62 | final ByteArrayOutputStream os = new ByteArrayOutputStream(); 63 | dbBuilder.buildWritable().writeTo(os); 64 | 65 | final Database db = 66 | DatabaseFormat.getCurrent() 67 | .getDatabaseReader() 68 | .from(Buffer.from(os.toByteArray())); 69 | 70 | assertEquals("NEW",getValueFromBuffer(db.getFieldValue(0, "state"))); 71 | assertEquals("1",getValueFromBuffer(db.getFieldValue(1, "region"))); 72 | assertEquals("N",getValueFromBuffer(db.getFieldValue(2, "state"))); 73 | assertEquals("2",getValueFromBuffer(db.getFieldValue(3, "region"))); 74 | assertEquals("USED",getValueFromBuffer(db.getFieldValue(4, "state"))); 75 | 76 | } 77 | 78 | private String getValueFromBuffer(Buffer buffer) { 79 | UnsignedByteArray byteArray = UnsignedByteArrays.from(buffer); 80 | return UnsignedByteArrays.toString(byteArray); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/immutable/impl/IndexToIndexMultiMapReaderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.immutable.impl; 12 | 13 | import com.google.common.collect.TreeMultimap; 14 | import com.google.common.primitives.Ints; 15 | import com.yandex.yoctodb.util.buf.Buffer; 16 | import com.yandex.yoctodb.util.immutable.IndexToIndexMultiMap; 17 | import org.junit.Test; 18 | 19 | import java.io.ByteArrayOutputStream; 20 | import java.io.IOException; 21 | 22 | import static org.junit.Assert.assertTrue; 23 | 24 | /** 25 | * Unit tests for {@link IndexToIndexMultiMapReader} 26 | * 27 | * @author incubos 28 | */ 29 | public class IndexToIndexMultiMapReaderTest { 30 | 31 | private final int DOCS = 128; 32 | 33 | @Test 34 | public void buildInt() throws IOException { 35 | final TreeMultimap elements = TreeMultimap.create(); 36 | for (int i = 0; i < DOCS; i++) { 37 | elements.put(i / 2, i); 38 | } 39 | final com.yandex.yoctodb.util.mutable.IndexToIndexMultiMap mutable = 40 | new com.yandex.yoctodb.util.mutable.impl.IntIndexToIndexMultiMap( 41 | elements.asMap().values()); 42 | 43 | final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 44 | mutable.writeTo(baos); 45 | 46 | final Buffer buf = Buffer.from(baos.toByteArray()); 47 | 48 | final IndexToIndexMultiMap result = 49 | IndexToIndexMultiMapReader.from(buf); 50 | 51 | assertTrue(result instanceof IntIndexToIndexMultiMap); 52 | } 53 | 54 | @Test 55 | public void buildBitSet() throws IOException { 56 | final TreeMultimap elements = TreeMultimap.create(); 57 | for (int i = 0; i < DOCS; i++) { 58 | elements.put(i / 2, i); 59 | } 60 | final com.yandex.yoctodb.util.mutable.IndexToIndexMultiMap mutable = 61 | new com.yandex.yoctodb.util.mutable.impl.BitSetIndexToIndexMultiMap( 62 | elements.asMap().values(), 63 | DOCS); 64 | 65 | final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 66 | mutable.writeTo(baos); 67 | 68 | final Buffer buf = Buffer.from(baos.toByteArray()); 69 | 70 | final IndexToIndexMultiMap result = 71 | IndexToIndexMultiMapReader.from(buf); 72 | 73 | assertTrue(result instanceof BitSetIndexToIndexMultiMap); 74 | } 75 | 76 | @Test(expected = UnsupportedOperationException.class) 77 | public void unsupported() throws IOException { 78 | final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 79 | 80 | baos.write(Ints.toByteArray(Integer.MAX_VALUE)); 81 | 82 | final Buffer buf = Buffer.from(baos.toByteArray()); 83 | 84 | IndexToIndexMultiMapReader.from(buf); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/mutable/impl/BitSetIndexToIndexMultiMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.google.common.primitives.Ints; 14 | import com.google.common.primitives.Longs; 15 | import com.yandex.yoctodb.util.mutable.ArrayBitSet; 16 | import com.yandex.yoctodb.util.mutable.IndexToIndexMultiMap; 17 | import com.yandex.yoctodb.v1.V1DatabaseFormat; 18 | import net.jcip.annotations.NotThreadSafe; 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | import java.io.IOException; 22 | import java.io.OutputStream; 23 | import java.util.Collection; 24 | 25 | /** 26 | * {@link IndexToIndexMultiMap} implementation based on {@link LongArrayBitSet}s 27 | * 28 | * @author svyatoslav 29 | * @author incubos 30 | */ 31 | @NotThreadSafe 32 | public final class BitSetIndexToIndexMultiMap implements IndexToIndexMultiMap { 33 | private final int documentsCount; 34 | @NotNull 35 | private final Collection> map; 36 | 37 | public BitSetIndexToIndexMultiMap( 38 | @NotNull 39 | final Collection> map, 40 | final int documentsCount) { 41 | if (documentsCount < 0) 42 | throw new IllegalArgumentException("Negative document count"); 43 | 44 | this.map = map; 45 | this.documentsCount = documentsCount; 46 | } 47 | 48 | @Override 49 | public long getSizeInBytes() { 50 | return 4L + // Type 51 | 4L + // Keys count 52 | 4L + // Bit set size in longs 53 | 8L * map.size() * LongArrayBitSet.arraySize(documentsCount); 54 | } 55 | 56 | @Override 57 | public void writeTo( 58 | @NotNull 59 | final OutputStream os) throws IOException { 60 | // Type 61 | os.write(Ints.toByteArray(V1DatabaseFormat.MultiMapType.LONG_ARRAY_BIT_SET_BASED.getCode())); 62 | 63 | // Keys count 64 | os.write(Ints.toByteArray(map.size())); 65 | 66 | // Count longs in bit-set 67 | os.write(Ints.toByteArray(LongArrayBitSet.arraySize(documentsCount))); 68 | 69 | // Sets 70 | final ArrayBitSet docs = LongArrayBitSet.zero(documentsCount); 71 | for (Collection ids : map) { 72 | docs.clear(); 73 | for (int docId : ids) { 74 | assert 0 <= docId && docId < documentsCount; 75 | docs.set(docId); 76 | } 77 | for (long currentWord : docs.toArray()) { 78 | os.write(Longs.toByteArray(currentWord)); 79 | } 80 | } 81 | } 82 | 83 | @Override 84 | public String toString() { 85 | return "BitSetIndexToIndexMultiMap{" + 86 | "values=" + map.size() + 87 | ", documentsCount=" + documentsCount + 88 | '}'; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /core/src/main/java/com/yandex/yoctodb/util/UnsignedByteArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util; 12 | 13 | import com.google.common.primitives.Bytes; 14 | import com.google.common.primitives.UnsignedBytes; 15 | import com.yandex.yoctodb.util.buf.Buffer; 16 | import net.jcip.annotations.Immutable; 17 | import net.jcip.annotations.NotThreadSafe; 18 | import org.jetbrains.annotations.NotNull; 19 | 20 | import java.io.IOException; 21 | import java.io.OutputStream; 22 | import java.nio.ByteBuffer; 23 | import java.util.Arrays; 24 | import java.util.Iterator; 25 | 26 | /** 27 | * A wrapper for {@code byte[]} providing {@code equals()} and {@code 28 | * hashCode()} implementations. The array is supposed to be immutable. 29 | * 30 | * Bytes in the byte array are treated as unsigned. 31 | * 32 | * @author incubos 33 | */ 34 | @Immutable 35 | @NotThreadSafe 36 | public final class UnsignedByteArray 37 | implements Comparable, 38 | Iterable, 39 | OutputStreamWritable { 40 | @NotNull 41 | final byte[] data; 42 | private int hash; 43 | 44 | UnsignedByteArray( 45 | @NotNull 46 | final byte[] data) { 47 | this.data = data; 48 | } 49 | 50 | @NotNull 51 | public Buffer toByteBuffer() { 52 | return Buffer.from(ByteBuffer.wrap(data)); 53 | } 54 | 55 | @Override 56 | public Iterator iterator() { 57 | return Bytes.asList(data).iterator(); 58 | } 59 | 60 | public int length() { 61 | return data.length; 62 | } 63 | 64 | public boolean isEmpty() { 65 | return data.length == 0; 66 | } 67 | 68 | @Override 69 | public long getSizeInBytes() { 70 | return length(); 71 | } 72 | 73 | @Override 74 | public void writeTo( 75 | @NotNull 76 | final OutputStream os) throws IOException { 77 | os.write(data); 78 | } 79 | 80 | @Override 81 | public int hashCode() { 82 | if (hash == 0) { 83 | hash = Arrays.hashCode(data); 84 | } 85 | return hash; 86 | } 87 | 88 | @Override 89 | public boolean equals(final Object o) { 90 | if (this == o) return true; 91 | if (o == null || getClass() != o.getClass()) return false; 92 | 93 | final UnsignedByteArray that = (UnsignedByteArray) o; 94 | 95 | return Arrays.equals(data, that.data); 96 | } 97 | 98 | @Override 99 | public int compareTo( 100 | @NotNull 101 | final UnsignedByteArray o) { 102 | if (this == o) { 103 | return 0; 104 | } else { 105 | return UnsignedBytes.lexicographicalComparator() 106 | .compare(this.data, o.data); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /core/src/test/java/com/yandex/yoctodb/util/mutable/impl/VariableLengthByteArraySortedSetTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) YANDEX LLC, 2014-2016 3 | * 4 | * The Source Code called "YoctoDB" available at 5 | * https://github.com/yandex/yoctodb is subject to the terms of the 6 | * Mozilla Public License, v. 2.0 (hereinafter referred to as the "License"). 7 | * 8 | * A copy of the License is also available at http://mozilla.org/MPL/2.0/. 9 | */ 10 | 11 | package com.yandex.yoctodb.util.mutable.impl; 12 | 13 | import com.yandex.yoctodb.util.UnsignedByteArray; 14 | import com.yandex.yoctodb.util.mutable.ByteArraySortedSet; 15 | import org.junit.Test; 16 | 17 | import java.util.SortedSet; 18 | import java.util.TreeSet; 19 | 20 | import static com.yandex.yoctodb.util.UnsignedByteArrays.from; 21 | import static org.junit.Assert.assertEquals; 22 | import static org.junit.Assert.assertTrue; 23 | 24 | /** 25 | * Unit tests for {@link VariableLengthByteArraySortedSet} 26 | * 27 | * @author incubos 28 | */ 29 | public class VariableLengthByteArraySortedSetTest { 30 | @Test 31 | public void indexingFixed() { 32 | final SortedSet elements = new TreeSet<>(); 33 | final int size = 3; 34 | for (int i = 0; i < size; i++) 35 | elements.add(from(i)); 36 | final ByteArraySortedSet set = 37 | new VariableLengthByteArraySortedSet( 38 | elements); 39 | for (int i = 0; i < size; i++) 40 | assertEquals(i, set.indexOf(from(i))); 41 | } 42 | 43 | @Test 44 | public void indexingVariable() { 45 | final SortedSet elements = new TreeSet<>(); 46 | final byte[] e1 = new byte[]{1, 1, 0}; 47 | final byte[] e2 = new byte[]{1, 0}; 48 | final byte[] e3 = new byte[]{0}; 49 | final byte[] e4 = new byte[]{}; 50 | elements.add(from(e1)); 51 | elements.add(from(e2)); 52 | elements.add(from(e3)); 53 | elements.add(from(e4)); 54 | final ByteArraySortedSet set = 55 | new VariableLengthByteArraySortedSet( 56 | elements); 57 | assertEquals(0, set.indexOf(from(e4))); 58 | assertEquals(1, set.indexOf(from(e3))); 59 | assertEquals(2, set.indexOf(from(e2))); 60 | assertEquals(3, set.indexOf(from(e1))); 61 | } 62 | 63 | @Test(expected = AssertionError.class) 64 | public void notFound() { 65 | final SortedSet elements = new TreeSet<>(); 66 | final int size = 3; 67 | for (int i = 0; i < size; i++) 68 | elements.add(from(i)); 69 | final ByteArraySortedSet set = 70 | new VariableLengthByteArraySortedSet( 71 | elements); 72 | set.indexOf(from(size + 1)); 73 | } 74 | 75 | @Test 76 | public void string() { 77 | final SortedSet elements = new TreeSet<>(); 78 | final int size = 10; 79 | for (long i = 0; i < size; i++) 80 | elements.add(from(i)); 81 | final ByteArraySortedSet set = 82 | new VariableLengthByteArraySortedSet( 83 | elements); 84 | final String s = set.toString(); 85 | assertTrue(s.contains(Integer.toString(size))); 86 | } 87 | } 88 | --------------------------------------------------------------------------------