1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.core.partition.impl.btree.mavibot;
21
22
23 import java.io.DataInputStream;
24 import java.io.DataOutputStream;
25 import java.io.IOException;
26 import java.io.RandomAccessFile;
27 import java.nio.charset.StandardCharsets;
28
29 import org.apache.directory.api.ldap.model.entry.DefaultEntry;
30 import org.apache.directory.api.ldap.model.entry.Entry;
31 import org.apache.directory.api.ldap.model.ldif.LdifEntry;
32 import org.apache.directory.api.ldap.model.ldif.LdifReader;
33 import org.apache.directory.api.ldap.model.name.Dn;
34 import org.apache.directory.api.ldap.model.schema.SchemaManager;
35 import org.apache.directory.mavibot.btree.Tuple;
36 import org.apache.directory.mavibot.btree.util.TupleReaderWriter;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40
41
42
43
44
45
46 public class LdifTupleReaderWriter<E> implements TupleReaderWriter<Dn, E>
47 {
48
49 private LdifReader reader = null;
50
51 private static final Logger LOG = LoggerFactory.getLogger( LdifTupleReaderWriter.class );
52
53 private String ldifFile;
54
55 private RandomAccessFile raf;
56
57 private SchemaManager schemaManager;
58
59 public LdifTupleReaderWriter( String ldifFile, SchemaManager schemaManager )
60 {
61 this.ldifFile = ldifFile;
62 this.schemaManager = schemaManager;
63
64 try
65 {
66 raf = new RandomAccessFile( ldifFile, "r" );
67 }
68 catch ( Exception e )
69 {
70 throw new RuntimeException( e );
71 }
72 }
73
74
75 @Override
76 public Tuple<Dn, E> readSortedTuple( DataInputStream in )
77 {
78 try
79 {
80 if ( in.available() > 0 )
81 {
82 Tuple<Dn, E> tuple = new Tuple<>();
83 tuple.setKey( new Dn( in.readUTF() ) );
84
85 String[] tokens = in.readUTF().split( ":" );
86
87 long offset = Long.parseLong( tokens[0] );
88
89 int length = Integer.parseInt( tokens[1] );
90
91 raf.seek( offset );
92
93 byte[] data = new byte[length];
94
95 raf.read( data, 0, length );
96
97 try ( LdifReader ldifReader = new LdifReader() )
98 {
99 LdifEntry ldifEntry = ldifReader.parseLdif( new String( data, StandardCharsets.UTF_8 ) ).get( 0 );
100 Entry entry = new DefaultEntry( schemaManager, ldifEntry.getEntry() );
101
102 tuple.setValue( ( E ) entry );
103 }
104
105 return tuple;
106 }
107 }
108 catch ( Exception e )
109 {
110 LOG.error( "Failed to read a sorted tuple", e );
111 }
112
113 return null;
114 }
115
116
117 @Override
118 public Tuple<Dn, E> readUnsortedTuple( DataInputStream in )
119 {
120 try
121 {
122 if ( reader == null )
123 {
124 reader = new LdifReader( in );
125 }
126 }
127 catch ( Exception e )
128 {
129 String msg = "Failed to open the LDIF input stream";
130 LOG.error( msg, e );
131
132 throw new RuntimeException( msg, e );
133 }
134
135 Tuple<Dn, E> t = null;
136
137 if ( reader.hasNext() )
138 {
139 LdifEntry ldifEntry = reader.next();
140
141 if ( ldifEntry == null )
142 {
143 throw new IllegalStateException(
144 "Received null entry while parsing, check the LDIF file for possible incorrect/corrupted entries" );
145 }
146
147 t = new Tuple<>();
148
149 t.setKey( ldifEntry.getDn() );
150 t.setValue( ( E ) ( ldifEntry.getOffset() + ":" + ldifEntry.getLengthBeforeParsing() ) );
151 }
152
153 return t;
154 }
155
156
157 @Override
158 public void storeSortedTuple( Tuple<Dn, E> t, DataOutputStream out ) throws IOException
159 {
160 out.writeUTF( t.getKey().getName() );
161 out.writeUTF( ( String ) t.getValue() );
162 }
163
164 }