All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sleepycat.je.rep.util.ldiff.LDiffUtil Maven / Gradle / Ivy

The newest version!
/*-
 * Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle Berkeley
 * DB Java Edition made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle Berkeley DB Java Edition for a copy of the
 * license and additional information.
 */

package com.sleepycat.je.rep.util.ldiff;

import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import com.sleepycat.je.Cursor;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.EnvironmentLockedException;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;
import com.sleepycat.je.utilint.Adler32;

public class LDiffUtil {

    /* Convenient masking constant. */
    final static long MASK_32BIT = 0xffffffffl;

    /* To compute a MD5 hash for each block. */
    static MessageDigest md = null;
    static {
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    /* Concatenate two byte arrays into one. */
    public static byte[] concatByteArray(byte[] a, byte[] b) {
        if ((a == null) || (b == null)) {
            return (a == null) ? b : a;
        }

        int len = a.length + b.length;
        byte[] dest = new byte[len];
        /* Copy the content of a to dest. */
        System.arraycopy(a, 0, dest, 0, a.length);
        /* Copy the content from b to the remaining part of dest. */
        System.arraycopy(b, 0, dest, a.length, b.length);

        return dest;
    }

    /**
     * Each byte (Xi in the tech report) is replaced by a 32 bit Adler checksum
     * of the bytes representing the concatenation of the key/value pair.
     * 
     * @return the checksum
     */
    public static int getXi(byte[] keyValue) {
        Adler32 adler32 = new Adler32();
        adler32.update(keyValue, 0, keyValue.length);
        return (int) adler32.getValue();
    }

    public static Block readBlock(int blockId, Cursor cursor, int numKeys)
        throws DatabaseException {

        /* DatabaseEntry represents the key and data of each record. */
        DatabaseEntry key = new DatabaseEntry();
        DatabaseEntry data = new DatabaseEntry();
        /* Adler32 to compute the rolling checksum of key/data pair. */
        Adler32 adler32 = new Adler32();
        int i = 0;
        int a = 0, b = 0;
        md.reset();
        Block block = new Block(blockId);

        /* Please pay attention to the check order in while loop. */
        while ((i < numKeys) &&
               (cursor.getNext(key, data, LockMode.DEFAULT) ==
                OperationStatus.SUCCESS)) {
            /* Indicates having a new block. */
            if (i == 0) {
                block.setBeginKey(key.getData());
                block.setBeginData(data.getData());
            }

            /* Calculate rollingChksum on "key|data" bytes. */
            adler32.reset();
            adler32.update(key.getData(), 0, key.getData().length);
            adler32.update(data.getData(), 0, data.getData().length);
            final int xi = (int) adler32.getValue();
            a += xi;
            b += a;
            /* Update MessageDigest with "key|data" bytes. */
            md.update(key.getData());
            md.update(data.getData());
            i++;
        }

        /* Allocate a block and return. */
        long cksum = (a & LDiffUtil.MASK_32BIT) | ((long) b << 32);
        block.setRollingChksum(cksum);
        block.setMd5Hash(md.digest());
        block.setNumRecords(i);
        return block;
    }

    public static Environment openEnv(String envDir) {
        /* Open the database environment. */
        EnvironmentConfig envConfig = new EnvironmentConfig();
        /* envConfig.setTransactional(false); */
        envConfig.setAllowCreate(false);
        envConfig.setReadOnly(true);
        try {
            return new Environment(new File(envDir), envConfig);
        } catch (EnvironmentLockedException e) {
            e.printStackTrace();
        } catch (DatabaseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Database openDb(Environment env, String dbName) {

        /* Open the remote database within that environment. */
        DatabaseConfig dbConfig = new DatabaseConfig();
        /* dbConfig.setTransactional(false); */
        dbConfig.setAllowCreate(false);
        dbConfig.setReadOnly(true);
        dbConfig.setSortedDuplicates(true);
        try {
            return env.openDatabase(null, dbName, dbConfig);
        } catch (DatabaseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void close(Environment env, Database db) {
        if (db != null) {
            try {
                db.close();
            } catch (DatabaseException e) {
                e.printStackTrace();
            }
        }
        if (env != null) {
            try {
                env.close();
            } catch (DatabaseException e) {
                e.printStackTrace();
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy