5 Replies Latest reply: Aug 14, 2013 7:02 PM by drakitine RSS

    ConditionalIndex: bug or feature?

    AlexeyOlenev

      Let's imagine that we have ConditionalIndex with filter on fields X and Y, and this index was built by extractor which returns value of a field Z, so I expect that behaviour is something like this:

      public void onUpdate() {
          if (filter.evaluate(entry)) {
              Object value = extractor.extract(entry);
              index.update(entry.getKey(), value);
          }
      }
      
      public void onInsert() {
           // the same behaviour as for on Update()
      }
      
      

      But in fact index will not be updated in following case:

      1) Put entry in cache. Since fields X and Y don't match filter, index will not be updated

      2) Update entry in cache (doesn't matter by put() or by EntryProcessor). Now X and Y satisfy filter, BUT index will not be updated because field Z(indexed field) wasn't changed

       

      Is it a bug or feature?

      We are using Coherence 3.7.1.5

        • 1. Re: ConditionalIndex: bug or feature?
          Jonathan.Knight

          Hi Alexey

           

          I'd say this is a bug. I've tested it with the test below which fails in 3.7.1.7 and looks like it is still broken in 12.1.2.

           

          import com.tangosol.io.pof.ConfigurablePofContext;
          import com.tangosol.io.pof.annotation.Portable;
          import com.tangosol.io.pof.annotation.PortableProperty;
          import com.tangosol.net.BackingMapManagerContext;
          import com.tangosol.net.cache.BackingMapBinaryEntry;
          import com.tangosol.run.xml.XmlElement;
          import com.tangosol.run.xml.XmlHelper;
          import com.tangosol.util.Binary;
          import com.tangosol.util.ConditionalIndex;
          import com.tangosol.util.ExternalizableHelper;
          import com.tangosol.util.Filter;
          import com.tangosol.util.MapTrigger;
          import com.tangosol.util.extractor.PofExtractor;
          import com.tangosol.util.filter.AndFilter;
          import com.tangosol.util.filter.EqualsFilter;
          import org.junit.Before;
          import org.junit.Test;
          
          
          import static org.hamcrest.CoreMatchers.is;
          import static org.junit.Assert.assertThat;
          
          
          public class ConditionalIndexTest {
          
          
              private ConfigurablePofContext serializer;
          
          
              @Before
              public void setup() {
                  XmlElement pofXML = XmlHelper.loadXml("" +
                          "<?xml version=\"1.0\"?>\n" +
                          "<pof-config xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
                          "              xmlns=\"http://xmlns.oracle.com/coherence/coherence-pof-config\"\n" +
                          "              xsi:schemaLocation=\"http://xmlns.oracle.com/coherence/coherence-pof-config coherence-pof-config.xsd\">     \n" +
                          "  <user-type-list>\n" +
                          "    <include>coherence-pof-config.xml</include>\n" +
                          "    <user-type>\n" +
                          "      <type-id>1000</type-id>\n" +
                          "      <class-name>" + MyDomainClass.class.getName() + "</class-name>\n" +
                          "    </user-type>\n" +
                          "  </user-type-list>\n" +
                          "</pof-config>");
          
          
                  serializer = new ConfigurablePofContext(pofXML);
              }
          
          
              @Test
              public void shouldNotAddNonMatchingEntryOnInsert() throws Exception {
                  String key = "Key-1";
                  MyDomainClass domainObject = new MyDomainClass("X_1", "Y_1", "Z_1");
                  Binary binaryKey = ExternalizableHelper.toBinary(key, serializer);
                  Binary binaryValue = ExternalizableHelper.toBinary(domainObject, serializer);
                  BinaryEntryStub entry = new BinaryEntryStub(binaryKey, binaryValue, null, null);
          
          
                  Filter filter = new AndFilter(
                          new EqualsFilter(new PofExtractor(String.class, 1), "X_2"),
                          new EqualsFilter(new PofExtractor(String.class, 2), "Y_2")
                  );
          
          
                  PofExtractor extractor = new PofExtractor(String.class, 3);
          
          
                  ConditionalIndex index = new ConditionalIndex(filter, extractor, false, null, true, null);
                  index.insert(entry);
                  assertThat(index.getIndexContents().isEmpty(), is(true));
                  assertThat(index.isPartial(), is(true));
              }
          
          
              @Test
              public void shouldAddMatchingEntryIndexOnUpdateWhenExtractedFieldHasNotChanged() throws Exception {
                  String key = "Key-1";
                  Binary binaryKey = ExternalizableHelper.toBinary(key, serializer);
          
          
                  MyDomainClass domainObjectOriginal = new MyDomainClass("X_1", "Y_1", "Z_1");
                  Binary binaryValueOriginal = ExternalizableHelper.toBinary(domainObjectOriginal, serializer);
                  BinaryEntryStub entryInsert = new BinaryEntryStub(binaryKey, binaryValueOriginal, null, null);
          
          
                  MyDomainClass domainObjectUpdate = new MyDomainClass("X_2", "Y_2", "Z_1");
                  Binary binaryValueUpdate = ExternalizableHelper.toBinary(domainObjectUpdate, serializer);
                  BinaryEntryStub entryUpdate = new BinaryEntryStub(binaryKey, binaryValueUpdate, binaryValueOriginal, null);
          
          
                  Filter filter = new AndFilter(
                          new EqualsFilter(new PofExtractor(String.class, 1), "X_2"),
                          new EqualsFilter(new PofExtractor(String.class, 2), "Y_2")
                  );
          
          
                  PofExtractor extractor = new PofExtractor(String.class, 3);
          
          
                  ConditionalIndex index = new ConditionalIndex(filter, extractor, false, null, true, null);
                  index.insert(entryInsert);
                  index.update(entryUpdate);
          
          
                  assertThat(index.getIndexContents().isEmpty(), is(false));
                  assertThat((String) index.get(binaryKey), is("Z_1"));
              }
          
          
              @Test
              public void shouldAddMatchingEntryIndexOnUpdateWhenExtractedFieldHasChanged() throws Exception {
                  String key = "Key-1";
                  Binary binaryKey = ExternalizableHelper.toBinary(key, serializer);
          
          
                  MyDomainClass domainObjectOriginal = new MyDomainClass("X_1", "Y_1", "Z_1");
                  Binary binaryValueOriginal = ExternalizableHelper.toBinary(domainObjectOriginal, serializer);
                  BinaryEntryStub entryInsert = new BinaryEntryStub(binaryKey, binaryValueOriginal, null, null);
          
          
                  MyDomainClass domainObjectUpdate = new MyDomainClass("X_2", "Y_2", "Z_2");
                  Binary binaryValueUpdate = ExternalizableHelper.toBinary(domainObjectUpdate, serializer);
                  BinaryEntryStub entryUpdate = new BinaryEntryStub(binaryKey, binaryValueUpdate, binaryValueOriginal, null);
          
          
                  Filter filter = new AndFilter(
                          new EqualsFilter(new PofExtractor(String.class, 1), "X_2"),
                          new EqualsFilter(new PofExtractor(String.class, 2), "Y_2")
                  );
          
          
                  PofExtractor extractor = new PofExtractor(String.class, 3);
          
          
                  ConditionalIndex index = new ConditionalIndex(filter, extractor, false, null, true, null);
                  index.insert(entryInsert);
                  index.update(entryUpdate);
          
          
                  assertThat(index.getIndexContents().isEmpty(), is(false));
                  assertThat((String) index.get(binaryKey), is("Z_2"));
              }
          
          
          
          
              @Portable
              public static class MyDomainClass {
                  @PortableProperty(value = 1)
                  private String fieldX;
                  @PortableProperty(value = 2)
                  private String fieldY;
                  @PortableProperty(value = 3)
                  private String fieldZ;
          
          
                  public MyDomainClass() {
                  }
          
          
                  public MyDomainClass(String fieldX, String fieldY, String fieldZ) {
                      this.fieldX = fieldX;
                      this.fieldY = fieldY;
                      this.fieldZ = fieldZ;
                  }
              }
          
          
              private class BinaryEntryStub extends BackingMapBinaryEntry implements MapTrigger.Entry {
          
          
                  private BinaryEntryStub(Binary binKey, Binary binValue, Binary binValueOrig, BackingMapManagerContext ctx) {
                      super(binKey, binValue, binValueOrig, ctx);
                  }
          
          
                  @Override
                  public boolean isOriginalPresent() {
                      return getOriginalBinaryValue() != null;
                  }
              }
          
          
          }
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          }
          }
          
          
          

           

          JK

          • 2. Re: ConditionalIndex: bug or feature?
            AlexeyOlenev

            Hi Jonathan

            Are you going to create a ticket about it?

            • 3. Re: ConditionalIndex: bug or feature?
              Jonathan.Knight

              Ahh... well, if I worked for Oracle then I would raise a ticket but I don't so hopefully someone from Oracle will raise one or if you have a support contract you could raise an SR.

               

              JK

              • 4. Re: ConditionalIndex: bug or feature?
                AlexeyOlenev

                Sorry I thought that you are from Oracle Support team.

                • 5. Re: ConditionalIndex: bug or feature?
                  drakitine

                  COH-10259