BUG + PATCH: SecondaryKeyCreator went from partial data

If you put a DatabaseEntry containing only partial in a main database data, and this primary database has an associated secondary database, then when the secondary key is be recalculated the SecondaryKeyCreator is given to the same object of DatabaseEntry partial instead of a 'merged' new DatabaseEntry containing the new value of entire data updated.

This is obviously unacceptable, because as a general rule, the secondary key may rely on all or part of the primary data, and the SecondaryKeyCreator must be able to see it all.

The patch below fixes this (including some refactoring in order to eliminate duplication of code):
diff -ur bdb/com/sleepycat/je/DatabaseEntry.java src/java/com/sleepycat/je/DatabaseEntry.java
--- bdb/com/sleepycat/je/DatabaseEntry.java     2008-06-10 10:52:08.000000000 -0500
+++ src/java/com/sleepycat/je/DatabaseEntry.java        2009-02-24 14:25:42.073159061 -0600
@@ -470,4 +471,48 @@
         }
         return hash;
     }
+
+    /**
+     * Merge this DatabaseEntry's partial data into the given existing data,
+     * truncating or extending it as required.
+     *
+     * @param origdata buffer containing the original data; will not be modified by this method
+     * @param origoffset offset of the original data in the origdata buffer
+     * @param origlen length of the original data in the origdata buffer
+     * @return the merge of the given data and this entry in a newly allocated buffer
+     * @throws NullPointerException if origdata is null
+     * @throws IllegalArgumentException if this entry is not partial
+     */
+    public byte[] mergeInto(byte[] origdata, int origoffset, int origlen) {
+
+        /* Check we're partial */
+        if (!partial)
+            throw new IllegalArgumentException("data is not partial");
+
+        /* Compute old and new lengths and allocate new buffer */
+        int oldlen = (doff + dlen > origlen) ? doff + dlen : origlen;
+        int len = oldlen - dlen + size;
+        byte[] newData = new byte[len];
+
+        /* Keep 0..doff of the old data (truncating if doff > length) */
+        int pos = 0;
+        int slicelen = (doff < origlen) ? doff : origlen;
+        if (slicelen > 0)
+            System.arraycopy(origdata, origoffset, newData, pos, slicelen);
+        pos += doff;
+
+        /* Copy in the new data */
+        slicelen = size;
+        System.arraycopy(data, offset, newData, pos, slicelen);
+        pos += slicelen;
+
+        /* Append the rest of the old data (if any). */
+        slicelen = origlen - (doff + dlen);
+        if (slicelen > 0)
+            System.arraycopy(origdata, origoffset + doff + dlen, newData, pos, slicelen);
+
+        /* Done */
+        return newData;
+    }
 }
+
diff -ur bdb/com/sleepycat/je/SecondaryDatabase.java src/java/com/sleepycat/je/SecondaryDatabase.java
--- bdb/com/sleepycat/je/SecondaryDatabase.java 2008-06-10 10:52:08.000000000 -0500
+++ src/java/com/sleepycat/je/SecondaryDatabase.java    2009-02-24 14:25:09.712446250 -0600
@@ -713,6 +713,24 @@
             return;
         }

+        /*
+         * Make sure we don't give partial data to the key creator.
+         * Assume old data is not partial, but new data might be.
+         */
+        assert oldData == null || !oldData.getPartial();
+        if (newData != null && newData.getPartial()) {
+            if (oldData == null) {
+                newData = new DatabaseEntry(newData.getData(),
+                                            newData.getOffset(),
+                                            newData.getSize());
+            } else {
+                byte[] buf = newData.mergeInto(oldData.getData(),
+                                               oldData.getOffset(),
+                                               oldData.getSize());
+                newData = new DatabaseEntry(buf);
+            }
+        }
+
         SecondaryKeyCreator keyCreator = secondaryConfig.getKeyCreator();
         if (keyCreator != null) {
             /* Each primary record may have a single secondary key. */
diff -ur bdb/com/sleepycat/je/dbi/CursorImpl.java src/java/com/sleepycat/je/dbi/CursorImpl.java
--- bdb/com/sleepycat/je/dbi/CursorImpl.java    2008-05-20 11:27:34.000000000 -0500
+++ src/java/com/sleepycat/je/dbi/CursorImpl.java       2009-02-24 14:38:38.524268376 -0600
@@ -1275,50 +1275,17 @@
             byte[] newData;

             /* Resolve partial puts. */
-            if (data.getPartial()) {
-                int dlen = data.getPartialLength();
-                int doff = data.getPartialOffset();
-                int origlen = (foundDataBytes != null) ?
-                    foundDataBytes.length : 0;
-                int oldlen = (doff + dlen > origlen) ? doff + dlen : origlen;
-                int len = oldlen - dlen + data.getSize();
-
-                if (len == 0) {
-                    newData = LogUtils.ZERO_LENGTH_BYTE_ARRAY;
-                } else {
-                    newData = new byte[len];
-                }
-                int pos = 0;
-
-                /*
-                 * Keep 0..doff of the old data (truncating if doff > length).
-                 */
-                int slicelen = (doff < origlen) ? doff : origlen;
-                if (slicelen > 0)
-                    System.arraycopy(foundDataBytes, 0, newData,
-                                     pos, slicelen);
-                pos += doff;
-
-                /* Copy in the new data. */
-                slicelen = data.getSize();
-                System.arraycopy(data.getData(), data.getOffset(),
-                                 newData, pos, slicelen);
-                pos += slicelen;
-
-                /* Append the rest of the old data (if any). */
-                slicelen = origlen - (doff + dlen);
-                if (slicelen > 0)
-                    System.arraycopy(foundDataBytes, doff + dlen, newData, pos,
-                                     slicelen);
+            if (data.getPartial() && foundDataBytes != null) {
+                newData = data.mergeInto(foundDataBytes, 0, foundDataBytes.length);
             } else {
                 int len = data.getSize();
                 if (len == 0) {
                     newData = LogUtils.ZERO_LENGTH_BYTE_ARRAY;
                 } else {
                     newData = new byte[len];
+                    System.arraycopy(data.getData(), data.getOffset(),
+                                     newData, 0, len);
                 }
-                System.arraycopy(data.getData(), data.getOffset(),
-                                 newData, 0, len);
             }

             if (databaseImpl.getSortedDuplicates()) {

You are right that it is a bug. Thank you for this comment! We will fix it in a future release.

In the meantime I suggest to work around this by using only not a partial DatabaseEntry for methods put (), when secondary are associated with the primary database.

Please note that using a partial DatabaseEntry for a method put () has the performance advantage very little and is very rarely used. This feature is included primarily for compatibility with the original edition of the BDB product C.

-mark

Tags: Database

Similar Questions

  • I sent a long text on my iPhone is and he went from English to Chinese characters.  Why did do that?

    I sent a long text on my iPhone is and he went from English to Chinese characters.  Why did do that?

    SSounds as a possible coding glitch, msg is read as instead of UTF8 UTF16 may be.  Probably caused by the carrier.

  • I went from a Win7 32-bit on a 64-bit win7 machine computer. Now, I get "this connection is not approved" any solution? tried everything

    I went from a Win7 32-bit on a 64-bit win7 machine computer. Now, I get "this connection is not approved" on many pages, including support for Mozilla, Yahoo, send a mail to yahoo, etc. The only thing that has changed is my computer. Everything worked on the 32-bit system. I tried DELL-no-help, I tried Norton-no-help - I tried all published recommendations - nothing helped. Can someone give an explanation of how solve this incompatibility (presumed) Win7 64 bit computers? How can I quickly and absolutely get rid of MESSAGES "THIS CONNECTION IS UNTRUSTED"?
    Thanks for ANY help from an expert.

    Right after that I posted this problem it seemed the solution:
    I noticed a pop-up, named "BROWSERSAFEGUARD" who has attempted to set my computer to a "cleaner" for a price. I checked in my installed programs if there was a "Browsersafeguard" and he was there. I uninstalled it, check "incompatible with my system" and my computer turned on like never before. Lightning fast connections and no message more "this connection is not approved. Wow. It took me 7 days to find it. Hope this will help you, too. Send a message to this one to let me know if it solved your problem

  • Icons in the bar of the addon went from right to left

    Hello world

    I recently updated to the most recent 4b 10 of Firefox. I currently use the bar addon on the bottom which contains several related icons addon (like firebug, etc.). Those who work still, but for some reason some they went from the right side of the toolbar addon (where they have always been) left without apparent reason.
    I know that is a kind of small problem, but it's really disturbing, I look in the wrong corner after the icons it for so many years. Is there a way I can go back to that?

    Thank you!
    Diamond

    1. Right click on the module bar and select Customize.
    2. Drag the Flexible space of the Customize Toolbar dialog box icon and place it to the left of the icons in the bar of the modules.
    3. Click done
  • Entry value change when he went from teststand for labview.

    Hi all

    I try to spend my labview VI value hexadecimal teststand. When I run the VI independently giving the value as 00000010 I get the expected results of the VI.  But even when value is passed through local variable teststand, when it reached VI of entry it was conerted to 000000 A 0 and so I'm getting wrong output.

    I am not able to understand how the value goes to the value of the input parameter when she went from teststand for labview.

    Any ideas?

    I discovered the error.  I was entering the value in the wrong format in teststand... instead of 0 x 10 I've entered only 010 and was therefore is converted to A.

  • Recently went from Outlook Express to Windows Live Mail. Since that time I can't send/receive emails without this message popup Windows live mail ID error 0x800ccc78 Server Error 530.

    Recently went from Outlook Express to Windows Live Mail.  Since that time I can't send/receive emails without this message popup Windows live mail ID error 0x800ccc78 Server Error 530.

    You will need to ask here:

    Windows Live Mail Forum
    http://windowslivehelp.com/forums.aspx?ProductID=15

    And you need to display an error message in its entirety. You can left click on it to highlight then right click to copy and then paste in this thread. Just the number of code alone is not enough.

  • I went from internet providers and now when I try to send an email I get a message saying "undeliverable email".

    original title: cannot send emails

    I went from internet providers and now I can only receive emails but get the error message following "undeliverable email" when I send a.  This is the message that: 530 5.7.0 must issue a STARTTLS first command

    Don't know if you still need help...

    First of all, make sure you can access the internet.

    Means the way to websites like google.com, youtube.com, etc..

    Then make sure you can send an e-mail by mail to yourself.

    If you are unable to send an email to yourself, check the correct email typed in address.

    If it still does not work, you will need to contact your email provider.

  • Why my hard drive went from 70% of free space to 60% of the overnight?

    Computer laptop w/Vista Home Premium left overnight. Free space on hard drive (C OS) went from 70% to 60% the next morning. What happened and how can I fix?

    Thank you.

    Try treesize free http://www.jam-software.com/treesize_free/ to show you what fits in your car.

    I hope this helps.

  • the color went from Windows Vista how I get it back

    the color went from Windows Vista, but if I'm going to monitor the settings it shows color is available.  How to vista windows, rather than black and white the color back?

    Hello

    1. don't you make changes on the computer before the issue started?
    2. What is the brand and model of your monitor?
    3. What is the brand and model of your graphics card?

    Perform a system restore to restore the computer to an earlier point in time before the problem started.

    See these articles for help:
    http://Windows.Microsoft.com/en-us/Windows-Vista/what-is-system-restore
    http://Windows.Microsoft.com/en-us/Windows-Vista/system-restore-frequently-asked-questions

  • The display of my office went from vertical to horozontal

    Original title: ' ideas: insert an error code or give a brief description of what you're trying to accomplish or difficulty. " __ »

    The display of my office went from vertical to horozontal. How can I fix it

    Try to press Ctrl + Alt + up ARROW, or try Ctrl + Alt + and a different key to the arrow.

    If this does not work: right click on the empty desk > graphics > Rotation.

    See you soon.

    Mick Murphy - Microsoft partner

  • I have an account but cannot modify/use the tools.  I went from computers a week ago.  Help, please.

    I have an account but cannot modify/use the tools.  I went from computers a week ago.  Help, please.

    It should not, but you will need to download the right software to use. Adobe Acrobat Reader is what you are currently using. This is why you don't have the tools you are used to.

    Adobe Acrobat (not Reader), that's what you signed up for. He has the tools, you need and are a completely different, even if application you may have initially subscribed by using Adobe Acrobat Reader.

  • How can I move photos from one date to another in my catalog? Downloaded LR of photos taken over several days to a date. LR6 PC Win7

    How can I move photos from one date to another in my catalog? Downloaded LR of photos taken over several days to a date. LR6 Win7 PC.

    Hi bubba43,

    Please select the images in the library grid mode Module and then drag and drop them in another folder you want.

    Kind regards

    Tanuj

  • Move the VM from one data center to another domain controller

    Hi all

    I have a machine virtual Windows 2008 R2 64-bit with 2 GB of 32 disks each and I need to migrate from one data center to another data center. Everything can agree with the approach on this movement of server? Thanks in advance.

    Summary: -.

    Source VC1-VM

    Target the VC2:-need to migrate to VC2

    Thank you

    vm2014

    As you move between two different vCenters, you can export the VM as OVF and then import them into the second vCenter.

  • Local data store has disappeared from the data store window (necessary emergency aid)

    Dear team,

    I m facing a very strange problem, all of a sudden one of the local ESX datastore disappeared thereafter are full details we have encountered/noticed.

    A local data store disappeared from the data store window.able to see this data store to add storage Wizard, which allows us to format the same.

    * If we take a session putty from here we can see and browse this store of data without problem.

    * Virtual computers that are running on this data store work as well (all files are accessible / VM is accessible on the network)

    * Unable to take backup image do error "the object has already been deleted or was not completely created.

    * Not able to take a «cannot complete the copy file... network» clone »

    Getting from newspapers in vmkernel:

    (14 dec 17:11:39 localhost vmkernel: 0:01:55:28.677 cpu1:4097) ScsiDeviceIO: 747: command 0 x 28-the device 'mpx.vmhba1:C0:T1:L0' failed, the data of sense H:0 x D:0 x 2 P:0 x 0 0 valid: 0 x 4 0 44 x 0 x 0.

    (14 dec 17:11:39 localhost vmkernel: 0:01:55:28.677 cpu1:4097) ScsiDeviceToken: 293: Sync IO 0 x 28-the device 'mpx.vmhba1:C0:T1:L0' failed: error/o H:0 x D:0 x P:0 x 0 2 0 valid sense data: 0x4 0 44 x 0 x 0.

    (14 dec 17:11:39 localhost vmkernel: 0:01:55:28.677 cpu6:4110) capability3: 5354: Sync READ error ('. fbb.sf') (ioFlags: 8): i/o error

    Need your help urgently to solve the same.

    concerning

    Mr. VMware

    Dear all,

    We have enclosed a case at VMware, please find their findings on the same.

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    After the webex session, we just had, I discovered the root cause of the problem reported to an underlying problem on the block device (the logical drive, or a problem on the Board) presented to accommodate the data in question store successfully.

    In short, whenever we try to do raw reading from the disk (from sector 0), the same always fail when we reach the 30932992 bytes (31 MB) brand with an IO error (which is consistent, he is always on this region of the disc that read operations fail, no more, no less). This result can be seen, even if no partition is in the disk (using if = / dev/sdb instead of/dev/sdb1 with dd) and even after zeroing on all sectors (if dd \u003d/dev/zero of = / dev/sdb). Strangely, read operations work fine (as he writes zeros of random data) throughout the entire disk. Keep in mind that the tests I did with no VMware tools (I used almost only dd for these operations), which prohibits certainly a VMware problem (in fact, if you were to try to start the server with a Linux live CD and run the same tests that I did, you would see the same behavior).

    I know that there is no report of material of any bad behavior on the table, but data collected with our tests today completely invalid who. The next step is for you to take this to the server provider to check for problems on the table or discs, because they are there and they are the reason for the problem you reported initially.

    Please let me know if you have other questions about it.

    Thank you

    -

    David Meireles

    Technical Support Engineer

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Now we have blocked a case from the hardware vendor, to see what the next move will be.

    concerning

    Mr. VMware

  • Update of a column of table from xml data

    Hello

    I have an obligation to update a particular table from xml data column. to do this, I wrote the code below but I am not able to insert. could you please a peek into that.

    create table emp3
    as
    select *From emp
    where 1=1;
    
    alter table emp3
    add (fax_response varchar2(50));
    
    /*create sequence EmailRecords_XMLFILE_SEQ
      minvalue 1
      maxvalue 999999999999999999999999999
      start with 1
      increment by 1
      nocache;*/
    
    /* create global temporary table EmailRecords_XMLFILE
      (
      ID NUMBER not null,
      xmlfile CLOB
      )
      on commit preserve rows;*/
    
    /* create global temporary table UPD_Email_Records_With_Xml
      (
      id NUMBER not null,
    
      response VARCHAR2(500)
    
      )
      on commit preserve rows; */
    
    
    

    the XML data is

    <FAX>
    <EMAILOG>
    <ID>7839</ID>
    <RESPONSE>FAX SENT</RESPONSE>
    </EMAILOG>
    <EMAILOG>
    <ID>7566</ID>
    <RESPONSE>FAX NOT SENT</RESPONSE>
    </EMAILOG>
    </FAX>
    
    
    

    CREATE OR REPLACE PROCEDURE proc_upd_email_records (
       loc_xml          IN       CLOB,
       p_err_code_out   OUT      NUMBER,
       p_err_mesg_out   OUT      VARCHAR2
    )
    IS
       loc_id   NUMBER;
    BEGIN
       loc_id := emailrecords_xmlfile_seq.NEXTVAL; --created sequence
    
    
    
       INSERT INTO emailrecords_xmlfile --created Global Temp table
                   (ID, xmlfile
                   )
            VALUES (loc_id, loc_xml
                   );
    
       COMMIT;
          insert into UPD_Email_Records_With_Xml --created Global Temp table
            (ID, RESPONSE)
            select x1.id,
    
                      x1.RESPONSE
              from EmailRecords_XMLFILE,
                   xmltable('/FAX/EMAILOGID' passing
                            xmltype.createxml(EmailRecords_XMLFILE.xmlfile)
                            columns header_no for ordinality,
                            id number path 'ID',
                            RESPONSE VARCHAR2(250) path 'RESPONSE'
    
                               ) x1
             where EmailRecords_XMLFILE.id = loc_id;
       COMMIT;
    
       UPDATE emp3 er
          SET er.fax_response = (SELECT response
                               FROM upd_email_records_with_xml pr
                              WHERE pr.ID = er.empno)
        WHERE er.empno IN (SELECT ID
                             FROM upd_email_records_with_xml);
    EXCEPTION
       WHEN NO_DATA_FOUND
       THEN
          raise_application_error
             (-20000,
              'Sorry ! The Xml File which is passed is empty. Please try with Valid Xml File. Thank you!!! '
             );
       WHEN OTHERS
       THEN
          p_err_code_out := 4;
          p_err_mesg_out := 'error in insertion=> ' || SQLERRM;
    END proc_upd_email_records;
    {code}{code}
    
    
    

    Someone suggest me a slightly easier way to insert data...

    Thank you...

    You're complicating things

    A simple MERGE statement will do.

    create or replace procedure (proc_upd_email_records)

    loc_xml in clob

    )

    is

    Start

    merge into e emp3

    a_l'_aide_de)

    Select id

    response

    from xmltable)

    "/ FAX/EMAILOG.

    by the way xmlparse (document loc_xml)

    the columns id number way "ID".

    , path of varchar2 (250) response 'RESPONSE '.

    )

    ) v

    on (e.empno = v.id)

    When matched then update

    Set e.fax_response = v.response

    ;

    end;

    /

    But there is no value added by using these temporary tables if you are not at least an intermediate XMLType column (storage preferably binary XML).

    -What is the input XML code?

    -What is the version of db?

Maybe you are looking for