1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2002,2008 Oracle.  All rights reserved.
5 *
6 * $Id: PersistComparator.java,v 1.1 2008/02/07 17:12:27 mark Exp $
7 */
8
9package com.sleepycat.persist.impl;
10
11import java.io.Serializable;
12import java.util.Comparator;
13import java.util.List;
14
15import com.sleepycat.persist.model.FieldMetadata;
16
17/**
18 * The btree comparator for persistent key classes.  The serialized form of
19 * this comparator is stored in the BDB JE database descriptor so that the
20 * comparator can be re-created during recovery.
21 *
22 * @author Mark Hayes
23 */
24public class PersistComparator implements Comparator<Object>, Serializable {
25
26    private static final long serialVersionUID = 5221576538843355317L;
27
28    private String keyClassName;
29    private String[] comositeFieldOrder;
30    private transient PersistKeyBinding binding;
31
32    public PersistComparator(String keyClassName,
33                             List<FieldMetadata> compositeKeyFields,
34                             PersistKeyBinding binding) {
35        this.keyClassName = keyClassName;
36        this.binding = binding;
37
38        if (compositeKeyFields != null) {
39            comositeFieldOrder =
40                CompositeKeyFormat.getFieldNameArray(compositeKeyFields);
41        }
42    }
43
44    public int compare(Object o1, Object o2) {
45
46        /*
47         * The binding will be null after the comparator is deserialized, i.e.,
48         * during BDB JE recovery.  We must construct it here, without access
49         * to the stored catalog since recovery is not complete.
50         */
51        if (binding == null) {
52            Class keyClass;
53            try {
54                keyClass = SimpleCatalog.classForName(keyClassName);
55            } catch (ClassNotFoundException e) {
56                throw new IllegalStateException(e);
57            }
58            binding = new PersistKeyBinding(keyClass, comositeFieldOrder);
59        }
60
61        byte[] b1 = (byte[]) o1;
62        byte[] b2 = (byte[]) o2;
63
64        Comparable k1 = (Comparable) binding.bytesToObject(b1, 0, b1.length);
65        Comparable k2 = (Comparable) binding.bytesToObject(b2, 0, b2.length);
66
67        return k1.compareTo(k2);
68    }
69}
70