1 2 Previous Next 23 Replies Latest reply: May 17, 2012 9:31 PM by User738616-Oracle RSS

    How do i convert String type to an BinaryEntry Type ?

    LSV
      We have to differentiate between keys that come to Erase method of custom publisher. So, we appended "|" at the end of the key as below

      key = "a"; //Actual key that is in Cache

      if(//some condition)
      {
      newKey = "a|"; //newKey to differntiate
      getCache().remove(newKey);
      }
      else
      getCache().remove(key);

      Now, the call comes to Erase method of our custom publisher. Here, we need to perform different operation for the key which has "|" in it. So, we added below code in custom Erase method.

      public void erase(BinaryEntry binEntry)
      {
      String key = (String) binEntry.getKey();
      if(key.contains("|"))
      {
      //Need to perform some DB operation here. Then,
      //now the key is "a|". we need to remove the "|" symbol and call erase method to remove the actual key ("a") from cache. So we added below code

      String newKey = (dnsDomainName).replace("|", "");

      //Here the problem is, key is of type String. But, Erase method can take only BinaryEntry type. So, we tried this

      binEntry = (BinaryEntry)(binEntry.getContext().getKeyToInternalConverter().convert(key));

      super.erase(binEntry); //but it dint work. The entry is not getting deleted from Cache.

      //How do we convert the key that is of String type to BinaryEntry ?

      }
      else
      {
      super.erase(binEntry);
      }
      }


      Can someone suggest ?
        • 1. Re: How do i convert String type to an BinaryEntry Type ?
          robvarga
          LSV wrote:
          We have to differentiate between keys that come to Erase method of custom publisher. So, we appended "|" at the end of the key as below

          key = "a"; //Actual key that is in Cache

          if(//some condition)
          {
          newKey = "a|"; //newKey to differntiate
          getCache().remove(newKey);
          }
          else
          getCache().remove(key);

          Now, the call comes to Erase method of our custom publisher. Here, we need to perform different operation for the key which has "|" in it. So, we added below code in custom Erase method.

          public void erase(BinaryEntry binEntry)
          {
          String key = (String) binEntry.getKey();
          if(key.contains("|"))
          {
          //Need to perform some DB operation here. Then,
          //now the key is "a|". we need to remove the "|" symbol and call erase method to remove the actual key ("a") from cache. So we added below code

          String newKey = (dnsDomainName).replace("|", "");

          //Here the problem is, key is of type String. But, Erase method can take only BinaryEntry type. So, we tried this

          binEntry = (BinaryEntry)(binEntry.getContext().getKeyToInternalConverter().convert(key));

          super.erase(binEntry); //but it dint work. The entry is not getting deleted from Cache.

          //How do we convert the key that is of String type to BinaryEntry ?

          }
          else
          {
          super.erase(binEntry);
          }
          }


          Can someone suggest ?
          Excuse me, but you write here totally does not make sense on its own.

          1. What class is this method on?
          2. Why do you want to use a key in the place of an entry?

          If I correctly interpret what you try to achieve, your super-class implementation has to know how to deal with the trailing pipe character as you are never supposed to change the key on an entry, and the entry without the pipe does not exist either.

          Best regards,

          Robert
          • 2. Re: How do i convert String type to an BinaryEntry Type ?
            LSV
            To Answer your question,


            1. What class is this method on? -- This method ( erase(BinaryEntry binEntry) ) is in the CustomPublisher class which extends com.oracle.coherence.patterns.pushreplication.PublishingCacheStore.

            2. Why do you want to use a key in the place of an entry? -- My requirement is , I want to change the key that is in an BinaryEntry. Is there a way through which i can change the key of an BinaryEntry like the way we use UpdateBinaryValue for updating the value of an BinaryEntry.
            • 3. Re: How do i convert String type to an BinaryEntry Type ?
              User738616-Oracle
              Hi,

              You make your CustomPublisher class implement "com.tangosol.net.cache.BinaryEntryStore" interface to make your methods use BinaryEntry. You should never try changing the key of an object but rather set an attribute in the value of the object that differentiates your objects.

              Hope this helps!

              Cheers,
              NJ
              • 4. Re: How do i convert String type to an BinaryEntry Type ?
                LSV
                Thanks NJ,

                you mean to do a getCache().put(key,value); instead of remov(key) ?
                • 5. Re: How do i convert String type to an BinaryEntry Type ?
                  User738616-Oracle
                  Hi,
                  you mean to do a getCache().put(key,value); instead of remov(key) ?
                  No, I didn't mean the above and I am not even sure how you can replace one by another. I meant in your VO you have an attribute that differentiates your objects rather than appending a "|" to the key and try changing the key.

                  Hope this helps!

                  Cheers,
                  NJ
                  • 6. Re: How do i convert String type to an BinaryEntry Type ?
                    LSV
                    Thanks NJ,

                    got your point.
                    • 7. Re: How do i convert String type to an BinaryEntry Type ?
                      LSV
                      NJ,

                      I have a doubt, if i have an attribute in my VO to differentiate key. i call remove(key) in different class. How do i get that attribute in CustomPublisher Class ? remove method can have only key as parameter right. Still i dint get your exact solution. Can you please clear ?
                      • 8. Re: How do i convert String type to an BinaryEntry Type ?
                        User738616-Oracle
                        Hi,

                        I am not very sure what ou are trying to achieve but if the CustomPublisher class implements "com.tangosol.net.cache.BinaryEntryStore" interface, the erase(binaryEntry) and eraseAll(binaryEntries) signature will have it.

                        Hope this helps!

                        Cheers,
                        NJ
                        • 9. Re: How do i convert String type to an BinaryEntry Type ?
                          LSV
                          NJ,

                          My CustomPublisher does not implement "com.tangosol.net.cache.BinaryEntryStore". It extends "com.oracle.coherence.patterns.pushreplication.PublishingCacheStore". This is my requirement

                          I have a class where i do this.

                          Class A

                          if(//some Operation Performed in UI)
                          {
                          getCache().remove(Key); #1 remove
                          }
                          else //Different operation is performed in UI
                          {
                          getCache().remove(key); #2 remove
                          }

                          Here in both the cases, Key is same.


                          When remove(key) is called, the control comes to erase(binaryEntry) of CustomPublisher class.


                          public void erase(BinaryEntry binEntry)
                          {

                          if(#1 remove)
                          {
                          super.erase(binEntry);
                          //Need to remove the same entry from DB as well
                          }
                          else //#2 remove
                          {
                          super.erase(binEntry); //Just remove from Cache. no need to delete from DB.
                          }
                          }


                          So, i need to differentiate between #1 remove and #2 remove operation done in Class A. We can not pass value in remove method. We can just pass a Key. So, i was trying to add a flag in Key itself (in Class A) and try to differentiate it in CustomPublisher class. But, it dint work. and i realize that it is not advisable too from your replies.


                          Hope i am clear about my requirement. Can you suggest ?

                          Edited by: LSV on May 14, 2012 6:32 AM
                          • 10. Re: How do i convert String type to an BinaryEntry Type ?
                            User738616-Oracle
                            Hi LSV,

                            Yes, now I got your usecase. I would suggest you to extend PublishingCacheStore and also implement BinaryEntryStore so that method contract remains same in your CustomPublisher and PublishingCacheStore.

                            Re selective erase, use an entry processor to set the attribute and call erase from with the entry processor. In your erase method you can check the attribute value for decision making purposes.

                            Hppe this helps!

                            Cheers,
                            NJ
                            • 11. Re: How do i convert String type to an BinaryEntry Type ?
                              Jonathan.Knight
                              user738616 wrote:
                              Re selective erase, use an entry processor to set the attribute and call erase from with the entry processor. In your erase method you can check the attribute value for decision making purposes.
                              No you cannot check the value in the erase method. If you call entry.remove() in an EntryProcessor the BinaryCacheStore is passed an entry that only contains the key and the original value, it does not include the updated value. I tried this as LSV's use case sounded quite intriguing but it does not work. The only way to get an entry with a flag set somewhere would be to do an update then a remove but the problem there is that there is no way to do both these operations atomically without using locking so another update might come and update the same entry between setting the flag and calling remove.

                              JK
                              • 12. Re: How do i convert String type to an BinaryEntry Type ?
                                User738616-Oracle
                                Hi,

                                Yes JK is right ! I forgot that the remove() will remove the entry from the BackingMap. Another alternative would be to use the below EP:
                                public class EP2 extends AbstractProcessor implements Serializable{
                                     private boolean isSynthetic;
                                     
                                     public EP2(boolean bln){
                                          this.isSynthetic=bln;
                                     }
                                     @Override
                                     public Object process(Entry entry) {
                                          BinaryEntry binEntry = (BinaryEntry) entry;
                                          if (isSynthetic){
                                               //Synthetic Remove                    
                                               
                                               // This is a bug and should evict entry and not call erase
                                               //binEntry.remove(isSynthetic);   
                                               
                                               //Alternative solution is to expire with a minimum delay of 1 ms 
                                               //This will call the store method so make a check of the original and new value and do nothing if they are same to avoid DB update
                                                        binEntry.expire(1);
                                                     
                                          }else{
                                               //Will hit the cache store               
                                               entry.remove(isSynthetic);               
                                          }
                                          return null;
                                     }
                                }
                                On client side, make a call for remove as below:
                                cache.invoke(key, new EP2(true)); // coherence eviction only
                                
                                cache.invoke(key, new EP2(false)); // for invoking erase()
                                Hope this helps!

                                Cheers,
                                NJ
                                • 13. Re: How do i convert String type to an BinaryEntry Type ?
                                  Jonathan.Knight
                                  Hi,

                                  The code above will not give you anything either.

                                  When the BinaryCacheStore erase method is called it will be passed a BinaryEntry that has a key, an original value and null for the current value. There is no way to tell how the call to erase was triggered - either by a call to remove or by eviction.

                                  If you execute the code above (I tried this in 3.7.1.3) then if isSynthetic = true you will see the store method called on the BinaryCacheStore as the Binary value is mutated to set the new expiry time, but no erase is called when the entry is evicted and even if it was there would be no way to see why erase was called.

                                  In the comment above where you say...
                                  user738616 wrote:
                                                 // This is a bug and should evict entry and not call erase
                                                 //binEntry.remove(isSynthetic);
                                  are you saying it should call erase or it should not call erase. In 3.7.1.3 the erase method is called - although I think it synthetic removes should not call erase so maybe that is what you are saying too.

                                  As I said above, I looked at this for a while yesterday and it is not straight forward to solve.

                                  JK
                                  • 14. Re: How do i convert String type to an BinaryEntry Type ?
                                    User738616-Oracle
                                    Hi,
                                    When the BinaryCacheStore erase method is called it will be passed a BinaryEntry that has a key, an original value and null for the current value. There is no way to tell how the call to erase was triggered - either by a call to remove or by eviction.
                                    cache.invoke(key, new EP2(true));
                                    The above invocation will not call the erase method at all but it will be evict the entry after 1ms so a replacement of binaryEntry.remove(true) with a side effect that the entry will stay for 1ms more. Also, this will call the store() method so need to compare the original to currentValue of the object to avoid unnecessay DB call. So, you need not worry at all about the erase() method in this case. Refer code of EP2 in the above post
                                    cache.invoke(key, new EP2(false));
                                    This code will call the erase method of the CacheStore.
                                    are you saying it should call erase or it should not call erase. In 3.7.1.3 the erase method is called - although I think it synthetic removes should not call erase so maybe that is what you are saying too.
                                    Yes binaryEntry.remove(true) should not invoke the erase() method.

                                    Hope this makes it clearer to you!

                                    Cheers,
                                    NJ
                                    1 2 Previous Next