Added a history list. (from 0.2 beta 1)
Added a permanent location setting. (from 0.2 beta 1) Added SMS number setting. (from 0.2 beta 2) Added Movie Showtimes search otpion. Added Local Showtimes search option.
This commit is contained in:
parent
a2aa9fe4e1
commit
722ac10dcf
18 changed files with 1396 additions and 268 deletions
269
src/net/thauvin/j2me/googlme/RmsIndex.java
Normal file
269
src/net/thauvin/j2me/googlme/RmsIndex.java
Normal file
|
@ -0,0 +1,269 @@
|
|||
/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.thauvin.j2me.googlme;
|
||||
|
||||
import javax.microedition.rms.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* An Rms based BTree index. Currently, the functionality is similar to a
|
||||
* persistent hashtable.
|
||||
*/
|
||||
public class RmsIndex {
|
||||
|
||||
static byte[] DUMMY = new byte[0];
|
||||
|
||||
RecordStore store;
|
||||
|
||||
Node root;
|
||||
|
||||
int n = 32;
|
||||
|
||||
String cachedKey;
|
||||
|
||||
Node cachedNode;
|
||||
|
||||
int cachedIndex;
|
||||
|
||||
/** Node helper class */
|
||||
class Node {
|
||||
int index;
|
||||
|
||||
int size;
|
||||
|
||||
String[] keys = new String[n + n + 1];
|
||||
|
||||
String[] values = new String[n + n + 1];
|
||||
|
||||
int[] children = new int[n + n + 2];
|
||||
|
||||
/** Create a new Node */
|
||||
|
||||
Node() throws RecordStoreException {
|
||||
index = store.addRecord(DUMMY, 0, 0);
|
||||
}
|
||||
|
||||
Node(Node split) throws RecordStoreException {
|
||||
this();
|
||||
System.arraycopy(split.keys, n + 1, keys, 0, n);
|
||||
System.arraycopy(split.values, n + 1, values, 0, n);
|
||||
System.arraycopy(split.children, n + 1, children, 0, n + 1);
|
||||
size = n;
|
||||
split.size = n;
|
||||
split.store();
|
||||
store();
|
||||
}
|
||||
|
||||
/** Load the node at the given index position */
|
||||
|
||||
Node(int index) throws RecordStoreException {
|
||||
this.index = index;
|
||||
byte[] data = store.getRecord(index);
|
||||
|
||||
if (data == null || data.length == 0)
|
||||
return;
|
||||
|
||||
try {
|
||||
DataInputStream dis = new DataInputStream(
|
||||
new ByteArrayInputStream(data));
|
||||
|
||||
size = dis.readInt();
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
children[i] = dis.readInt();
|
||||
keys[i] = dis.readUTF();
|
||||
values[i] = dis.readUTF();
|
||||
}
|
||||
|
||||
children[size] = dis.readInt();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void put(String key, String value) throws RecordStoreException {
|
||||
|
||||
int i;
|
||||
for (i = 0; i < size; i++) {
|
||||
int cmp = key.compareTo(keys[i]);
|
||||
if (cmp == 0) {
|
||||
values[i] = value;
|
||||
store();
|
||||
return;
|
||||
} else if (cmp < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
int newIndex = 0;
|
||||
|
||||
if (children[i] != 0) {
|
||||
Node child = new Node(children[i]);
|
||||
child.put(key, value);
|
||||
|
||||
if (child.size < n + n + 1)
|
||||
return;
|
||||
|
||||
Node split = new Node(child);
|
||||
newIndex = split.index;
|
||||
|
||||
key = child.keys[n];
|
||||
value = child.values[n];
|
||||
}
|
||||
|
||||
System.arraycopy(keys, i, keys, i + 1, size - i);
|
||||
System.arraycopy(values, i, values, i + 1, size - i);
|
||||
System.arraycopy(children, i + 1, children, i + 2, size - i);
|
||||
|
||||
keys[i] = key;
|
||||
values[i] = value;
|
||||
children[i + 1] = newIndex;
|
||||
size++;
|
||||
|
||||
if (size < n + n + 1)
|
||||
// otherwise, store will be performed by uplink
|
||||
store();
|
||||
}
|
||||
|
||||
public void store() throws RecordStoreException {
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
DataOutputStream dos = new DataOutputStream(bos);
|
||||
dos.writeInt(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
dos.writeInt(children[i]);
|
||||
dos.writeUTF(keys[i]);
|
||||
dos.writeUTF(values[i]);
|
||||
}
|
||||
dos.writeInt(children[size]);
|
||||
byte[] data = bos.toByteArray();
|
||||
store.setRecord(index, data, 0, data.length);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new index with the given Name
|
||||
*/
|
||||
public RmsIndex(String name) throws RecordStoreException {
|
||||
|
||||
store = RecordStore.openRecordStore(name, true);
|
||||
root = store.getNumRecords() == 0 ? new Node() : new Node(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the given key
|
||||
*
|
||||
* @param key: The key
|
||||
* @return String: The value associated with the key, or null if none.
|
||||
* @throws RecordStoreException
|
||||
*/
|
||||
public String get(String key) throws RecordStoreException {
|
||||
|
||||
Node current = root;
|
||||
|
||||
while (true) {
|
||||
int i;
|
||||
for (i = 0; i < current.size; i++) {
|
||||
int cmp = key.compareTo(current.keys[i]);
|
||||
if (cmp == 0)
|
||||
return current.values[i];
|
||||
else if (cmp < 0)
|
||||
break;
|
||||
}
|
||||
if (current.children[i] == 0)
|
||||
return null;
|
||||
current = new Node(current.children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the given value to the given key persistently
|
||||
*
|
||||
* @param key: The key
|
||||
* @param value: The value
|
||||
* @throws RecordStoreException
|
||||
*/
|
||||
public void put(String key, String value) throws RecordStoreException {
|
||||
|
||||
root.put(key, value);
|
||||
if (root.size < n + n + 1)
|
||||
return;
|
||||
|
||||
// split root....
|
||||
|
||||
Node left = root;
|
||||
root = new Node();
|
||||
|
||||
left.index = root.index;
|
||||
root.index = 1;
|
||||
|
||||
Node right = new Node(left);
|
||||
|
||||
root.keys[0] = left.keys[n];
|
||||
root.values[0] = left.values[n];
|
||||
root.children[0] = left.index;
|
||||
root.children[1] = right.index;
|
||||
root.size = 1;
|
||||
root.store();
|
||||
}
|
||||
|
||||
public void close() throws RecordStoreException {
|
||||
store.closeRecordStore();
|
||||
}
|
||||
|
||||
public int size() throws RecordStoreException {
|
||||
|
||||
Node current = root;
|
||||
|
||||
return current.size;
|
||||
|
||||
}
|
||||
|
||||
public String get(int recordNum) throws RecordStoreException {
|
||||
|
||||
Node current = root;
|
||||
|
||||
return current.values[recordNum];
|
||||
|
||||
}
|
||||
|
||||
public String getKey(int recordNum) throws RecordStoreException {
|
||||
|
||||
Node current = root;
|
||||
|
||||
return current.keys[recordNum];
|
||||
|
||||
}
|
||||
|
||||
public void deleteAll(String name) throws RecordStoreException {
|
||||
|
||||
store.closeRecordStore();
|
||||
RecordStore.deleteRecordStore(name);
|
||||
store = RecordStore.openRecordStore(name, true);
|
||||
root = store.getNumRecords() == 0 ? new Node() : new Node(1);
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue