public DatastoreResults <T> Query(DatastoreQuery <T> q)
        {
            var results = new BlockingCollection <DatastoreResult <T> >();

            Task.Factory.StartNew(() =>
            {
                foreach (var item in new DirectoryInfo(_path).EnumerateFiles("*" + ObjectKeySuffix, SearchOption.AllDirectories)
                         .Select(f =>
                {
                    var path = f.FullName;
                    if (path.StartsWith(_path))
                    {
                        path = path.Substring(_path.Length);
                    }

                    if (Path.IsPathRooted(path))
                    {
                        path = path.TrimStart(Path.DirectorySeparatorChar);
                    }

                    var key = new DatastoreKey(path.Substring(0, path.IndexOf(ObjectKeySuffix)));
                    var entry = new DatastoreEntry <T>(key, default(T));
                    return(new DatastoreResult <T>(entry));
                }))
                {
                    if (!results.TryAdd(item, Timeout.Infinite))
                    {
                        break;
                    }
                }
            })
            .ContinueWith(_ => results.CompleteAdding());

            return(DatastoreResults <T> .WithCollection(q, results).NaiveQueryApply());
        }
Beispiel #2
0
        private void RunQuery(DatastoreResults <byte[]> .ResultBuilder qrb)
        {
            byte[] range = null;
            if (!string.IsNullOrEmpty(qrb.DatastoreQuery.Prefix))
            {
                range = Encoding.UTF8.GetBytes(qrb.DatastoreQuery.Prefix);
            }

            using (var i = _db.NewIterator(ReadOptions.Default))
            {
                i.SeekToFirst();

                if (qrb.DatastoreQuery.Offset > 0)
                {
                    var offset = 0;
                    while (offset < qrb.DatastoreQuery.Offset)
                    {
                        if (range != null)
                        {
                            if (i.Key().ToArray().HasPrefix(range))
                            {
                                offset++;
                            }
                        }
                        else
                        {
                            offset++;
                        }

                        i.Next();
                    }
                }

                for (var sent = 0; i.Valid(); sent++)
                {
                    if (qrb.DatastoreQuery.Limit > 0 && sent >= qrb.DatastoreQuery.Limit)
                    {
                        break;
                    }

                    if (qrb.Cancellation.IsCancellationRequested)
                    {
                        break;
                    }

                    if (range != null && i.Key().ToArray().HasPrefix(range))
                    {
                        var k = new DatastoreKey(i.Key().ToString());
                        var v = qrb.DatastoreQuery.KeysOnly ? null : i.Value().ToArray();
                        var e = new DatastoreEntry <byte[]>(k, v);

                        if (!qrb.Output.TryAdd(new DatastoreResult <byte[]>(e), Timeout.Infinite, qrb.Cancellation.Token))
                        {
                            break;
                        }
                    }

                    i.Next();
                }
            }
        }