basic question on reference counting + virtual^redefining

Given

class C : public B

Q: i have a variable holding a C object , how do i get a variable of type B, connected to the same object?
A: simple assignment will do, but sliced!

Here’s the call to C constructor

C obj;

Using pointers — B* ptr = &obj;
Using references — B& ref = obj;

Q: Can 2 non-ref variables refer to the same object in memory?
A: I don’t think so. You need the address. nonrefs don’t know how to use addresses.
A: I guess it’s similar to java primitives. No way to create 2 int variables connected to the same int object
A: I feel the slicing problem occurs when you copy objects, but what about when you have just one object but multiple pointers?

Now we are ready to differentiate virtual vs redefining. Building on our example, say B has a public method m(), redefined in C. What is ptr->m() or ref.m()?

* difference — virtual is C::m() ^ redefinition is B::m(),
* difference — virtual is runtime binding ^ redefinition is compile time binding

Now a note on java. Java has only overloading (compile time binding) vs overriding ie virtual. C++ offers virtual ^ overloading ^ redefining. Last 2 are compile time binding.

ptr + virtual -} C // B ptr to a C object, to call a virtual method m()
ref + virtual -} C
nonref + virtual -} B
ptr + redefine -} B
ref + redefine -} B

In summary, only ptr/ref + virtual is really virtual. Not virtual if you use a nonref OR if you drop “virtual” keyword.

Destructors behave just like methods —
ptr + virtual -} C
ptr + non-virtual -> B. See P104 [[NittyGritty]]

Advertisements

temp table vs derived tables

sybase temp tables are extremely useful to simplify/enable complex queries.

Oracle offers temp tables, but another technique is derived tables ie sub-select in FROM.

%%tech strengths for fin IT jobs

— ranked
java + c# + c++
perl, unix — still widely used in financial but not many people know in-depth
SQL — outer join, self-join, sub-query and other complex joins, case expressions, group-by. See the t-sql book.

# eor
index design and utilization — banks heavy usage
milestoning pitfalls, limitations — banks heavy usage
refactor
complex data analysis using SQL — banks use it all the time.
query plan

make an autosys job start/stop@fixed days

Sometimes you might need to have a job start RUNNING at a fixed time (per Caldendar Cal1), and become success at a fixed time (per Calendar Cal2).

For now, let’s not dispute the requirement. (You might have a job that should not start in the window.)

Here’s a solution:
* Box b1 starts RUNNING per Cal1
* child file watcher w1 starts RUNNING right away
* a top-level job creates the file as per Cal2 => w1 becomes success.

Hibernate basic 2-table join — nested scan implemented in java

Zhu Rong,

To my dismay, hibernate (a popular,stable,fast java ORM framework) implements a 2 table join with individual SELECT’s on the inner table. As you explained, it’s more efficient to join inside the database?

Here’s my experiment. Hibernate supports a basic many-to-one mapping. Student object/table joining Course object/table. if i load 22 Student objects, hibernate uses lazy loading to delay querying the Course table until necessary. When it does query Course, it uses CourseId (join column, but not necessarily a PK or FK) to select just one Course. If 22 students are in 11 courses, hibernates runs 11 queries!

sleep() ^ yield() ^ wait()

Feature 1: does the thread let go of CPU@@
Feature 2: does the thread release lock@@
Feature 3: which real-world thread is affected? current call stack or another thread in an argument?
Feature 3a: is any Thread object explicitly mentioned? as arg or host object?
Feature 4: What objects are involved?

myObj.wait() is most complex:
1) yes
2) exactly 1 and only 1 lock (myObj), even if the thread holds multiple locks
3) current thread only
3a) none.
4) an object to serve as the waiting room

sleep() is simple:
1) yes
2) no, even if holding n locks
3) current thread only
3a) none. this is a static method.
4) No object involved. Thread.sleep() is a static method

yield() is similar to sleep()
4) No object involved. Thread.yield() is a static method
3) current thread only
2) no, even if holding n locks
1) yes

RAII mutex needed : no guaranteed unlock at thread death

See other posts on thread death, such as if a thread fails before releasing mutex #Shanyou

Update: RAII mutex introduces data inconsistency and is not always a good thing.

Mutex is shared by multiple stacks so can’t live on stack, but in a special semaphore memory area. According to [[OO MT using c++]], some semaphores (mutex locks) are shared among PROCESSES, so must live outside the address space of any process. When a process (or thread) dies, it could die owning the semaphore, blocking other processes indefinitely.

Because mutex release is manual, not by default, you should consider RAII, such as boost scoped_lock. See other posts on RAII mutex.

http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/topic/apis/concep26.htm says

If a thread is the owner of one or more exclusive write locks acquired by pthread_rwlock_wrlock(), pthread_rwlock_trywrlock(), or pthread_rwlock_timedwrlock_np(), when that thread terminates, the exclusive write locks are not automatically released by the system. This is an error in the application and indicates that the data associated with the lock is in an inconsistent state. If another thread attempts to get a shared read or exclusive write lock on the lock, that thread blocks forever.

http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html echos

“When a thread terminates, the mutex does not unless explicitly unlocked. Nothing happens by default.”

[[c++ cookbook]] echos “If an operating system thread is killed, it will not release its locks…”

##RAII (mutex + eg) — briefly

Resource Release Is Finalization is arguably the more relevant part of RAII.

The “resource” in question is often a shared resource, but not shared simultaneously. It has to be acquired and released. Such resources include
* locks
* files
* DB connections
* heap objects (via pointers)

— exemplifications
java synchronized keyword
java finally() to close DB connection
std::auto_ptr
boost::scoped_ptr
boost::mutex::scoped_lock

simple race condition illustration

Simplest eg: consider 2 threads both running counter++ on a shared variable.You expect counter to increment twice but it may increment once.

Key factor: the operation is not an (so-called atomic) one-stepper. counter++ is a “load-and-store”. It’s not *atomic*. Between the steps, another thread can change the shared variable.

For a bigger example, consider a web page hit counter.

C++ array declaration and object construction

Pig * ptr = new Pig[5]; // pointer to an array of simple Pig objects
Q: Does this create 5 Pig objects? YES tested. P238[[ 24 ]]
Q: using no-arg constructor? yes tested.
Q: contiguous memory? yes

Note the return type of this or the singular-new is identical — ptr to Pig. No one knows to use array-delete except the guy initializing the ptr.

Pig arr[5];
Q: Does this create 5 empty Pig objects? … in contiguous memory? YES … on stack? ALWAYS!
Q: no-arg constructor needed? Yes.
Q: How many times does constructor get called if we use a debugger? 5 times

#include
#define SIZE 3
using namespace std;
#define S(x) cout<<#x<<":\t"<<x<<"\n";
class CAT {
public:
CAT() {
cout < no-arg constructor with addr = ” << this << "\n";
itsAge = 0;
itsWeight = 0;
} // default constructor
~CAT(); // destructor
int GetAge() const {
return itsAge;
}
int GetWeight() const {
return itsWeight;
}
void SetAge(int age) {
itsAge = age;
}
CAT operator=(const CAT&);
CAT::CAT(const CAT&);
private:
int itsAge, itsWeight;
};
CAT::CAT(const CAT& rhs) {
cout < copy constructor ” << this << " <- " << &rhs << "\n";
this->itsAge = rhs.itsAge;
this->itsWeight = 8888888;
cout << "<– copy constructor\n";
}
// if you return CAT& then you won’t call copy constructor upon return
CAT CAT::operator=(const CAT& rhs) {
cout < assigning ” << this << " <- " << &rhs << "\n";
if (this == &rhs)
return *this;
this->itsAge = rhs.itsAge;
this->itsWeight = 11111111;
cout << "<– assignment " << this << " <- " << &rhs << "\n";
return *this;
}
CAT::~CAT() {
cout << this << " Destructor called!\n";
this->itsAge = this->itsWeight = 999999999;
}
int main() {
CAT * Family = new CAT[SIZE];
cout << "<– array declaration\n";
int i;
CAT * pCat;
for (i = 0; i < SIZE; i++) {
pCat = new CAT; // same memory location would be reused after reclaim!
pCat->SetAge(2 * i + 1);
CAT & alias2family = Family[i];
CAT * tmp = &(Family[i] = *pCat);
S(tmp);// same addr across iterations, due to the assignment pbclone
delete pCat;
}
for (i = 0; i < SIZE; i++)
std::cout << "Cat #" << i + 1 << ": " << Family[i].GetAge()
<< std::endl;
delete[] Family;
//system(“pause”);
return 0;
}

## IPC solutions: full list

I get this interview question repeatedly. See the chapters of [[programming perl]] and [[c++ threading]]. Here is my impromptu answer, not backed by any serious research. (Perl and c are similar; java is different.)

Let’s first focus on large volume data flow IPC. As of 2012, fastest and most popular IPC is shared memory, followed by named pipe. Across machines, you would have to accept the lower throughput of UDP (or worse still TCP) sockets. However, even faster than shared memory is a single-process data flow — eliminating IPC overhead. I feel you can use either heap or global area. Therefore, the throughput ranking is

# single-process
# shared mem
# named pipe or unix domain sockets
# UDP, TCP

— here’s a fuller list

  • MOM — dominant async solution in high volume, high-reliability systems
  • shared mem — extremely popular in MOM and ETL
  • named pipes and nameless “|” pipes
  • unix-domain sockets;
  • sysV msg queues. Not popular nowadays
  • shared files, ftp, DB — wide spread
  • memory mapped file
  • web service — dominant in cross platform systems
  • signals
  • RMI — java only
  • email

inter-dealer broker

espeed is dealer-to-dealer market; tradeweb is a dealer-to-customer market. –I think there’s no “broker” among the clients. espeed itself is the broker.

As broker, it’s not allowed to take positions. A FI position typically is worth millions, whereas a stock trade averages $5000 only. In some cases, an inter-dealer broker may take a position for a few minutes. Flat definitely by end of the day. One biz model is “bring the 2 sides together and collect an introduction fee”

dealer-to-dealer is an auction model; dealer-to-customer is the RFQ model like bid-wanted.

Treasury low-latency trading(Barc

(Background: most low-latency trading systems are related to eq or FX…)

Bloomberg and tradeweb allow an institutional client to send RFQ to her favourite Treasury dealers. The dealer’s auto quoter is typically low-latency. Typical latency [from receiving RFQ at gateway, to sending out quote from gateway] is typically 100~200ms. 500ms would be too high.

For an interdealer broker (espeed/brokertec), 30ms is good. 60ms will arouse complaints from hedge fund clients. Perhaps 30ms from receiving order to sending out acknowledgement? Distributed cache? No need. Just a regular database cache is enough. Coherence is being considered though.

Order matching engine is the heart of a treasury ECN operator. An ECN for muni bond or corporate bond may have a very different algorithm.

real world challenges using hibernate

1) performance. Hierbernate holds up well for mid-sized databases. For one GS system, we employ 3 techniques
 
* configuation on cachsing, lazy loading etc
* customize important queries using HQL
* hand-written SQL, when the generated SQL isn't optimized, but this tends to disable builtin performance features such as caching.
 
2) doens't work easily with stored procedures
 
3) if another db operation is already coded using jdbc, then one transaction can't easily span both

RAII mutex unlocking in exception stack unwinding

Q: why adopt exception handling in my c++ app instead of traditional error handling?

I don’t buy the “convenience” argument. To me the real justification is stack unwinding and RAII, including nearly guaranteed [1]
* unlock — same as in java synchronized keyword
* dtor

Without try/catch, deadlock is more likely.

[1] actually guarantee is tough and may require careful coding. See http://ose.sourceforge.net/browse.php?group=library-manual&entry=threads.htm –>

When an exception occurs, and the stack unwound, only destructors for objects created on the stack are invoked. If you had created an object using “operator new()”, and only held a pointer to that heap object via a stack ref/ptr variable, the heap object will not be destroyed, resulting in a memory leak. A similar problem can arise when using threads in that an exception occurring within the bounds of a mutex lock, can result in the mutex not being unlocked when the stack is unwound and control returned to a higher point in the call chain.

I think one way to guarantee is using a scoped mutex. As a stackvar, the object has a limited LIFETIME and the var has a limited SCOPE.

In java, synchronized keyword guarantees automatic unlocking upon exception. If you use Lock objects, then you must do it yourselves. Try/finally seems to be the way. My suggestion:

* put lock() in Method 1, in a try block
* put abnormal unlock() in finally block
* put normal unlock() statements in any subsequent method on the call stack.

##java’s advantages over c++

#1) portable — no compiler discrepancies
#2) memory management — c++ stack variables are fine, but heap and pointer are messy. Look at all the smart pointers.
) slicing problem

These are the c++ PAINS addressed by java. The other c++ shortcomings are less painful

#3) thread
#4) simpler, (and thread-safe) collections than STL
) reflection, proxy — one of java’s most powerful features
) simpler generics — but i feel this is less battle tested, as most developers don’t write generic classes.
) no multiple, virtual or private/protected inheritance
) simpler remoting

shared^static library (minGW

wikipedia says (modified) —

Originally, only static libraries existed. Dynamic linking involves loading the subroutines of a library (DLL or *.so) into an application program at load time or runtime, rather than linking them in at compile time.

Dynamic libraries …. allowing the same disk file to be used by multiple running programs at the same time. Static library disk files, by definition, cannot be shared — it has to be bitwise “copied” into each executable.

When linking against .lib file in Windows one must first know if it is a regular static library or an import library. In the latter case, a .DLL file must be present at runtime.

A something.dll.a file is a MinGW static-import-library for the associated something.dll file – the equivalent of Visual Studio’s .lib static import libraries for linking to DLLs

shared^static library – phasebook

http://stackoverflow.com/questions/2649334/difference-between-static-and-shared-libraries
is good

zipfile — static lib (not shared lib) is created using q(ar) and conceptually a zipfile

  • static = unshared. A static library (some.a) is “copied” into your executable image, enlarging it.
  • copied
  • enlarge

shared = dynamic library — In unix, some.so.n means SSSharedObject. In windows some.dll means DDDynamic Link Library.

  • baggage — using Static library, your executable doesn’t carry any external “baggage” i.e. the shared library files.
  • recompile — of your executable is necessary only if using “static” library

http://stackoverflow.com/questions/4250624/ld-library-path-vs-library-path explained it well — your libraries can be static or shared. If it is static then you don’t need to search for the library after your program is compiled and linked. If shared then LD_LIBRARY_PATH is used when searching for the shared library, even after your executable has been successfully compiled and linked. This resembles dotnet DLL or jars — you can upgrade a DLL/jar without recompiling the executable.

!!all promotions are "awarded" to long-surviving objects

GC commentators usually tiptoes around this tricky topic — “generational GC typically promote an object from eden to old gen only when it has survived a few minor collections”. It’s not a hard guarantee that every promoted has survived at least 2 minor GC[1]

[1] but I believe there is a guarantee of at least 1 survival. Very simple, promotion can only happen during collection. If an object is promoted then it must be live at the time.

[[javaPerformance]] make it clear that premature promotion does happen — a new object is promoted during its very first collection. This object (like all new objects) is likely to become garbage soon, but once promoted will not be examined until a major GC. This tends to litter the oldgen with garbage.

!! every new object is allocated in Eden

Contrary to popular belief, some large objects might be allocated from oldgen (as of 2012).

This is at the discretion of the garbage collector. Note every JVM garbage collector controls allocation as its 2nd job (cleanup is first job). There’s no guarantee by the JVM vendor exactly when a large object may be allocated from eden or oldgen.

Therefore, it’s only safe to say that “most allocations hit eden”.

hibernate interceptors

In one GS system, we use interceptor to incercept inserts or deletes. As a standard, we don't put business logic in interceptors.
 
We put in lastUpdated and lastUpdatedBy and such things. It's somewhat similar to triggers but more efficient.
 

pure-pure virtual invoked during base ctor/dtor #bbg

Update: P273 [[eff c#]] compares c# vs c++ when a pure virtual is invoked by ctor (book skips dtor). It confirms c++ would crash, but my bloodshed c++ compiler detected pure virtual called in base ctor and failed compilation. See source code at bottom.

This is rather obscure , not typical. Not even a valid question.

struct B{
 virtual void cleanup() = 0;
 ~B(){
   cleanup();
  }// not virtual
};
struct D: public B{
 void cleanup(){}
};
int main(){ D derivedObject; } 
// derivedObject destructed. 
// If (see below why impossible) code were to compile, what would happen here?

%%A: the invisible ~D() runs, then the defined ~B() runs even though it’s non-virtual.
%%A: I think it’s undefined behavior ONLY with “delete”.
%%A: virtual method called during base object destruction/construction – Warning by Scott Meyers. At time of base class destruction only the pure virtual is available, so system crashes saying “pure virtual function called”.

(In java, superclass ctor calling a virtual function results in the subclass’s version invoked, before the subclass ctor runs! Compiles but dangerous. If you do this, make sure the subclass ctor is empty.)

Q: how can a compiler intercept that error condition, with 0 runtime cost?
A: see post on pure pure virtual

Note, if Derived had not implemented the pure virtual, then Derived would have become an abstract class and non-instantiable.

Actually compiler detects the call to cleanup() is a call to B::cleanup() which is abstract. Here’s a demo.

struct B{
  virtual void cleanup() = 0;
  B();
  ~B();  // not virtual
};
//void B::cleanup(){       cout<<"B::cleanup\n";}
B::B(){
  cout<<"B()\n"; //this->cleanup(); //breaks compiler if enabled
}
B::~B(){
  cout<<"~B()\n"; //this->cleanup(); //breaks compiler if enabled
}
struct D: public B{
  void cleanup(){       cout<<"D::cleanup\n"; }
  ~D(){cout<<"~D()\n"; }
};
int main(){
    if (true){
       D derivedObject; // derivedObject destructed. Suppose this can compile, what will happen?
    }
    cin.get();
}

2 threads sharing a stack variable — c++^java

In C++, any primitive/class object on stack/heap are often passed by reference. It’s possible to create a char stackVar and pass its address to another thread. 2 threads can then write to the same stack memory location simultaneously. In contrast, Java’s primitive stack objects are thread-confined.

It’s important to make sure the stack object doesn’t go out of scope too early, creating a dangling pointer.

Possible in java? I don’t think so. Java stack only holds primitives. Java Primitives are never passed by reference. Suppose thread A has a method A that creates an int on its stack, then starts a thread B that reads the int stackVar. It looks like pass-by-ref but is probably pass-by-value behind the scene, because java requires that local int to be _final_

pure^concrete virtual functions #bbg

3 types of virtual methods
* concrete virtual — virtual methods without “=0”. Regular virtual methods.
* concrete pure virtual – with “=0”. pure but with a body. See http://www.gotw.ca/gotw/031.htm. Least common.
* pure-pure virtual  — with “=0”. pure and without a body.  “Pure virtual” usually means this.

You can think of the “=0” as a NULL address assigned to the func ptr. Remember compiler maps each function NAME to an address of the function’s body. At first, a pure/abstract function has no body YET.
[2] concrete pure virtual????

Diff: if a class has at least one pure virtual, then you can’t [2] instantiate it. Subclass must implement it to become non-abstract – This is the purpose for the “PURE”.

Basically, all methods are implemented as func-ptr FIELDS and absolutely non-nullable in any class instance. With a func-ptr field in NULL, this class is non-instantiable i.e. “abstract”.

similar: Both PURE and concrete-virtual methods can have a “body” i.e. a method definition.
** Diff: But PURE declaration ends in “=0” so body must be somewhere else. Concrete virtual can have a body attached to declaration.

similar: the body is callable by subclasses
** Diff: but must be explicitly called in the PURE case. See http://www.gotw.ca/gotw/031.htm and also [[eff c++ 167]]

Q (I don’t remember the exact question at Bloomberg IV. A obscure question): pretend to be a compiler writer. How can your compiler intercept a call to an unimplemented PURE virtual method (i.e. a pure-pure virtual), with 0 runtime cost? P273 [[eff c#]] compares c# vs c++ when a pure virtual is invoked by ctor. It confirms c++ would crash.
%%A: Synthesize a body for each undefined PURE virtual. In the body, we can clean up and print diagnostic then call abort().
%%A: check the vtable. If the function pointer is null, then the host class can’t be instantiated in the first place.

 

bind2nd/bind1st is used like a cvctor


find_if ( &array[0], &array[2],
bind2nd(greater(), 55)

If you have trouble making out the objects in such a call to bind2nd,
here’s a simple rule

bind2nd always takes objects and instantiate another object, not a type

It’s like a converter constructor, but bind2nd is actually a function template.

In our example,

* greater() is an Object, not a type, not a function
* find_if needs an Object (not a type) as argument

template-argument inference and binary_function

– function templates are often specialized without explicit template-argument, because compiler can infer from function arguments.
– However, class templates always need explicit template-argument.

Despite the name, unary_function (and binary_function) is an empty class template (actually struct template)
* without operator() declared ( — so You must subclass and furnish it in order to use it )
* that needs explicit type arg.

##ptr and ref as lval/rval

(pbclone means pass-by-creating-a-clone, usually on stack)

Ptr as lval — reseating
Ptr unwrapped as lval — pointee obj state change, possibly assignment overloading

Ref as lval during initialization — seating. ie permanently saving an address into the 4-byte ref
Ref as lval but not initialization — obj state change, possibly assignment overloading

Nonref primitive as lval — obj state change, just like java primitive
Nonref class type as lval — obj state change, possibly assignment overloading

Ptr (including “new struct123”) as rval — returns address

Ptr unwrapped as rval, initializing a ref — pbref by returning address
Ptr unwrapped as rval, not initializing a ref — pbclone
.
Ref as rval, initializing another ref — pbref by returning address
Ref as rval, not initializing another ref — pbclone
.
Nonref class type var as rval, initializing a ref — pbref by returning address
Nonref class type var as rval, not initializing a ref — pbclone
.
Nonref primitive var as rval, initializing a ref — pbref by returning address
Nonref primitive var as rval, not initializing a ref — pbclone
.
nonref primitive literal like “23.5” as rval, not initializing a ref — pbclone
nonref primitive literal like “23.5” as rval, initializing a ref — illegal

list^vector… – bloomberg phone IV

Q: list advantage over vector?
%%A: no iterator invalidation
%%A: efficient head operation, without shifting entire array
AA: efficient insert()/erase() on internal positions, without shifting subsequent nodes, esp. if each object is physically stored in the array and expensive to copy. (In java, only the 32 bit address is physically stored in the array.) However, locating the position requires a graph traversal.

Q: vector advantage over list?
%%A: random access to internal nodes
%%A: sorting
%%A: less frequent (bulk) memory allocations. List must allocate memory for each new node
%%A: each node needs no pointer to next node

Q: efficiently find anagrams in a file of English words, using just one loop
%%A: create objects wrapping {original string, normalized string} and throw them into a list. Sort the list using the normalized string. But this is considered 2 loops.
%%A: throw them into a multimap instead, using a customized less functor

Q2: There are the 100 unique integers between 1 and 100 in a file, but one of them is deleted. How do u find it with 1 loop?
%%A: pre-compute the sum of 100, then subtract each number found

Q2b: five numbers deleted?
%%A: start with the 100-bit binary number of all ones – call it base. (I think it’s 2^100-1). For each number (say 66) read from the file, shift a one by 66 bits (easy for a computer) and subtract it from the base. This will flip a single bit in base. In the end we are left with a binary number containing only five bits. To quickly find the most significant of the five bits, compute base-2-log and take the integer portion.
%%A: start with an bool array of 100 False. As we see a number from the file, we use the number as index to flip the array element. After the scan, we have 5 values left in the array.

Q3: what’s the copy constructor signature?

Q3b: why override it?
%%A: a ptr field will be shallow-copied

Q3c: what if I drop the const?

Q3d: What if I drop the “&”
%%A: the pass-by-value will call copy ctor in another stack frame
AA: pbclone will call the same custom copy ctor recursively.
AA: compiler warning; infinite recursion and stack overflow

%%Q: in most companies, templates are too hard so people avoid creating home-grown templates
A: at Bloomberg we avoid them but we do have some.

ref-counting usage in STL

a1) A container of pointers usually use ref-counting smart pointers

b1) strings are usually ref-counted

[ Above 2 points are unrelated but they lead to the next point ]

1) I believe a vector of POINTERS uses ref-counting smart pointers, but a vector of CHAR is never ref-counted.

##[09] (career)safety net for %%family

See also [[#halo]], [[# towards an app architect]], [[http://bigblog.tanbin.com/2006/11/u-cant-be-developer-for-ever.html ]]

For a techie like me, what long term factors help to create a cushion or safety net?

#1) citizenship
#2) Zofia’s professional credentials
#) brank — titles in well-known companies
#) health and insurance
* home ownership + rental income
* English language skill for wife and me
* trec DBA
* trec presales
* trec PM
* post graduate degree -> teach

a manager of entity objects #memory leak

(In fact, the paramount justification/motivation of this entire concept is memory leak prevention in C/C++, perhaps in conjunction with a custom Allocator. A java guy may think this “manager” concept sounds cool and impressive but it’s actually less relevant to Java. Like all practical ideas, it started as a simple class with a single purpose and a single field — the pointer. An instance of this class is always an auto-variable on the heap, so it’s AUTOmatically destructed. A non-default dtor deletes the pointer. RAII is one of the simplest yet most effective ways to prevent memory leak.)

You can design a manager for your entity/domain objects. For example, I had a serializer/deserializer for my message objects.

A classic manager is designed to take up responsibility of object creation (like factory), object persistence, object lookup, object destruction, object linking (dependency injection?)…. For overly complex objects, it might be beneficial to separate these lifecycle logic and object manipulation into a manager object, and leave a clean set of behavior inside the domain object.

In contrast, Some designers prefer to consolidate all of these logic in the domain object. A code smell — a well-defined, well-modeled domain model class having methods that return instances of itself. Static or non-static methods, but no factory.

a manager is often a singleton or a “static” thing

== eg of managers ==
* a manager often handles persistence of domain objects. Conversely, I think the same manager can handle object loading from database. Such a manager is not a DAO but a choke point to the DAO layer or persistence layer.

* object validity check — sometimes can be done better by a manager, esp. if that expertise lies in the manager. In one project, i need to check validity of a family of domain objects. If those objects are not derived from each other, then it’s perhaps best to put the validation logic in the manager.

* Factories are managers
* xml bean factory in dependency injection
* EJB container is a manager
* object visibility checker??
* object mutability/read-only checker — error memos read-only checker?
* resource pool is a manager, but objects in it aren’t domain models

PCP – how to internalize, using PnL

(PCP under continuous dividend model? See http://bigblog.tanbin.com/2013/11/equity-fwd-contract-pricing-internalize.html)

key PCP concept — the equivalence of values of 2 portfolios ANY time after you buy them, not just at expiration. However, the valuation (plotted against S) at any time before expiration is non-intuitive and hard to grapple.

Suppose A buys a long European call and B buys [a long European put + a futures]. All instruments were bought at a fair price, so PnL both start $0. (MV is irrelevant at this stage.) N days later, when market rates (spot, implied vol…) have moved a bit, we would expect both portfolios to show small but identical PnL[1]. Therefore, looking at PnL rather than MV, the cash component disappears from the equation, since cash will (almost) always have zero PnL.

Note MV is a poorly defined (non-intuitive) concept for futures and a lot of derivatives. See post on MktVal clarified.

Similar to the PnL view, the delta view involves only 3 positions — call/put/forward, not  the cash.

[1] exact PnL amount is hard to visualize as it involves BS.

(A: European options have no assignment before maturity.)

Now let’s look at MV or valuations. Valuations are more important in practice and relate to observed market prices. At t=0 portfolio MV are equal only if we started at t= -1 with an equal amount of seed capital. At t=0, MV becomes (assuming zero interest rate)

  Premium_c + $K cash = Premium_p + f

N days later, or at expiration, MV becomes

  MV_c + $K cash = MV_p + MV_f

Some people (like my boss Saurabh) say a long call + a short put == a forward [2], but I find it less intuitive. LHS is the difference between the 2 premiums, which could be 0 or negative.

Update – Now I agree C = P + F is the best way to remember it, once you recognize that you must get down to details with the fwd contract and build intimate knowledge thereof.

I guess the statement in [2] assumes a long position in the forward contract can become either an asset or liability any time before expiration. If I must translate [2] into English, i would say a long call combining a short put has identical PnL to a forward contract (assuming European options). Suppose both portfolios start with just the positions + no cash. At T=0, all 3 securities are bought at fair values, so Portfolio A has PnL=0, so does B. Based on the delta rule above, a 1 cent change in underlier would result in identical changes in the 2 portfolio’s valuations, so the 2 portfolios always have identical valuations, either positive or negative.

What if your short put gets assigned? Answer is hidden somewhere in this blog. If you indeed lose the short position, the delta rule will stop working.

Is PCP compromised by any of the “unrealistic/simplistic” assumptions of BS? No. PCP is model-independent.

Is PCP affected by the vol skew or the vol term structure ? I don’t think so.