#include "HTDJInterface.h"
#include "HTDJLocalModel.h"
#include "HTDJRemoteModel.h"
class HTDJController
HTDJController(
HTDJLocalModel& local,
HTDJRemoteModel& remote,
HTDJInterface& hinterface
c++11 Model View Controller skeleton
|
VIEW
class HTDJController;
class HTDJInterface
{
HTDJInterface( HTDJController* p_controller)
|
MODEL
class HTDJLocalModel;
class HTDJController; // For access to log functions
// Note that we want GLOBAL ACCESS to a GENERIC local model.
extern HTDJLocalModel* g_p_local;
class HTDJLocalModel
{
HTDJLocalModel(HTDJController* p_controller);
|
c++11 containers
|
sorted_vector |
use when doing lots of unsorted insertions and maintaining constant sort would be expensive; NOTHING beats vector for that
|
map |
sorted binary search tree; always sorted by key; you can walk through in sorted order (choose unordered if not needed!)
|
multimap |
same as map but allows dupe keys (not common)
|
unordered_map |
hashmap; always sorted by key; additional bucket required for hash collisions; no defined order when walking through
|
unordered_multimap |
same as map but allows dupe keys; dupes are obviously in the same bucket, and you can walk just the dupes if needed
|
set multiset unordered_set unordered_multiset |
sets are just like maps, except the key is embedded in the object, nice for encapsulation.
Items must be const (!) since they are the key - sounds bad, but this is mitigated by the mutable keyword.
You can use mutable on the variables that are not part of the key to remove the const.
This changes the constness of the object from binary (completely const) to logical (constness is defined by the developer).
So... set is an excellent way to achieve both encapsulation and logical const - make const work for you, not against! :-)
An even better approach: use pointers.
The entire object can be dereferenced and accessed then without const issues.
Two requirements: you must make sure yourself that you do not change the key values - you can mark them const, provided in constructor;
you must create sort functors that dereference the pointers to sort using object contents if needed
(the default sorting will be by pointer address).
The arguably biggest advantage, as a result, is that you can create multiple sets
to reference the same group of objects with different sort funtors to create multiple indices.
You just have to manage the keys carefully, so that they don't change (which would invalidate the sorting).
TODO: develop a sort-on-demand unordered set of pointers that allow changing the key, with b_sort_ tracking for when key changes or new items added?
|
c++11 example for large groups of objects with frequent crud AND search
|
Best solution is an unordered set of pointers:
typedef boost::unordered_set<MajorObject*> MajorObjects;
|
c++11 example for large groups of objects with infrequent crud and frequent search
|
Best solution is a vector of pointers sorted on demand (sorted_vector):
TODO
|
c++11 example to associate two complex objects (one the map key, one the map value)
|
Use unordered_map with a custom object as key. You must add hash and equals functions. Boost makes it easy:
static bool operator==(MyKeyObject const& m1, MyKeyObject const& m2)
{
return
m1.id_0 == m2.id_0
&& m1.id_1 == m2.id_1;
}
static std::size_t hash_value(MyKeyObject const& mko)
{
std::size_t seed = 0;
boost::hash_combine(seed, mko.id_0);
boost::hash_combine(seed, mko.id_1);
return seed;
}
typedef boost::unordered_map<MyKeyObject, MyValueObject*> MyMap;
Note that you can extend this to use a pointer to a key object, whoop.
|
c++11 example for multiple unordered_set indexes into one group of objects
|
Objects will be dynamically created. One set should include them all and be responsible for memory allocation cleanup:
TODO
|
c++11 example for set with specific sorting
|
Use set with a specific sort functor. You can create as many of these indexes as you want!
struct customers_set_sort_functor
{
bool operator()(const MyObject* l, const MyObject* r) const
{
// the id is the key
return l->id_ < r->id_;
}
};
typedef set<MyObject*,myobject_sort_by_id_functor> MyObjectsById;
|
c++11 for loop using lambda
|
This C++11 for loop is clean and elegant and a perfect way to check if your compiler is ready for c++11:
vector<int> v;
for_each( v.begin(), v.end(), [] (int val)
{
cout << val;
} );
This is using a lambda function, we should switch from iterators and functors to those - but not quite yet, since we're writing cross-platform code. Do not touch this until we can be sure that all platforms provide compatible C++11 handling.
|
c++11 integer types
|
I really like the "fast" C++11 types, that give best performance for a guaranteed minimum bit width.
Use them when you know a variable will not exceed the maximum value of that bit width, but does not have to be a precise bit width in memory or elsewhere.
Pick specific-width fields whenever data is shared with other processes and components and you want a guarantee of its bit width.
And when using pointer size and array indices you should use types defined for those specific situations.
FAST types:
int_fast8_t
int_fast16_t fastest signed integer type with width of
int_fast32_t at least 8, 16, 32 and 64 bits respectively
int_fast64_t
uint_fast8_t
uint_fast16_t fastest unsigned integer type with width of
uint_fast32_t at least 8, 16, 32 and 64 bits respectively
uint_fast64_t
SMALL types:
int_least8_t
int_least16_t smallest signed integer type with width of
int_least32_t at least 8, 16, 32 and 64 bits respectively
int_least64_t
uint_least8_t
uint_least16_t smallest unsigned integer type with width of
uint_least32_t at least 8, 16, 32 and 64 bits respectively
uint_least64_t
EXACT types:
int8_t signed integer type with width of
int16_t exactly 8, 16, 32 and 64 bits respectively
int32_t with no padding bits and using 2's complement for negative values
int64_t (provided only if the implementation directly supports the type)
uint8_t unsigned integer type with width of
uint16_t exactly 8, 16, 32 and 64 bits respectively
uint32_t (provided only if the implementation directly supports the type)
uint64_t
SPECIFIC-USE types:
intptr_t integer type capable of holding a pointer
uintptr_t unsigned integer type capable of holding a pointer
size_t unsigned integer type capable of holding an array index (same size as uintptr_t)
|
c++ in-memory storage of "major" objects
|
OBSERVATION ONE
Consider An Important Qt Design: QObjects cannot normally be copied
their copy constructors and assignment operators are private
why? A Qt Object...
might have a unique QObject::objectName(). If we copy a Qt Object, what name should we give the copy?
has a location in an object hierarchy. If we copy a Qt Object, where should the copy be located?
can be connected to other Qt Objects to emit signals to them or to receive signals emitted by them. If we copy a Qt Object, how should we transfer these connections to the copy?
can have new properties added to it at runtime that are not declared in the C++ class. If we copy a Qt Object, should the copy include the properties that were added to the original?
in other words, a QObject is a pretty serious object that has the ability to be tied to other objects and resources in ways that make copying dangerous
isn't this true of all serious objects? pretty much
OBSERVATION TWO
if you have a vector of objects, you often want to track them individually outside the vector
if you use a vector of pointers, you can move the object around much more cheaply, and not worry about costly large vector reallocations
a vector of objects (not pointers) only makes sense if the number of objects is initially known and does not change over time
OBSERVATION THREE
STL vectors can store your pointers, iterate thru them, etc.
for a vector of any substantial size, you want to keep objects sorted so you can find them quickly
that's what my sorted_vector class is for; it simply bolts vector together with sort calls and a b_sorted status
following STL practices, to get sorting, you have to provide operator< for whatever is in your vector
BUT... you are not allowed to do operator<(const MyObjectPtr* right) because it would require a reference to a pointer which is not allowed
BUT... you can provide a FUNCTOR to do the job, then provide it when sorting/searching
a functor is basically a structure with a bool operator()(const MyObjectPtr* left, const MyObjectPtr* right)
OBSERVATION FOUR
unordered_set works even better when combining frequent CRUD with frequent lookups
SUMMARY
Dealing with tons of objects is par for the course in any significant app.
Finding a needle in the haystack of those objects is also standard fare.
Having multiple indices into those objects is also essential.
Using unordered_set with object pointers and is very powerful.
|
c++ stl reverse iterator skeleton
|
From SGI...
reverse_iterator rfirst(V.end());
reverse_iterator rlast(V.begin());
while (rfirst != rlast)
{
cout << *rfirst << endl;
...
rfirst++;
}
|
c++ stl reading a binary file into a string
|
std::ifstream in("my.zip",std::ios::binary);
if (!in)
{
std::cout << "problem with file open" << std::endl;
return 0;
}
in.seekg(0,std::ios::end);
unsigned long length = in.tellg();
in.seekg(0,std::ios::beg);
string str(length,0);
std::copy(
std::istreambuf_iterator< char >(in) ,
std::istreambuf_iterator< char >() ,
str.begin()
);
For more, see c++ stl reading a binary file
|
c/c++ gdb debugging
|
(gdb) help break
Set breakpoint at specified line or function.
Argument may be line number, function name, or "*" and an address.
If line number is specified, break at start of code for that line.
If function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no arg, uses current execution address of selected stack frame.
This is useful for breaking on return to a stack frame.
Multiple breakpoints at one place are permitted, and useful if conditional.
Do "help breakpoints" for info on other commands dealing with breakpoints.
|
ddd gives you a front end. I need to use it more, compare to other options
|
C - Create a portable command line C project in Visual Studio
|
Visual Studio: File -> New -> project
Visual C++ -> Win32 -> Win32 Console Application
name: oms_with_emap
next -> click OFF precompiled header checkbox (even tho it didn't seem to respect it)
you'll get a _tmain(..., TCHAR*...)
change it to main(..., char*...)
change the project to explicitly say "Not using precompiled header"
remove the f'in stdafx.h
recompile! should be clean
vs will recognize C files and compile accordingly
|
c++ Create a portable C++ project in Visual Studio
|
It's probably best to create a project_name.cpp file with your main() function.
int main( int argc, char * argv[] )
{
return 0;
}
Then in Visual Studio...
File->New->Project from existing code
C++
(then use mostly defaults on this page, once you provide file location and project name)
Project file location: <base>\project_name
Project name: project_name
[x] Add files from these folders
Add subs
[x] <base>\project_name
NEXT
Use Visual Studio
Console application project
No ATL, MFC, CLR
NEXT
NEXT
FINISH
Then add boost include and lib paths, required preprocessor definitions, etc.
Example (if you built 1.53 in place with Visual Studio):
INCLUDE: C:\Software Development\boost_1_53_0
LIB: C:\Software Development\boost_1_53_0\stage\lib
|
boost build for both 32 and 64 bit Windows
|
Open a VS2013 x64 Native Tools Command Prompt.
EITHER: for new installs, you have to run bootstrap.bat first, it will build bjam;
OR: for reruns, remove boost dirs: [bin.v2, stage].
Then build 64-bit:
cd "C:\Michael's Data\development\sixth_column\boost_1_55_0"
bjam --toolset=msvc-12.0 address-model=64 --build-type=complete --stagedir=windows_lib\x64 stage
Now open VS2013 x86 Native Tools Command Prompt and build 32-bit:
cd "C:\Michael's Data\development\sixth_column\boost_1_55_0"
bjam --toolset=msvc-12.0 address-model=32 --build-type=complete --stagedir=windows_lib\x86 stage
|
php debugging
|
Tail these:
tail -f /var/log/apache2/sitelogs/thedigitalage.org/ssl_error_log
tail -f /var/log/ampache-tda/ampache.(today).log
|
This leads to too much noise, not needed...
emacs /etc/php/apache2-php5.3/php.ini
display_errors = On
/etc/init.d/apache restart
|
java eclipse project layout format
|
* Eclipse workspace (can also be the top version-control folder)
|
** project folder (typically one "app" that you can "run")
|
*** package(s) (named something like "com.developer.project.application")
|
**** classes (each class is contained in one file)
|
SQL Server 2008+ proper upsert using MERGE
|
-- We need an "upsert": if record exists, update it, otherwise insert.
-- There are several options to do that.
-- Trying to do it correctly means...
-- 1) use a lock or transaction to make the upsert atomic
-- 2) use the best-available operation to maximize performance
-- SQL Server 2008 has MERGE which may be slightly more efficient than
-- separate check && (insert||update) steps. And we can do it with
-- a single lock instead of a full transaction (which may be better?).
-- It's messy to code up though since three blocks of fields must be specified.
-- Cest la vie.
MERGE [dbo].[FACT_DCSR_RemPeriodMonthlyReport] WITH (HOLDLOCK) AS rpmr
USING (SELECT @ID AS ID) AS new_foo
ON rpmr.ID = new_foo.ID
@last_months_year as DCSRYear,
@last_month as DCSRMonth,
@last_month_name as MonthName,
Device_Type_ID,
WHEN MATCHED THEN
UPDATE
SET f.UpdateSpid = @@SPID,
UpdateTime = SYSDATETIME()
WHEN NOT MATCHED THEN
INSERT
(
ID,
InsertSpid,
InsertTime
)
VALUES
(
new_foo.ID,
@@SPID,
SYSDATETIME()
);
|
bash chmod dirs
|
find /path/to/base/dir -type d -exec chmod g+x {} \;
|
mediawiki collapsible skeleton
|
#replace#
|
mediawiki collapsible example
|
DJs are kept on the active Active djs are maintained Active djs are maintained Active djs are maintained Active djs are maintained Active djs are maintained Active djs are maintained djs list when both the server and the dj are enabled.
|
All djs are shown in the prefs djs list.
Line 2
Line 3
All djs are shown in the prefs djs list.All djs are shown in the prefs djs list.All djs are shown in the prefs djs list.All djs are shown in the prefs djs list.All djs are shown in the prefs djs list.
cd /var/www/localhost/htdocs/mediawiki
emacs LocalSettings_redirector.php (to hardcode each site)
php maintenance/update.php
(repeat for each site)
emacs LocalSettings_redirector.php (to reset dynamic behavior)
|