Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add FindFrom for slicing indexes

  • Loading branch information...
commit 5c342becb75afab5fd74ad225811c6a3849caf7b 1 parent a6c14dd
@brendonh authored
View
10 src/loge/database.go
@@ -108,11 +108,11 @@ func (db *LogeDB) Transact(actor Transactor, timeout time.Duration) bool {
}
func (db *LogeDB) Find(typeName string, linkName string, target LogeKey) ResultSet {
- typ, ok := db.types[typeName]
- if !ok {
- panic(fmt.Sprintf("Type does not exist: %s", typeName))
- }
- return db.store.find(typ, linkName, target)
+ return db.store.find(db.types[typeName], linkName, target)
+}
+
+func (db *LogeDB) FindFrom(typeName string, linkName string, target LogeKey, from LogeKey, limit int) ResultSet {
+ return db.store.findFrom(db.types[typeName], linkName, target, from, limit)
}
View
50 src/loge/leveldb.go
@@ -39,6 +39,8 @@ type levelDBResultSet struct {
it *prefixIterator
prefixLen int
next string
+ limit int
+ count int
closed bool
}
@@ -197,7 +199,11 @@ func (store *levelDBStore) storeLinks(obj *logeObject) error {
// -----------------------------------------------
func (store *levelDBStore) find(typ *logeType, linkName string, key LogeKey) ResultSet {
- return ldb_find(store, defaultReadOptions, typ, linkName, key)
+ return ldb_find(store, defaultReadOptions, typ, linkName, key, "", -1)
+}
+
+func (store *levelDBStore) findFrom(typ *logeType, linkName string, key LogeKey, from LogeKey, limit int) ResultSet {
+ return ldb_find(store, defaultReadOptions, typ, linkName, key, from, limit)
}
func (rs *levelDBResultSet) Valid() bool {
@@ -210,11 +216,17 @@ func (rs *levelDBResultSet) Next() LogeKey {
}
var next = rs.next
rs.it.Next()
+ rs.count++
+
if rs.it.Valid() {
rs.next = string(rs.it.Key()[rs.prefixLen:])
+ if rs.limit >= 0 && rs.count >= rs.limit {
+ rs.Close()
+ }
} else {
rs.Close()
- }
+ }
+
return LogeKey(next)
}
@@ -289,6 +301,7 @@ func (context *levelDBContext) rollback() {
func (context *levelDBContext) cleanup() {
context.ldbStore.db.ReleaseSnapshot(context.snapshot)
+ context.readOptions.Close()
}
func (context *levelDBContext) Write() error {
@@ -314,7 +327,11 @@ func (context *levelDBContext) storeLinks(obj *logeObject) error {
}
func (context *levelDBContext) find(typ *logeType, linkName string, target LogeKey) ResultSet {
- return ldb_find(context.ldbStore, context.readOptions, typ, linkName, target)
+ return ldb_find(context.ldbStore, context.readOptions, typ, linkName, target, "", -1)
+}
+
+func (context *levelDBContext) findFrom(typ *logeType, linkName string, key LogeKey, from LogeKey, limit int) ResultSet {
+ return ldb_find(context.ldbStore, context.readOptions, typ, linkName, key, from, limit)
}
func (context *levelDBContext) get(typ *logeType, key LogeKey) interface{} {
@@ -332,7 +349,7 @@ func (context *levelDBContext) getLinks(typ *logeType, linkName string, key Loge
func (store *levelDBStore) loadTypeMetadata() {
var typeType = store.types.Type("_type")
var tag = typeType.EncodeTag()
- var it = store.iteratePrefix(tag, defaultReadOptions)
+ var it = store.iteratePrefix(tag, []byte{}, defaultReadOptions)
defer it.Close()
for it = it; it.Valid(); it.Next() {
@@ -348,7 +365,7 @@ func (store *levelDBStore) loadTypeMetadata() {
func (store *levelDBStore) tagVersions(vt *spack.VersionedType, typ *logeType) {
var prefix = encodeTaggedKey([]uint16{ldb_LINK_INFO_TAG, vt.Tag}, "")
- var it = store.iteratePrefix(prefix, defaultReadOptions)
+ var it = store.iteratePrefix(prefix, []byte{}, defaultReadOptions)
defer it.Close()
for it = it; it.Valid(); it.Next() {
@@ -357,7 +374,6 @@ func (store *levelDBStore) tagVersions(vt *spack.VersionedType, typ *logeType) {
typ.Links[info.Name] = info
}
-
var maxTag uint16 = 0;
var missing = make([]*linkInfo, 0)
@@ -413,9 +429,13 @@ func encodeIndexKey(prefix []byte, target string, source string) []byte {
// -----------------------------------------------
func ldb_find(store *levelDBStore, readOptions *levigo.ReadOptions,
- typ *logeType, linkName string, target LogeKey) ResultSet {
+ typ *logeType, linkName string, target LogeKey, from LogeKey, limit int) ResultSet {
- fmt.Printf("Find options %v\n", readOptions)
+ if limit == 0 {
+ return &levelDBResultSet {
+ closed: true,
+ }
+ }
var vt = store.types.Type(typ.Name)
var linkInfo = typ.Links[linkName]
@@ -424,7 +444,7 @@ func ldb_find(store *levelDBStore, readOptions *levigo.ReadOptions,
encodeTaggedKey([]uint16{ldb_INDEX_TAG, vt.Tag, linkInfo.Tag}, string(target)),
0)
- var it = store.iteratePrefix(prefix, readOptions)
+ var it = store.iteratePrefix(prefix, []byte(from), readOptions)
if !it.Valid() {
it.Close()
return &levelDBResultSet {
@@ -433,7 +453,6 @@ func ldb_find(store *levelDBStore, readOptions *levigo.ReadOptions,
}
var prefixLen = len(prefix)
-
var next = string(it.Key()[prefixLen:])
return &levelDBResultSet{
@@ -441,6 +460,8 @@ func ldb_find(store *levelDBStore, readOptions *levigo.ReadOptions,
prefixLen: prefixLen,
next: next,
closed: false,
+ limit: limit,
+ count: 0,
}
}
@@ -506,9 +527,14 @@ type prefixIterator struct {
Finished bool
}
-func (store *levelDBStore) iteratePrefix(prefix []byte, readOptions *levigo.ReadOptions) *prefixIterator {
+func (store *levelDBStore) iteratePrefix(prefix []byte, from []byte, readOptions *levigo.ReadOptions) *prefixIterator {
var it = store.db.NewIterator(readOptions)
- it.Seek(prefix)
+ var seekPrefix = append(prefix, from...)
+ it.Seek(seekPrefix)
+
+ if len(from) > 0 && it.Valid() {
+ it.Next()
+ }
return &prefixIterator {
Prefix: prefix,
View
14 src/loge/storage.go
@@ -18,9 +18,11 @@ type ResultSet interface {
type storeContext interface {
get(*logeType, LogeKey) interface{}
getLinks(*logeType, string, LogeKey) []string
- find(*logeType, string, LogeKey) ResultSet
store(*logeObject) error
storeLinks(*logeObject) error
+
+ find(*logeType, string, LogeKey) ResultSet
+ findFrom(*logeType, string, LogeKey, LogeKey, int) ResultSet
}
type transactionContext interface {
@@ -89,6 +91,11 @@ func (store *memStore) find(typ *logeType, linkName string, key LogeKey) ResultS
panic("Find not implemented on memstore")
}
+func (store *memStore) findFrom(typ *logeType, linkName string, key LogeKey, from LogeKey, limit int) ResultSet {
+ // Until I can be bothered
+ panic("Find not implemented on memstore")
+}
+
func (store *memStore) store(obj *logeObject) error {
obj.Lock.SpinLock()
defer obj.Lock.Unlock()
@@ -157,6 +164,11 @@ func (context *memContext) find(typ *logeType, linkName string, key LogeKey) Res
panic("Find not implemented on memstore")
}
+func (context *memContext) findFrom(typ *logeType, linkName string, key LogeKey, from LogeKey, limit int) ResultSet {
+ // Until I can be bothered
+ panic("Find not implemented on memstore")
+}
+
func (context *memContext) commit() error {
var store = context.mstore
store.lock.SpinLock()
View
4 src/loge/transactions.go
@@ -99,6 +99,10 @@ func (t *Transaction) Find(typeName string, linkName string, target LogeKey) Res
return t.context.find(t.db.types[typeName], linkName, target)
}
+func (t *Transaction) FindFrom(typeName string, linkName string, target LogeKey, from LogeKey, limit int) ResultSet {
+ return t.context.findFrom(t.db.types[typeName], linkName, target, from, limit)
+}
+
// -----------------------------------------------
// Internals
// -----------------------------------------------
View
18 src/logetest/links.go
@@ -84,7 +84,7 @@ func LinkBench() {
db.Transact(func (t *loge.Transaction) {
t.Set("person", "Brendon", &Person{ "Brendon", 31, []uint16{} })
for i := 0; i < 10000; i++ {
- var key = fmt.Sprintf("pet-%d", i)
+ var key = fmt.Sprintf("pet-%04d", i)
t.Set("pet", loge.LogeKey(key), &Pet { key, "dog" })
t.AddLink("pet", "owner", loge.LogeKey(key), "Brendon")
}
@@ -102,4 +102,20 @@ func LinkBench() {
}
fmt.Printf("Found %d pets\n", count)
+
+ count = 0
+
+ var lastPet loge.LogeKey = ""
+
+ var loops = 0
+ for loops < 1000 {
+ var somePets = db.FindFrom("pet", "owner", "Brendon", lastPet, 100)
+ for somePets.Valid() {
+ lastPet = somePets.Next()
+ count++
+ }
+ loops++
+ }
+
+ fmt.Printf("Sliced %d pets\n", count)
}
View
4 src/logetest/main.go
@@ -12,9 +12,9 @@ type Pet struct {
}
func main() {
- //LinkBench()
+ LinkBench()
//LinkSandbox()
- WriteBench()
+ //WriteBench()
//Sandbox()
//Example()
}
Please sign in to comment.
Something went wrong with that request. Please try again.