Uploaded image for project: 'Terrier Core'
  1. Terrier Core
  2. TR-311

New integer compression techniques for the direct and inverted index structures

    Details

    • Type: New Feature
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 3.6
    • Fix Version/s: 4.0
    • Component/s: None
    • Labels:
      None

      Description

      Attached, the files for enabling modern integer compression techniques for the inverted index in Terrier.

      Files:
      matteo_compression.jar: the code
      matteo_compression_test.jar: unit testing
      JavaFastPFOR_Terrier.jar: MODIFIED JavaFastPFOR library, contains also Kamikaze. Add this to the build path.

      Required modifications to the rest of the code:

      1) In org.terrier.compression, make BitInBase public
      2) In (tes) org.terrier.tests.ShakespeareEndToEndTest, use always PostingIndex and PostingIndexInputStream instead of InvertedIndex and InvertedIndexInputStream
      3) Replace PostingTestUtils with the attached file (it contains some extra methods)

      The main entry point for this library may be the InvertedIndexRecompresser utility, which recompress a classical inverted index file using modern integer techinques specified via a configuration file. Read the javadoc documentation to learn about the usage.

        Attachments

          Issue Links

            Activity

            catena.matteo Matteo Catena created issue -
            catena.matteo Matteo Catena made changes -
            Field Original Value New Value
            Attachment PostingTestUtils.java [ 10388 ]
            catena.matteo Matteo Catena made changes -
            Attachment matteo_compression_test.jar [ 10389 ]
            catena.matteo Matteo Catena made changes -
            Description Attached the file for enabling modern integer compression techniques for the inverted index in Terrier.

            Files:
            matteo_compression.jar: the code
            matteo_compression_test.jar: unit testing
            JavaFastPFOR_Terrier.jar: MODIFIED JavaFastPFOR library, contains also Kamikaze. Add this to the build path.

            Required modifications to the rest of the code:

            1) In org.terrier.compression, make BitInBase public
            2) In (tes) org.terrier.tests.ShakespeareEndToEndTest, use always PostingIndex and PostingIndexInputStream instead of InvertedIndex and InvertedIndexInputStream
            3) Replace PostingTestUtils with the attached file (it contains some extra methods)
            Attached, the files for enabling modern integer compression techniques for the inverted index in Terrier.

            Files:
            matteo_compression.jar: the code
            matteo_compression_test.jar: unit testing
            JavaFastPFOR_Terrier.jar: MODIFIED JavaFastPFOR library, contains also Kamikaze. Add this to the build path.

            Required modifications to the rest of the code:

            1) In org.terrier.compression, make BitInBase public
            2) In (tes) org.terrier.tests.ShakespeareEndToEndTest, use always PostingIndex and PostingIndexInputStream instead of InvertedIndex and InvertedIndexInputStream
            3) Replace PostingTestUtils with the attached file (it contains some extra methods)

            The main entry point for this library may be the InvertedIndexRecompresser utility, which recompress a classical inverted index file using modern integer techinques specified via a configuration file. Read the javadoc documentation to learn about the usage.
            craigm Craig Macdonald made changes -
            Fix Version/s 4.0 [ 10050 ]
            craigm Craig Macdonald made changes -
            Link This issue is related to TREC-368 [ TREC-368 ]
            Hide
            craigm Craig Macdonald added a comment -

            Matteo,

            This is the corresponding proposed CompressionConfiguration class for your work on compression. I haven't finished the bit about the Properties object that needs to be fed to the compression codec, I think you 'll need to provide me with more details about this bit.

            Thanks

            Craig

            Show
            craigm Craig Macdonald added a comment - Matteo, This is the corresponding proposed CompressionConfiguration class for your work on compression. I haven't finished the bit about the Properties object that needs to be fed to the compression codec, I think you 'll need to provide me with more details about this bit. Thanks Craig
            craigm Craig Macdonald made changes -
            Hide
            catena.matteo Matteo Catena added a comment - - edited

            From IntegerCodingPostingIndex.java:
            /**
            This implementation of

            {@link PostingIndex}

            provides access to an index of

            {@link IntegerCodingIterablePosting}

            s.
            This expects in the data.properties file some information, such as

            index.structureName.fields.count=the number of fields in the postings, if any
            index.structureName.blocks=0 (no blocks) or 1 (positions) or >1 (blocks of any size)
            index.structureName.compression.chunk-size=the maximum number of posting in a chunk
            index.structureName.compression.ids.factory-class=the

            {@link IntegerCodecFactory} implementation to use to get an {@link IntegerCodec} for docIds
            index.structureName.compression.tfs.factory-class=the {@link IntegerCodecFactory}

            implementation to use to get an

            {@link IntegerCodec} for tfs
            index.structureName.compression.fields.factory-class=the {@link IntegerCodecFactory} implementation to use to get an {@link IntegerCodec}

            for fields (optional)
            index.structureName.compression.blocks.factory-class=the

            {@link IntegerCodecFactory}

            implementation to use to get an

            {@link IntegerCodec}

            for blocks (optional)
            Note: depending on the factory-class property, other properties may be needed.
            //

            VIntCodecFactory, GammaCodecFactory, etc. should be fine with just that. JavaFastPFOR codecs requires some more properties. The most general configuration is as in LemireCodecFactory.java:
            /**
            This factory builds IntegerCodecs which wrap IntegerCODEC from the JavaFastPFOR package.
            This works reading properties from the data.properties file.
            In particular:
            prefix+.integercodec-class (the choosen codec);
            prefix+integercodec.primary-class (the primary codec, IF integercodec-class is a Composition);
            prefix+integercodec.secondary-class (the fallback codec, IF integercodec-class is a Composition);
            The available integercodec-class are
            me.lemire.integercompression.Composition
            me.lemire.integercompression.Simple16 (doesn't need to specify anything primary and secondary)
            me.lemire.integercompression.VariableByte (doesn't need to specify anything primary and secondary)

            The available integercodec.primary-class are
            me.lemire.integercompression.Kamikaze
            me.lemire.integercompression.NewPFD
            me.lemire.integercompression.OptPFD
            me.lemire.integercompression.FastPFOR
            me.lemire.integercompression.BinaryPacking

            The available integercodec.secondary-class are
            me.lemire.integercompression.Simple16
            me.lemire.integercompression.VariableByte

            For a simpler configuration, look at

            {@link SimpleLemireCodecFactoryS16}

            or

            {@link SimpleLemireCodecFactoryVB}

            //

            Show
            catena.matteo Matteo Catena added a comment - - edited From IntegerCodingPostingIndex.java: /** This implementation of {@link PostingIndex} provides access to an index of {@link IntegerCodingIterablePosting} s. This expects in the data.properties file some information, such as index.structureName.fields.count=the number of fields in the postings, if any index.structureName.blocks=0 (no blocks) or 1 (positions) or >1 (blocks of any size) index.structureName.compression.chunk-size=the maximum number of posting in a chunk index.structureName.compression.ids.factory-class=the {@link IntegerCodecFactory} implementation to use to get an {@link IntegerCodec} for docIds index.structureName.compression.tfs.factory-class=the {@link IntegerCodecFactory} implementation to use to get an {@link IntegerCodec} for tfs index.structureName.compression.fields.factory-class=the {@link IntegerCodecFactory} implementation to use to get an {@link IntegerCodec} for fields (optional) index.structureName.compression.blocks.factory-class=the {@link IntegerCodecFactory} implementation to use to get an {@link IntegerCodec} for blocks (optional) Note: depending on the factory-class property, other properties may be needed. // VIntCodecFactory, GammaCodecFactory, etc. should be fine with just that. JavaFastPFOR codecs requires some more properties. The most general configuration is as in LemireCodecFactory.java: /** This factory builds IntegerCodecs which wrap IntegerCODEC from the JavaFastPFOR package. This works reading properties from the data.properties file. In particular: prefix+.integercodec-class (the choosen codec); prefix+integercodec.primary-class (the primary codec, IF integercodec-class is a Composition); prefix+integercodec.secondary-class (the fallback codec, IF integercodec-class is a Composition); The available integercodec-class are me.lemire.integercompression.Composition me.lemire.integercompression.Simple16 (doesn't need to specify anything primary and secondary) me.lemire.integercompression.VariableByte (doesn't need to specify anything primary and secondary) The available integercodec.primary-class are me.lemire.integercompression.Kamikaze me.lemire.integercompression.NewPFD me.lemire.integercompression.OptPFD me.lemire.integercompression.FastPFOR me.lemire.integercompression.BinaryPacking The available integercodec.secondary-class are me.lemire.integercompression.Simple16 me.lemire.integercompression.VariableByte For a simpler configuration, look at {@link SimpleLemireCodecFactoryS16} or {@link SimpleLemireCodecFactoryVB} //
            Hide
            craigm Craig Macdonald added a comment -

            So it looks to me that the Index (or its properties object) must be passed to the CompressionConfiguration.

            Show
            craigm Craig Macdonald added a comment - So it looks to me that the Index (or its properties object) must be passed to the CompressionConfiguration.
            Hide
            catena.matteo Matteo Catena added a comment -

            > So it looks to me that the Index (or its properties object) must be passed to the CompressionConfiguration.
            I think the advantage in using a property object was to not have to write methods with dozens of parameters. Also, number of parameters are variable depending on the chosen codec.
            There shouldn't be much differences moving the conf. strings from the index prop.obj. to the ApplicationSetup prop.obj.
            On the other hand, the chosen compression is a characteristic of an index. When you experiment with with different index you'll have different data.properties but probably just one terrier.properties.

            > On IntegerCodecCompressionConfiguration:
            @Override
            public Class<? extends IterablePosting> getPostingIteratorClass() {
            return blocks
            ? fieldCount > 0
            ? BlockFieldIntegerCodingIterablePosting.class
            : BlockIntegerCodingIterablePosting.class
            : fieldCount > 0
            ? FieldIntegerCodingIterablePosting.class
            : BasicIntegerCodingIterablePosting.class;
            }

            I'm fine with that, but mind I haven't written Block/Field/BlockField/BasicIntegerCodingIterablePosting. There is just IntegerCodingIterablePosting class doing all the things.
            (Maybe we can save some if-then-elses splitting it).

            Show
            catena.matteo Matteo Catena added a comment - > So it looks to me that the Index (or its properties object) must be passed to the CompressionConfiguration. I think the advantage in using a property object was to not have to write methods with dozens of parameters. Also, number of parameters are variable depending on the chosen codec. There shouldn't be much differences moving the conf. strings from the index prop.obj. to the ApplicationSetup prop.obj. On the other hand, the chosen compression is a characteristic of an index. When you experiment with with different index you'll have different data.properties but probably just one terrier.properties. > On IntegerCodecCompressionConfiguration: @Override public Class<? extends IterablePosting> getPostingIteratorClass() { return blocks ? fieldCount > 0 ? BlockFieldIntegerCodingIterablePosting.class : BlockIntegerCodingIterablePosting.class : fieldCount > 0 ? FieldIntegerCodingIterablePosting.class : BasicIntegerCodingIterablePosting.class; } I'm fine with that, but mind I haven't written Block/Field/BlockField/BasicIntegerCodingIterablePosting. There is just IntegerCodingIterablePosting class doing all the things. (Maybe we can save some if-then-elses splitting it).
            Hide
            craigm Craig Macdonald added a comment -

            On the latter point, I did the splits already.

            Show
            craigm Craig Macdonald added a comment - On the latter point, I did the splits already.
            Hide
            craigm Craig Macdonald added a comment -

            On the earlier point, let me clarify. There are two configuration issues:

            • telling the ConfigurationConfig object how to configure indexing: user, typically via ApplicationSetup, and should save the configuration in index properties (c.f data.properties), c.f. next point.
            • telling the IntegerCodingPostingIndex what classes to load for decompression, which should be done via the index properties (c.f data.properties).

            I'm referring to the fact that ConfigurationConfig should probably obtain the index object to store the compression configuration.

            Show
            craigm Craig Macdonald added a comment - On the earlier point, let me clarify. There are two configuration issues: telling the ConfigurationConfig object how to configure indexing: user, typically via ApplicationSetup, and should save the configuration in index properties (c.f data.properties), c.f. next point. telling the IntegerCodingPostingIndex what classes to load for decompression, which should be done via the index properties (c.f data.properties). I'm referring to the fact that ConfigurationConfig should probably obtain the index object to store the compression configuration.
            Hide
            catena.matteo Matteo Catena added a comment -

            Yes, I think index obj is needed to store compression configuration on data.properties.
            I'd say that this should read from ApplicationSetup while writing an index (+ accessing index properties to save the configuration); read from data.properties while reading and index.

            Show
            catena.matteo Matteo Catena added a comment - Yes, I think index obj is needed to store compression configuration on data.properties. I'd say that this should read from ApplicationSetup while writing an index (+ accessing index properties to save the configuration); read from data.properties while reading and index.
            Hide
            catena.matteo Matteo Catena added a comment - - edited

            On a different point:
            We are using JavaFastPFOR_Terrier.jar, which is a modified version of JavaFastPFOR.
            I wonder if we should use instead the official version of github.

            The modifications were:
            – Kamikaze's PFORDelta is part of the package (maybe we should use kamikaze official lib as well).
            – Original behaviour:
            Codecs compress an array of integers and store the #byte used for compression, array length in the same output.
            Modified behaviour:
            Codecs don't store the #byte used original array length in their output. This would be redundant, since Terrier knows a posting list length and the chunks size.
            Also, my IntegerCodec has to store the #bytes used in the posting list, BEFORE the codec output (this information is used also for skipping).
            While this permitted to save bytes avoiding redundant information, I wonder if we should use the official package for the sake of "standardization"

            Also, JavaFastPFOR received a lot of updates since my visit in Glasgow, and other codecs have been introduced.
            If signatures are unchanged, we get these other codecs "for free".

            Moreover, I recently spotted some other interesting codec implementations:
            https://github.com/stuhood/gvi (group varint implementation. group varint is what google said to use in DeanWSDM'09)
            http://grepcode.com/file/repo1.maven.org/maven2/org.apache.lucene/lucene-core/4.5.0/org/apache/lucene/util/packed/EliasFanoDocIdSet.java
            http://grepcode.com/file/repo1.maven.org/maven2/org.apache.lucene/lucene-core/4.5.0/org/apache/lucene/util/packed/EliasFanoEncoder.java
            These classes implement VignaWSDM'13 quasi-succint-index codec (but honestly, I'm not sure how to use and integrate this).

            Show
            catena.matteo Matteo Catena added a comment - - edited On a different point: We are using JavaFastPFOR_Terrier.jar, which is a modified version of JavaFastPFOR. I wonder if we should use instead the official version of github. The modifications were: – Kamikaze's PFORDelta is part of the package (maybe we should use kamikaze official lib as well). – Original behaviour: Codecs compress an array of integers and store the #byte used for compression, array length in the same output. Modified behaviour: Codecs don't store the #byte used original array length in their output. This would be redundant, since Terrier knows a posting list length and the chunks size. Also, my IntegerCodec has to store the #bytes used in the posting list, BEFORE the codec output (this information is used also for skipping). While this permitted to save bytes avoiding redundant information, I wonder if we should use the official package for the sake of "standardization" Also, JavaFastPFOR received a lot of updates since my visit in Glasgow, and other codecs have been introduced. If signatures are unchanged, we get these other codecs "for free". Moreover, I recently spotted some other interesting codec implementations: – https://github.com/stuhood/gvi (group varint implementation. group varint is what google said to use in DeanWSDM'09) – http://grepcode.com/file/repo1.maven.org/maven2/org.apache.lucene/lucene-core/4.5.0/org/apache/lucene/util/packed/EliasFanoDocIdSet.java http://grepcode.com/file/repo1.maven.org/maven2/org.apache.lucene/lucene-core/4.5.0/org/apache/lucene/util/packed/EliasFanoEncoder.java These classes implement VignaWSDM'13 quasi-succint-index codec (but honestly, I'm not sure how to use and integrate this).
            Hide
            craigm Craig Macdonald added a comment -

            Ok, attaching matteo_compression.jar, which is the revised version of the Integer compression package.

            I have now got this working with my branch Terrier. I am still keen to integrate this in time for Terrier 4.0.

            Matteo, I have the following notes/questions:

            • give a look at the TestIntCompressionConfiguration and IntegerCodecCompressionConfiguration to see how things have evolved.
              To instantiate a compressed index, the user would only have to state the following in the terrier.properties file:
              indexing.direct.compression.configuration=org.terrier.matteo.indexing.IntegerCodecCompressionConfiguration
              indexing.inverted.compression.configuration=org.terrier.matteo.indexing.IntegerCodecCompressionConfiguration
              compression.integer.ids.codec.factory=LemireFastPFORVBFactory
              #alternatively:
              #compression.integer.ids.codec.factory=LemireCodecFactory(Composition,FastPFOR,VariableByte)
              compression.integer.tfs.codec.factory=VIntCodecFactory
              
            • I intend to change the global properties to encapsulate the index data structure, so that compression can be configured separately between inverted and direct structures.
            • I now wonder if we need IntegerCodecFactory classes at all, given that we dont inspect the data.properties file anymore. In essence, we could just have subclasses of IntegerCodec instead. However, I can keep the factories if you are still convinced they might be useful in the future, complete with their getCodec(Properties p) and writeProperties() methods.
            • I think InMemoryIterablePosting and IntegerCodingIterablePosting are now unused and will be removed.
            • Which one is FOR (c.f. the recommendation of our paper)
            • Your provided jar files didnt included Kamikaze, but I did find a version in your home directory. I note that it is 3.0.3 is mentioned at http://data.linkedin.com/opensource/kamikaze/releases in having problems. Can we upgrade to 3.0.7? I guess you don't have any existing indices to be concerned with the minor incompatibilities noted on that website.
            Show
            craigm Craig Macdonald added a comment - Ok, attaching matteo_compression.jar, which is the revised version of the Integer compression package. I have now got this working with my branch Terrier. I am still keen to integrate this in time for Terrier 4.0. Matteo, I have the following notes/questions: give a look at the TestIntCompressionConfiguration and IntegerCodecCompressionConfiguration to see how things have evolved. To instantiate a compressed index, the user would only have to state the following in the terrier.properties file: indexing.direct.compression.configuration=org.terrier.matteo.indexing.IntegerCodecCompressionConfiguration indexing.inverted.compression.configuration=org.terrier.matteo.indexing.IntegerCodecCompressionConfiguration compression.integer.ids.codec.factory=LemireFastPFORVBFactory #alternatively: #compression.integer.ids.codec.factory=LemireCodecFactory(Composition,FastPFOR,VariableByte) compression.integer.tfs.codec.factory=VIntCodecFactory I intend to change the global properties to encapsulate the index data structure, so that compression can be configured separately between inverted and direct structures. I now wonder if we need IntegerCodecFactory classes at all, given that we dont inspect the data.properties file anymore. In essence, we could just have subclasses of IntegerCodec instead. However, I can keep the factories if you are still convinced they might be useful in the future, complete with their getCodec(Properties p) and writeProperties() methods. I think InMemoryIterablePosting and IntegerCodingIterablePosting are now unused and will be removed. Which one is FOR (c.f. the recommendation of our paper) Your provided jar files didnt included Kamikaze, but I did find a version in your home directory. I note that it is 3.0.3 is mentioned at http://data.linkedin.com/opensource/kamikaze/releases in having problems. Can we upgrade to 3.0.7? I guess you don't have any existing indices to be concerned with the minor incompatibilities noted on that website.
            craigm Craig Macdonald made changes -
            Attachment matteo_compression.jar [ 10406 ]
            Hide
            catena.matteo Matteo Catena added a comment -

            > give a look at the TestIntCompressionConfiguration and IntegerCodecCompressionConfiguration to see how things have evolved.
            > To instantiate a compressed index, the user would only have to state the following in the terrier.properties file: [...]

            It seems good to me.

            > I intend to change the global properties to encapsulate the index data structure, so that compression can be configured separately between inverted and direct structures.

            I'm not sure I got the part about global properties, but sure different compressions for inverted and direct indices sounds good.

            > I now wonder if we need IntegerCodecFactory classes at all, given that we dont inspect the data.properties file anymore. In essence, we could just have subclasses of IntegerCodec instead. However, I can keep the factories if you are still convinced they might be useful in the future, complete with their getCodec(Properties p) and writeProperties() methods.

            I'm perfectly ok in just having subclasses of IntegerCodec. As long as new codecs can be integrated easily.

            > Which one is FOR (c.f. the recommendation of our paper)

            It is called BinaryPacking in JavaFastPFOR

            > Your provided jar files didnt included Kamikaze, but I did find a version in your home directory. I note that it is 3.0.3 is mentioned at http://data.linkedin.com/opensource/kamikaze/releases in having problems. Can we upgrade to 3.0.7? I guess you don't have any existing indices to be concerned with the minor incompatibilities noted on that website.

            I think that issue is related to Lucene indices. I guess we can update to 3.0.7 w/o problems

            Show
            catena.matteo Matteo Catena added a comment - > give a look at the TestIntCompressionConfiguration and IntegerCodecCompressionConfiguration to see how things have evolved. > To instantiate a compressed index, the user would only have to state the following in the terrier.properties file: [...] It seems good to me. > I intend to change the global properties to encapsulate the index data structure, so that compression can be configured separately between inverted and direct structures. I'm not sure I got the part about global properties, but sure different compressions for inverted and direct indices sounds good. > I now wonder if we need IntegerCodecFactory classes at all, given that we dont inspect the data.properties file anymore. In essence, we could just have subclasses of IntegerCodec instead. However, I can keep the factories if you are still convinced they might be useful in the future, complete with their getCodec(Properties p) and writeProperties() methods. I'm perfectly ok in just having subclasses of IntegerCodec. As long as new codecs can be integrated easily. > Which one is FOR (c.f. the recommendation of our paper) It is called BinaryPacking in JavaFastPFOR > Your provided jar files didnt included Kamikaze, but I did find a version in your home directory. I note that it is 3.0.3 is mentioned at http://data.linkedin.com/opensource/kamikaze/releases in having problems. Can we upgrade to 3.0.7? I guess you don't have any existing indices to be concerned with the minor incompatibilities noted on that website. I think that issue is related to Lucene indices. I guess we can update to 3.0.7 w/o problems
            Hide
            craigm Craig Macdonald added a comment -

            Ok. I made the proposed changes, which reduced the number of classes significantly. This means that we can target an index compressed by FOR using the following terrier.properties:

            compression.inverted.integer.ids.codec=LemireFORVBCodec
            compression.inverted.integer.tfs.codec=LemireFORVBCodec
            compression.inverted.integer.fields.codec=LemireFORVBCodec
            compression.inverted.integer.blocks.codec=LemireFORVBCodec
            indexing.compression.configuration=IntegerCodecCompressionConfiguration
            compression.integer.chunk.size=1024
            

            Looking at these, we need a bit of uniformity in the property names, but all else looks OK.

            Show
            craigm Craig Macdonald added a comment - Ok. I made the proposed changes, which reduced the number of classes significantly. This means that we can target an index compressed by FOR using the following terrier.properties: compression.inverted.integer.ids.codec=LemireFORVBCodec compression.inverted.integer.tfs.codec=LemireFORVBCodec compression.inverted.integer.fields.codec=LemireFORVBCodec compression.inverted.integer.blocks.codec=LemireFORVBCodec indexing.compression.configuration=IntegerCodecCompressionConfiguration compression.integer.chunk.size=1024 Looking at these, we need a bit of uniformity in the property names, but all else looks OK.
            craigm Craig Macdonald made changes -
            Link This issue is blocked by TREC-368 [ TREC-368 ]
            Hide
            craigm Craig Macdonald added a comment -

            BitInBase committed in r3792

            Show
            craigm Craig Macdonald added a comment - BitInBase committed in r3792
            craigm Craig Macdonald made changes -
            Link This issue is related to TREC-387 [ TREC-387 ]
            Hide
            craigm Craig Macdonald added a comment -

            Revised title.

            Show
            craigm Craig Macdonald added a comment - Revised title.
            craigm Craig Macdonald made changes -
            Summary New integer compression techniques for the inverted index New integer compression techniques for the direct and inverted index structures
            Hide
            craigm Craig Macdonald added a comment -

            At last, committed r3839. TREC-387 should be fixed, and a top-level documentation file is required. Thanks for your hard efforts Matteo!

            Show
            craigm Craig Macdonald added a comment - At last, committed r3839. TREC-387 should be fixed, and a top-level documentation file is required. Thanks for your hard efforts Matteo!
            craigm Craig Macdonald made changes -
            Status Open [ 1 ] Resolved [ 5 ]
            Resolution Fixed [ 1 ]
            Hide
            catena.matteo Matteo Catena added a comment -

            Well done, guys!
            Classes and configurations changed a bit, so I don't know if I can be useful. But please let me know if you need any help with the documentation.

            Show
            catena.matteo Matteo Catena added a comment - Well done, guys! Classes and configurations changed a bit, so I don't know if I can be useful. But please let me know if you need any help with the documentation.
            richardm Richard McCreadie made changes -
            Project TREC [ 10010 ] Terrier Core [ 10000 ]
            Key TREC-334 TR-311
            Workflow jira [ 10725 ] Terrier Open Source [ 10874 ]
            Affects Version/s 3.6 [ 10060 ]
            Affects Version/s 3.6 [ 10061 ]
            Component/s Core [ 10020 ]
            Fix Version/s 4.0 [ 10051 ]
            Fix Version/s 4.0 [ 10050 ]

              People

              • Assignee:
                craigm Craig Macdonald
                Reporter:
                catena.matteo Matteo Catena
              • Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: