📄 versionedstorage.java
字号:
}
} else if (curr instanceof VersionHistory) {
currHistory = ((VersionHistory)curr).versions;
currVersion = 0;
continue Repeat;
}
}
currThing = null;
return;
}
}
private static boolean matchString(String str, String pat) {
if (pat.indexOf('*') < 0) {
return pat.equals(str);
}
int pi = 0, si = 0, pn = pat.length(), sn = str.length();
int wildcard = -1, strpos = -1;
while (true) {
if (pi < pn && pat.charAt(pi) == '*') {
wildcard = ++pi;
strpos = si;
} else if (si == sn) {
return pi == pn;
} else if (pi < pn && str.charAt(si) == pat.charAt(pi)) {
si += 1;
pi += 1;
} else if (wildcard >= 0) {
si = ++strpos;
pi = wildcard;
} else {
return false;
}
}
}
private boolean match(Thing thing) {
if (type != null && !thing.isInstanceOf(type, kind, timestamp)) {
return false;
}
if (kind == SearchKind.LatestVersion) {
if (!thing.isLatest()) {
return false;
}
} else if (kind == SearchKind.LatestBefore) {
if (thing.timestamp.compareTo(timestamp) > 0 || thing.vh.getLatestBefore(timestamp) != thing) {
return false;
}
} else if (kind == SearchKind.OldestAfter) {
if (thing.timestamp.compareTo(timestamp) < 0 || thing.vh.getOldestAfter(timestamp) != thing) {
return false;
}
}
if (uri != null) {
if (!matchString(thing.vh.uri, uri)) {
return false;
}
}
for (int i = 0; i < patterns.length; i++) {
if (!matchProperty(patterns[i], thing)) {
return false;
}
}
currThing = thing;
return true;
}
private boolean matchProperty(NameVal prop, Thing thing) {
if (Symbols.Point.equals(prop.name)) {
if (prop.val instanceof NameVal[]) {
NameVal[] coord = (NameVal[])prop.val;
if (coord.length == 2) {
double x = ((Number)coord[0].val).doubleValue();
double y = ((Number)coord[1].val).doubleValue();
RectangleR2 r = new RectangleR2(x, y, x, y);
Iterator i = root.spatialIndex.iterator(r);
while (i.hasNext()) {
if (i.next() == thing) {
return true;
}
}
return false;
}
}
} else if (Symbols.Rectangle.equals(prop.name)) {
if (prop.val instanceof NameVal[]) {
NameVal[] coord = (NameVal[])prop.val;
if (coord.length == 4) {
RectangleR2 r = new RectangleR2(((Number)coord[0].val).doubleValue(),
((Number)coord[1].val).doubleValue(),
((Number)coord[2].val).doubleValue(),
((Number)coord[3].val).doubleValue());
Iterator i = root.spatialIndex.iterator(r);
while (i.hasNext()) {
if (i.next() == thing) {
return true;
}
}
return false;
}
}
} else if (Symbols.Keyword.equals(prop.name)) {
if (prop.val instanceof String) {
HashSet allKeywords = new HashSet();
for (int i = 0; i < thing.props.length; i++) {
PropVal pv = thing.props[i];
Object val = pv.val;
if (val instanceof String) {
ArrayList keywords = getKeywords((String)val);
allKeywords.addAll(keywords);
}
}
ArrayList keywords = getKeywords((String)prop.val);
return allKeywords.containsAll(keywords);
}
}
Object[] propVal = thing.get(prop.name);
NextItem:
for (int i = 0; i < propVal.length; i++) {
Object val = propVal[i];
Object pattern = prop.val;
if (val instanceof String && pattern instanceof String) {
if (matchString((String)val, (String)pattern)) {
return true;
}
} else if (pattern instanceof NameVal) {
if (val instanceof VersionHistory
&& followReference((NameVal)pattern, (VersionHistory)val))
{
return true;
}
} else if (pattern instanceof NameVal[]) {
if (val instanceof VersionHistory) {
NameVal[] arr = (NameVal[])prop.val;
for (int j = 0; j < arr.length; j++) {
if (!followReference(arr[j], (VersionHistory)val)){
continue NextItem;
}
}
return true;
}
} else if (pattern instanceof Range && val instanceof Comparable) {
try {
Range range = (Range)pattern;
Comparable cmp = (Comparable)val;
return cmp.compareTo(range.from) >= (range.fromInclusive ? 0 : 1) &&
cmp.compareTo(range.till) <= (range.tillInclusive ? 0 : -1);
} catch (ClassCastException x) {}
} else if (pattern != null && pattern.equals(val)) {
return true;
}
}
return false;
}
private boolean followReference(NameVal prop, VersionHistory vh) {
if (vh != null) {
if (kind == SearchKind.AllVersions) {
for (int i = 0, n = vh.versions.size(); i < n; i++) {
Thing v = (Thing)vh.versions.get(i);
if (matchProperty(prop, v)) {
return true;
}
}
} else {
Thing thing = vh.getVersion(kind, timestamp);
return thing != null && matchProperty(prop, thing);
}
}
return false;
}
}
private void createMetaType() {
VersionHistory vh = createVersionHistory(Symbols.Metatype, null);
vh.type = vh;
Thing metatype = createObject(null, vh, new NameVal[0]);
metatype.type = metatype;
root.metatype = vh;
}
private static String reverseString(String s) {
int len = s.length();
char[] chars = new char[len];
for (int i = 0; i < len; i++) {
chars[i] = s.charAt(len-i-1);
}
return new String(chars);
}
private VersionHistory createVersionHistory(String uri, VersionHistory type) {
VersionHistory vh = new VersionHistory();
vh.uri = uri;
vh.type = type;
vh.versions = db.createLink();
root.prefixUriIndex.put(uri, vh);
root.suffixUriIndex.put(reverseString(uri), vh);
return vh;
}
private static NameVal[] subArray(NameVal[] arr) {
NameVal[] newArr = new NameVal[arr.length-1];
System.arraycopy(arr, 1, newArr, 0, newArr.length);
return newArr;
}
private Thing createObject(Thing type, VersionHistory vh, NameVal[] props) {
Thing thing = new Thing();
thing.vh = vh;
thing.type = type;
thing.timestamp = new Date();
thing.props = new PropVal[props.length];
for (int i = 0; i < props.length; i++) {
thing.props[i] = new PropVal();
}
for (int i = 0; i < props.length; i++) {
NameVal prop = props[i];
PropDef def = (PropDef)root.propDefIndex.get(prop.name);
if (def == null) {
def = new PropDef();
def.name = prop.name;
root.propDefIndex.put(def);
}
Object val = prop.val;
PropVal pv = thing.props[i];
pv.def = def;
pv.val = val;
Key key = new Key(new Object[]{def, val});
if (val instanceof String) {
root.strPropIndex.put(key, thing);
ArrayList keywords = getKeywords((String)val);
for (int j = keywords.size(); --j >= 0;) {
root.inverseIndex.put((String)keywords.get(j), thing);
}
} else if (val instanceof Number) {
root.numPropIndex.put(key, thing);
} else if (val instanceof Date) {
root.timePropIndex.put(key, thing);
} else if (val instanceof VersionHistory || val == null) {
root.refPropIndex.put(key, thing);
if (Symbols.Rectangle.equals(prop.name)) {
PropVal[] coord = ((VersionHistory)val).getLatest().props;
RectangleR2 r = new RectangleR2(((Number)coord[0].val).doubleValue(),
((Number)coord[1].val).doubleValue(),
((Number)coord[2].val).doubleValue(),
((Number)coord[3].val).doubleValue());
root.spatialIndex.put(r, thing);
} else if (Symbols.Rectangle.equals(prop.name)) {
PropVal[] coord = ((VersionHistory)val).getLatest().props;
double x = ((Number)coord[0].val).doubleValue();
double y = ((Number)coord[1].val).doubleValue();
RectangleR2 r = new RectangleR2(x, y, x, y);
root.spatialIndex.put(r, thing);
}
} else {
throw new IllegalArgumentException("Invalid propery value type " + prop.val.getClass());
}
}
thing.modify();
vh.versions.add(thing);
root.timeIndex.put(thing);
root.latest.add(thing);
return thing;
}
private static ArrayList getKeywords(String str) {
ArrayList list = new ArrayList();
char[] separators = keywordSeparators;
str = str.toLowerCase();
int len = str.length();
int p = 0;
do {
int minNp = len;
for (int i = 0; i < separators.length; i++) {
int np = str.indexOf(separators[i], p);
if (np >= 0 && np < minNp) {
minNp = np;
}
}
if (minNp-p > 1) {
String keyword = str.substring(p, minNp);
if (!keywordStopList.contains(keyword)) {
list.add(keyword);
}
}
p = minNp + 1;
} while (p < len);
return list;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -