It's quite simple with only two operations, you can either push a value, or get all values, clearing all these values from the structure. Can be easily implemented with a queue aggregate.
push(value)
get() -> list of values, clears contents
In my opinion, there is no common name for a data structure which provides this functionality. Depending on the list order provided by get() it is similar to a stack or a queue.
Assuming Java, this could work for you (not tested):
import java.util.ArrayList;
import java.util.Collection;
import java.util.Stack;
public class FlushStack<E> extends Stack<E> {
public Collection<E> get() {
ArrayList<E> elements = new ArrayList<E>(this);
this.clear();
return elements;
}
}
It is basically a stack, only that "get" does a recurring "pop" until the stack is empty.
In pseudocode this would be something like:
def push (v): stack.push (v)
def get ():
retVal = []
while stack.isNotEmpty: retval += [stack.pop () ]
return retVal
Related
How Can I define a Record Collection or a Vector of Records?
I have this snippet code:
(defrecord Transaction [a, b, c])
I want define a Transaction collection called LastTransactions to implement a function like this:
(defn can-authorize
"Validate Authorization by Transaction"
[^Transaction transaction, ^LastTransactions lastTransactions]
(... business logic)
)
First Question, is that the right way to do that?
Second, How can i declare that structure?
Clojure's type hints don't offer any type validation - you can use Clojure Spec or Plumatic Schema for that. They only serve for the compiler to prevent reflection when Java methods are called on the parameters. For that purpose, you don't need to type hint a vector since Clojure's core functions for collections (first, conj, etc.) by design don't require reflection on standard collections.
However, if you need, you can type-hint the elements that you extract from the lastTransaction sequence, for example:
(defn can-authorize
"Validate Authorization by Transaction"
[^Transaction transaction, lastTransactions]
...
(for [^Transaction t lastTransactions]
(...do-something-with t))
Type-hints are used to avoid reflection. They are not used to statically type function or constructor args.
Just use basic ^java.util.List type-hint instead of ^LastTransactions. In this case, any use of wrong lastTransactions in the body of the function will fail with ClassCastException. However, it won't check the type of elements in that list. To do so, use type hinting everytime you work with elements of lastTransactions.
Example 1 with type hinting:
(defn can-authorize
[^Transaction transaction, ^java.util.List lastTransactions]
(.size lastTransactions)
)
In this case, decompiled java code will look like:
// Decompiling class: user$can_authorize
import clojure.lang.*;
import java.util.*;
public final class user$can_authorize extends AFunction
{
public static Object invokeStatic(final Object transaction, Object lastTransactions) {
final Object o = lastTransactions;
lastTransactions = null;
return ((List)o).size();
}
public Object invoke(final Object transaction, final Object lastTransactions) {
return invokeStatic(transaction, lastTransactions);
}
}
Example 2 without type hinting:
(defn can-authorize [^String transaction, lastTransactions]
(.size lastTransactions))
decompiled to:
// Decompiling class: user$can_authorize
import clojure.lang.*;
public final class user$can_authorize extends AFunction
{
public static Object invokeStatic(final Object transaction, Object lastTransactions) {
final Object target = lastTransactions;
lastTransactions = null;
return Reflector.invokeNoArgInstanceMember(target, "size", false);
}
public Object invoke(final Object transaction, final Object lastTransactions) {
return invokeStatic(transaction, lastTransactions);
}
}
Compare the resulted return statements:
with type hinting
return ((List)o).size();
without type hinting
return Reflector.invokeNoArgInstanceMember(target, "size", false);
PS: code decompiled by using clj-java-decompiler
I have a Datastore query using cursor (Objectify v5) and I want to get the cursor after each item in the result list. Code looks like this:
public List<Puzzle> queryWithCursor(String cursor, String order, int limit) {
Query<Puzzle> query = ObjectifyService.ofy()
.load()
.type(Puzzle.class)
.order(order)
.limit(limit);
query = query.startAt(Cursor.fromWebSafeString(cursor));
List<Puzzle> puzzles = new ArrayList<>();
QueryResultIterator<Puzzle> iterator = query.iterator();
while (iterator.hasNext()) {
Puzzle puzzle = iterator.next();
puzzle.setCursor(iterator.getCursor().toWebSafeString());
puzzles.add(puzzle);
}
return puzzles;
}
While the method works correctly, it triggers so many Datastore queries behind the scene. Basically, every time iterator.getCursor() runs, it triggers an additional query. I learnt from Stackdriver Trace that if limit is 20, the method triggers 19 queries in total (it seems that the last .getCursor() does not trigger additional query). So this method is even slower and more costly than the similar query using offset.
Is this really a bug? Is there a way to avoid the performance hit?
This is actually a fundamental behavior of the datastore, at least in the old sdk (as opposed to the new sdk that Objectify 6 uses, which may be the same maybe not). Calling getCursor() at non-batch boundaries restarts the query. You can try it with the low-level API.
There is a workaround: Make up your own Cursor class. It should consist of the low level Cursor and an offset. Explicitly set a chunk() size, then your cursor should consist of the Cursor at index 0 plus an offset into the chunk.
Then when you want to restart a query at that cursor, use .cursor(batchStartCursor).offset(offsetIntoBatch).
import com.google.appengine.api.datastore.Cursor;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.SortDirection;
import com.google.appengine.api.datastore.QueryResultList;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ListPeopleServlet extends HttpServlet {
static final int PAGE_SIZE = 15;
private final DatastoreService datastore;
public ListPeopleServlet() {
datastore = DatastoreServiceFactory.getDatastoreService();
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
FetchOptions fetchOptions = FetchOptions.Builder.withLimit(PAGE_SIZE);
// If this servlet is passed a cursor parameter, let's use it.
String startCursor = req.getParameter("cursor");
if (startCursor != null) {
fetchOptions.startCursor(Cursor.fromWebSafeString(startCursor));
}
Query q = new Query("Person").addSort("name", SortDirection.ASCENDING);
PreparedQuery pq = datastore.prepare(q);
QueryResultList<Entity> results;
try {
results = pq.asQueryResultList(fetchOptions);
} catch (IllegalArgumentException e) {
// IllegalArgumentException happens when an invalid cursor is used.
// A user could have manually entered a bad cursor in the URL or there
// may have been an internal implementation detail change in App Engine.
// Redirect to the page without the cursor parameter to show something
// rather than an error.
resp.sendRedirect("/people");
return;
}
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
PrintWriter w = resp.getWriter();
w.println("<!DOCTYPE html>");
w.println("<meta charset=\"utf-8\">");
w.println("<title>Cloud Datastore Cursor Sample</title>");
w.println("<ul>");
for (Entity entity : results) {
w.println("<li>" + entity.getProperty("name") + "</li>");
}
w.println("</ul>");
String cursorString = results.getCursor().toWebSafeString();
// This servlet lives at '/people'.
w.println("<a href='/people?cursor=" + cursorString + "'>Next page</a>");
}
}
I have followed the pattern from examples on GitHub. When I call store on the model object, passing an instance of the entity, I get a compile error indicating one of the implicit parameters is missing as shown below.
could not find implicit value for parameter sg: com.outworkers.phantom.macros.SingleGeneric.Aux[com.ss.wuhu.settlement.entity.Settlement,Repr,HL,Out]
I guess I am missing something obvious. Could someone please point out how to bring the implicit into scope?
Regards
Meeraj
This is the code snippet where I am storing the data.
import akka.Done
import com.outworkers.phantom.dsl._
import com.outworkers.phantom.connectors.{CassandraConnection, ContactPoints}
import com.ss.wuhu.settlement.entity.Settlement
import com.ss.wuhu.settlement.entity.mapping.{SettlementForCourierModel, SettlementForVendorModel}
object Connector {
private val hosts = Seq("127.0.0.1") // TODO from environment
lazy val connector: CassandraConnection = ContactPoints(hosts).keySpace("wuhu_order")
}
class SettlementDatabase(override val connector: CassandraConnection) extends Database[SettlementDatabase](connector) {
object SettlementForCourierModel extends SettlementForCourierModel with connector.Connector
object SettlementForVendorModel extends SettlementForVendorModel with connector.Connector
def truncateAll() = {
Database.truncate()
}
def store(set: Settlement) = {
for {
v <- Database.SettlementForVendorModel.store(set)
d <- Database.SettlementForCourierModel.store(set)
} yield (Done)
}
}
object Database extends SettlementDatabase(Connector.connector)
This is a known bug with an open issue: https://github.com/outworkers/phantom/issues/774
I suggest either using the workaround as described in the link above, or my workaround which was creating my own .store() using .insert().
example:
def myStore(person: Person) : Future[ResultSet] =
insert
.value(_.name, person.name)
.value(_.age, person.age)
.value(_.timeCreate, person.timeCreate)
.future()
The problem is from cracking-coding-interview, problem 3.2
Stack Min: How would you design a stack which, in addition to push
and pop, has a function min which returns the minimum element? Push,
pop and min should all operate in 0(1) time.
Then I wrote the following code, but the push function is wrong, because the incompatible type, not sure the problem, and why the pop is correct? Thanks
import scala.collection.mutable.Stack
class StackMin extends Stack[Int] {
val minstack=new Stack[Int]
override def push(element: Int): Stack[Int]={
if (element<= min()){
minstack.push(element)
}
super.push(element)
}
override def pop(): Int={
val value=super.pop()
if(value==min())
minstack.pop()
value
}
def min():Int={
if(minstack.isEmpty)
Int.MaxValue
else minstack.top
}
}
Clever solution.
The return type of the push method is wrong. You can specify it as StackMin.this.type:
override def push(element: Int): StackMin.this.type = {
Or leave it out entirely (let the compiler infer it):
override def push(element: Int) = {
I've written the following code for retrieving the StructureIds from an IEnumerable<Structure>:
Action<Structure> recurse = null;
List<int> structureIds = new List<int>();
recurse = (r) =>
{
structureIds.Add(r.StructureId);
r.Children.ForEach(recurse);
};
IEnumerable<Structure> structures = GetStructures();
structures.ForEach(recurse);
I'd really like to make this generic so I can use it with any IEnumerable, i.e. something like:
public static IEnumerable<TType> GetPropertyValues<TType, TPropertyType>(
this IEnumerable<TType> this, <Property Declaration>)
{
// Generic version of the above code?
}
Can this be done?
Action isn't very Linq'ish. How about Func instead? (Untested code)
public static IEnumerable<TProp> RecurseSelect<TSource, TProp>(
this IEnumerable<TSource> source,
Func<TSource, TProp> propertySelector,
Func<TSource, IEnumerable<TSource>> childrenSelector
)
{
foreach(TSource x in source)
{
yield return propertySelector(x);
IEnumerable<TSource> children = childrenSelector(x);
IEnumerable<TProp> values = children.RecurseSelect(propertySelector, childrenSelector);
foreach(TProp y in values)
{
yield return y;
}
}
}
And then
IEnumerable<Structure> structures = GetStructures();
IEnumerable<int> structureIds = structures.RecurseSelect(
s => s.StructureId,
s => s.Children);
Your problem is that you're not adding each item to a list, you're adding the a property of each item. That property will only be available for a Structure, and not any other type you might reuse the code with.
You also don't have a mechanism for getting the children of your other classes. (the r.Children property you use).
Your two solutions would be to use interfaces (that is, define IHasChildren and IGetProperty) that could be used as base types for a simple algorithm, or you could pass in functions to your method that allow this to be more freely calculated. For example, your method signature might need to be this:
public static IEnumerable<TPropertyType> GetPropertyValues<TType, TPropertyType>
(this IEnumerable<TType> rootItem, Func<TType, IEnumerable<TType>> getChildren, Func<TType, TPropertyType> getIdValue)
... but that's not going to be very pretty!