• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/db-4.8.30/java/src/com/sleepycat/persist/impl/
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2002-2009 Oracle.  All rights reserved.
5 *
6 * $Id$
7 */
8
9package com.sleepycat.persist.impl;
10
11import java.io.Serializable;
12import java.util.Comparator;
13import java.util.HashMap;
14import java.util.Map;
15
16/**
17 * The btree comparator for persistent key classes.  The serialized form of
18 * this comparator is stored in the BDB JE database descriptor so that the
19 * comparator can be re-created during recovery.
20 *
21 * @author Mark Hayes
22 */
23public class PersistComparator implements Comparator<byte[]>, Serializable {
24
25    private static final long serialVersionUID = 5221576538843355317L;
26
27    private String keyClassName;
28    private String[] comositeFieldOrder;
29    private Map<String, String[]> fieldFormatData;
30    private transient PersistKeyBinding binding;
31
32    public PersistComparator(PersistKeyBinding binding) {
33        this.binding = binding;
34        /* Save info necessary to recreate binding during deserialization. */
35        final CompositeKeyFormat format =
36            (CompositeKeyFormat) binding.keyFormat;
37        keyClassName = format.getClassName();
38        comositeFieldOrder = CompositeKeyFormat.getFieldNameArray
39            (format.getClassMetadata().getCompositeKeyFields());
40        /* Currently only enum formats have per-class data. */
41        for (FieldInfo field : format.getFieldInfo()) {
42            Format fieldFormat = field.getType();
43            if (fieldFormat.isEnum()) {
44                EnumFormat enumFormat = (EnumFormat) fieldFormat;
45                if (fieldFormatData == null) {
46                    fieldFormatData = new HashMap<String, String[]>();
47                }
48                fieldFormatData.put(enumFormat.getClassName(),
49                                    enumFormat.getFormatData());
50            }
51        }
52    }
53
54    public int compare(byte[] b1, byte[] b2) {
55
56        /*
57         * The binding will be null after the comparator is deserialized, i.e.,
58         * during BDB JE recovery.  We must construct it here, without access
59         * to the stored catalog since recovery is not complete.
60         */
61        if (binding == null) {
62            Catalog catalog = SimpleCatalog.getInstance();
63            Map<String, Format> enumFormats = null;
64            if (fieldFormatData != null) {
65                enumFormats = new HashMap<String, Format>();
66                for (Map.Entry<String, String[]> entry :
67                     fieldFormatData.entrySet()) {
68                    final String fldClassName = entry.getKey();
69                    final String[] enumNames = entry.getValue();
70                    final Class fldClass;
71                    try {
72                        fldClass = SimpleCatalog.classForName(fldClassName);
73                    } catch (ClassNotFoundException e) {
74                        throw new IllegalStateException(e);
75                    }
76                    enumFormats.put(fldClassName,
77                                    new EnumFormat(fldClass, enumNames));
78                }
79                catalog = new ComparatorCatalog(enumFormats);
80                for (Format fldFormat : enumFormats.values()) {
81                    fldFormat.initializeIfNeeded(catalog, null /*model*/);
82                }
83            }
84            final Class keyClass;
85            try {
86                keyClass = SimpleCatalog.classForName(keyClassName);
87            } catch (ClassNotFoundException e) {
88                throw new IllegalStateException(e);
89            }
90            binding = new PersistKeyBinding(catalog, keyClass,
91                                            comositeFieldOrder);
92        }
93
94        Comparable k1 = (Comparable) binding.bytesToObject(b1, 0, b1.length);
95        Comparable k2 = (Comparable) binding.bytesToObject(b2, 0, b2.length);
96
97        return k1.compareTo(k2);
98    }
99
100    @Override
101    public String toString() {
102        StringBuilder b = new StringBuilder();
103        b.append("[DPL comparator ");
104        b.append(" keyClassName = ").append(keyClassName);
105        b.append(" comositeFieldOrder = [");
106        for (String s : comositeFieldOrder) {
107            b.append(s).append(',');
108        }
109        b.append(']');
110        b.append(" fieldFormatData = {");
111        for (Map.Entry<String, String[]> entry : fieldFormatData.entrySet()) {
112            b.append(entry.getKey()).append(": [");
113            for (String s : entry.getValue()) {
114                b.append(s).append(',');
115            }
116            b.append(']');
117        }
118        b.append('}');
119        b.append(']');
120        return b.toString();
121    }
122}
123