Rev 4167 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2012.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 or
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
package uk.me.parabola.imgfmt.app.mdr;
import java.text.Collator;
import java.util.ArrayList;
import java.util.List;
import uk.me.parabola.imgfmt.Utils;
import uk.me.parabola.imgfmt.app.ImgFileWriter;
import uk.me.parabola.imgfmt.app.srt.Sort;
import uk.me.parabola.imgfmt.app.srt.Sort.SrtCollator;
/**
* Holds an index of name prefixes to record numbers.
*
* Extends MdrSection, although is sometimes a subsection, not an actual section.
*
* @author Steve Ratcliffe
*/
public class PrefixIndex
extends MdrSection
{
private final int prefixLength
;
private int maxIndex
;
// We use mdr8record for all similar indexes.
private final List<Mdr8Record
> index =
new ArrayList<>();
/**
* Sets the config and the prefix length for this index.
*
* Prefix length may differ depending on the amount of data, so will have
* to deal with that when it happens.
*
* @param config Configuration for sorting methods.
* @param prefixLength The prefix length for this index.
*/
public PrefixIndex
(MdrConfig config,
int prefixLength
) {
setConfig
(config
);
this.
prefixLength = prefixLength
;
}
/**
* We can create an index for any type that has a name.
* @param list A list of items that have a name.
* @param grouped used with MDR7 records
*/
public void createFromList
(List<? extends NamedRecord
> list,
boolean grouped
) {
maxIndex = list.
size();
// Prefixes are equal based on the primary unaccented character, so
// we need to use the collator to test for equality and not equals().
Sort sort = getConfig
().
getSort();
Sort.
SrtCollator collator =
(SrtCollator
) sort.
getCollator();
collator.
setStrength(Collator.
PRIMARY);
String lastCountryName =
null;
char[] lastPrefix =
"".
toCharArray();
int inRecord =
0; // record number of the input list
int outRecord =
0; // record number of the index
int lastMdr22SortPos = -
1;
for (NamedRecord r : list
) {
inRecord++
;
String name
;
if (r
instanceof Mdr7Record
) {
name =
((Mdr7Record
) r
).
getPartialName();
if (grouped
) {
int mdr22SortPos =
((Mdr7Record
) r
).
getCity().
getMdr22SortPos();
if (mdr22SortPos
!= lastMdr22SortPos
)
lastPrefix =
"".
toCharArray();
lastMdr22SortPos = mdr22SortPos
;
}
}
else
name = r.
getName();
char[] prefix = sort.
getPrefix(name, prefixLength
);
int cmp = collator.
compareOneStrengthWithLength(prefix, lastPrefix,
Collator.
PRIMARY, prefixLength
);
if (cmp
> 0) {
outRecord++
;
index.
add(new Mdr8Record
(prefix, inRecord
));
lastPrefix = prefix
;
if (grouped
) {
// Peek into the real type to support the mdr17 feature of indexes sorted on country.
Mdr5Record city =
((Mdr7Record
) r
).
getCity();
if (city
!=
null) {
String countryName = city.
getCountryName();
if (!countryName.
equals(lastCountryName
)) {
city.
getMdrCountry().
getMdr29().
setMdr17(outRecord
);
lastCountryName = countryName
;
}
}
}
}
}
}
/**
* We can create an index for any type that has a name.
* @param list A list of items that have a name.
*/
public void createFromList
(List<? extends NamedRecord
> list
) {
createFromList
(list,
false);
}
/**
* Write the section or subsection.
*/
public void writeSectData
(ImgFileWriter writer
) {
int size = Utils.
numberToPointerSize(maxIndex
);
for (Mdr8Record s : index
) {
for (int i =
0; i
< prefixLength
; i++
) {
writer.
put1u(s.
getPrefix()[i
]);
}
writer.
putNu(size, s.
getRecordNumber());
}
}
public int getItemSize
() {
return prefixLength + Utils.
numberToPointerSize(maxIndex
);
}
protected int numberOfItems
() {
return index.
size();
}
public int getPrefixLength
() {
return prefixLength
;
}
}